Skip to content

Panic in listenPush #4

Description

@pdyraga

Originally posted in checksum0#10.

When working on testnet and mainnet integration tests in threshold-network/keep-core#3599 we stumbled upon random panics when running tests:

=== FAIL: pkg/bitcoin/electrum TestGetLatestBlockHeight_Integration (unknown)
panic: assignment to entry in nil map

goroutine 511 [running]:
github.com/checksum0/go-electrum/electrum.(*Client).listenPush(0xc00036cc40, {0x120e9eb, 0x1c})
	/go/pkg/mod/github.com/keep-network/go-electrum@v0.0.0-20230524074410-befe891c2f8c/electrum/network.go:264 +0x74
github.com/checksum0/go-electrum/electrum.(*Client).SubscribeHeaders.func1()
	/go/pkg/mod/github.com/keep-network/go-electrum@v0.0.0-20230524074410-befe891c2f8c/electrum/subscribe.go:40 +0x36
created by github.com/checksum0/go-electrum/electrum.(*Client).SubscribeHeaders
	/go/pkg/mod/github.com/keep-network/go-electrum@v0.0.0-20230524074410-befe891c2f8c/electrum/subscribe.go:39 +0xfd

=== FAIL: pkg/bitcoin/electrum TestGetLatestBlockHeight_Integration/electrs-esplora_tcp_get (unknown)

=== FAIL: pkg/bitcoin/electrum TestGetLatestBlockHeight_Integration/electrumx_wss_get (unknown)
panic: assignment to entry in nil map

goroutine 511 [running]:
github.com/checksum0/go-electrum/electrum.(*Client).listenPush(0xc00036cc40, {0x[120](https://github.com/keep-network/keep-core/actions/runs/5215398427/jobs/9424824985?pr=3599#step:5:121)e9eb, 0x1c})
	/go/pkg/mod/github.com/keep-network/go-electrum@v0.0.0-20230524074410-befe891c2f8c/electrum/network.go:264 +0x74
github.com/checksum0/go-electrum/electrum.(*Client).SubscribeHeaders.func1()
	/go/pkg/mod/github.com/keep-network/go-electrum@v0.0.0-20230524074410-befe891c2f8c/electrum/subscribe.go:40 +0x36
created by github.com/checksum0/go-electrum/electrum.(*Client).SubscribeHeaders
	/go/pkg/mod/github.com/keep-network/go-electrum@v0.0.0-20230524074410-befe891c2f8c/electrum/subscribe.go:39 +0xfd

I think the problem lies in how the library handles closing the connection.

SubscribeHeaders creates a goroutine that writes to s.pushHandlers map in the listenPush function. If Shutdown() is called at the same time, unfortunate ordering of calls can lead to clearing s.pushHandlers = nil and then attempting to s.pushHandlers[method] = append(s.pushHandlers[method], c).

Separately from this issue, I think the goroutines created in SubscribeHeaders are leaking given there is no clear exit signal for them - the channel returned by listenPush is never closed and they are stuck on reading.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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