Bifrost: make Asgard address caching concurrency-safe (UTXO + Ethereum)
Closing in favor of !4594 (merged).
Reason: same changes were reopened from an upstream source branch instead of a fork. Please continue review/discussion in !4594 (merged).
Summary
Make Asgard address caching concurrency-safe in Bifrost UTXO and Ethereum clients by replacing unsynchronized mutable state with an atomic cache and shared cache helper logic.
Problem
isAsgardAddress / getAsgardAddress previously depended on shared mutable fields (asgardAddresses, lastAsgard) without synchronization.
These paths are reachable concurrently, so races and inconsistent reads were possible.
Where concurrent calls can happen
- Block scanner runs
scanBlocksandscanMempoolin separate goroutines. - Block prefetch starts additional goroutines that call
FetchTxsconcurrently. - Observer worker pool processes txins in parallel and calls
GetConfirmationCount. -
OnObservedTxInprocessing can overlap with the above execution paths.
This means getAsgardAddress / isAsgardAddress can be hit from multiple goroutines during normal operation.
Why this should be solved
This removes a real concurrency hazard in hot scanner/observer paths and makes Asgard address reads deterministic and thread-safe under parallel load.
Test plan
-
make testpasses -
make lintpasses -
make test-simulationpasses