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 scanBlocks and scanMempool in separate goroutines
  • block prefetch can start additional goroutines that call FetchTxs concurrently
  • observer worker pool processes txins in parallel and calls confirmation logic
  • OnObservedTxIn processing 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 AsgardCache helper in bifrost/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() to CompareAndSwap()
  • add focused unit tests for GetAsgardAddressCached

Test plan

  • make test passes
  • make lint passes
  • make test-simulation passes
Edited by ZlyDevMaya

Merge request reports

Loading
Loading