Loading
[Version-unspecific] fix(bifrost/eth,zec,ada): keep using stale asgard addresses when MAYANode cannot be read
Summary
When GetAsgardPubKeys failed, the ETH and ZEC clients threw away their cached asgard list. ZEC's isAsgardAddress then returned false for every address, so the scanner treated the block's txs as unrelated and moved past them. A short MAYANode outage (a restart or an upgrade) could lose inbounds for good. On both chains getBlockRequiredConfirmation returned the error, and GetConfirmationCount turned it into 0 confirmations, so the check failed open. This MR ports thornode!4594 (e91742a061), the part MAYA had not applied to ETH and ZEC. BTC and DASH get the same fix in !879. It changes only bifrost, so it is not version-gated.
Changes
- New
utxo.GetAsgardAddressesCachedinshared/utxo. If the refresh fails, it returns the last known addresses together with the error. An empty refresh never replaces a non-empty cache. The cache is still anatomic.Pointer. After a failed refresh the helper remembers the failure forAsgardRefreshBackoff(2s) and returns the stale addresses with the error without querying MAYANode again. The helper and its tests are byte-identical to the BTC/DASH parity MR (!879), which carries the same change, so the two MRs merge cleanly. - ETH:
getAsgardAddressesnow uses the helper. Confirmation counting no longer returns early on an asgard error. It uses the last known list, or none, so a vault spend counts as inbound value and can only raise the number of confirmations required. - ZEC: uses the helper, and
isAsgardAddresskeeps matching against the stale list.FetchTxsreturnsErrRetryableBlockScanwhenever the asgard list can't be refreshed, even with a stale list cached, since that list can miss a new vault. It does this before any reorg or scan bookkeeping. Confirmation counting fails closed, as on ETH. - Cardano (MAYA-only; the same fix adapted, since THOR has no Cardano):
getAsgardAddressesuses the sharedutxo.GetAsgardAddressesCached(still capped atMaxAsgardAddresses), so a MAYANode read error returns the last known vault addresses instead of dropping them.FetchTxsfails the block for a retry whenever the asgard list can't be refreshed, even with a stale list cached, so a deposit to a vault that became active since the last refresh is not skipped.isAsgardAddresskeeps matching the stale list, soOnObservedTxInstill records vault spends as self txs. With no list at all it fails closed: the tx is tracked as a customer tx and UTXO selection skips unconfirmed UTXOs.- Cardano confirmation counting does not use the asgard list, so it is unchanged.
- Not changed: EVM (ARB/AVAX) does no asgard lookups and has instant finality.
Tests
shared/utxo: covers a fresh hit, a refresh, an error with and without a stale cache, and an empty refresh.- ETH
asgard_cache_test.go: the stale cache is kept on error, and the confirmation count is 2, not 0, while the asgard read fails. - ZEC
asgard_cache_test.go:isAsgardAddressmatches against the stale list,FetchTxsretries the block when there is no cache and scans it normally when a stale cache exists, and the confirmation count is greater than 0 when the asgard read fails. - Cardano
client_test.go: the block is scanned against the stale list, the stale cache is kept on error, andOnObservedTxInrecords a vault spend as a self tx while the asgard read fails. A block with no cache still fails for a retry. - The new ETH, ZEC and Cardano tests fail without the fix.
go test -tags mocknet -p 2passes onethereum/...,zcash/...,cardano/...andshared/....
Review follow-up (round 4)
30e109c7a: Cardano and ZECFetchTxsfail the block on any asgard refresh error, also with a stale list cached, so a deposit to a vault that became active since the last refresh is retried instead of skipped. Stale matching inisAsgardAddressand confirmation counting is kept.e2f335244:GetAsgardAddressesCachedremembers a failed refresh forAsgardRefreshBackoff(2s) and returns the stale addresses with the error without querying MAYANode again, instead of one request per address check.1a986f934: ETH and ZEC tests check the value counted for confirmations while the asgard read fails (a deposit counts; a vault spend is excluded only with a stale list holding the vault).
Edited by Bitol Maya