Bifrost: make Asgard address caching concurrency-safe (UTXO + Ethereum)
Supersedes !4570 (closed).
This is a replacement of !4570 (closed), which was opened from a fork branch. Scope/changes are the same. Please continue review here.
Summary
Make Asgard address caching concurrency-safe in Bifrost UTXO and Ethereum clients by using an atomic cache and shared cache helper logic. This MR also hardens other shared UTXO client state that is read and written across concurrent scanner, signer, and solvency paths.
Problem
isAsgardAddress / getAsgardAddress previously depended on shared mutable fields without synchronization.
These paths are reachable concurrently, so races and inconsistent reads were possible.
In the UTXO client, additional shared fields such as fee and solvency state were also read and written without synchronization.
Where concurrent calls can happen
- block scanner runs
scanBlocksandscanMempoolin separate goroutines - block prefetch can start additional goroutines that call
FetchTxsconcurrently - observer worker pool processes txins in parallel and calls confirmation logic
-
OnObservedTxInprocessing can overlap with the above execution paths - solvency reporting and signer fee selection can overlap with scanner-side fee updates
This means Asgard-address lookups and some UTXO fee / solvency reads can be hit from multiple goroutines during normal operation.
Changes
- use a shared atomic
AsgardCachehelper inbifrost/pkg/chainclients/shared/utxo - use that shared cache from both UTXO and Ethereum clients
- switch remaining atomic usage in these paths to the standard library
sync/atomic - replace unsynchronized shared UTXO fee / solvency fields with atomic values
- serialize UTXO network-fee cache updates with a lock
- serialize UTXO solvency reporting so check/update of the last reported height is not racy
- serialize UTXO solvency reporting so concurrent callers cannot read and update the last reported height inconsistently
- change UTXO consolidation start gating from
Load()+Store()toCompareAndSwap() - add focused unit tests for
GetAsgardAddressCached
Test plan
-
make testpasses -
make lintpasses -
make test-simulationpasses