Skip to content

walletapi: Keep_Connectivity nils rpc_client.WS/RPC while calls may be in flight #35

Description

@Dirtybird99

Summary

When the watchdog ping fails, Keep_Connectivity tears down the shared RPC client in place:

if IsDaemonOnline() {
var result string
if err := rpc_client.Call("DERO.Ping", nil, &result); err != nil {
// fmt.Printf("Ping failed: %v", err)
rpc_client.RPC.Close()
rpc_client.WS = nil
rpc_client.RPC = nil
Connected = false
Connect("") // try to connect again
} else {

if err := rpc_client.Call("DERO.Ping", nil, &result); err != nil {
	rpc_client.RPC.Close()
	rpc_client.WS = nil
	rpc_client.RPC = nil
	Connected = false
	Connect("")
}

Meanwhile every other goroutine (sync loop, wallet RPC handlers, transfer building, history sync) uses the same rpc_client through the check-then-use pattern:

func IsDaemonOnline() bool {
	if rpc_client.WS == nil || rpc_client.RPC == nil {
		return false
	}
	return true
}

Impact

There is no synchronization between the nil-out and concurrent users:

  • A goroutine that passed IsDaemonOnline() can dereference rpc_client.RPC just after it was set to nil → panic.
  • RPC.Close() while another goroutine is inside CallResult aborts that call mid-flight (acceptable), but the unsynchronized pointer writes themselves are also a data race (same class as the globals race — see companion issue).
  • Connect("") then re-populates WS/RPC non-atomically, so readers can observe a half-initialized client.

Fix

Replace the two mutable fields with an atomically-swapped immutable client value: build the new Client fully, then client.Store(newClient) (atomic.Pointer[Client]); IsDaemonOnline and all callers load the pointer once and use that snapshot. Alternatively, guard connect/teardown/use with an RWMutex.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions