Loading
Bifrost: Hold vault lock through broadcast & add RPC context deadlines
Supersedes !4448 (closed).
This is a replacement of !4448 (closed), which was opened from a fork branch. Scope/changes are the same. Please continue review here.
Summary
This MR improves UTXO signing safety and RPC resilience, and aligns ZEC/BTC RPC client interfaces so one shared client abstraction can be used.
Problem
- Vault-level locking did not consistently cover the full sign -> broadcast window, which can allow concurrent UTXO selection/broadcast races.
- UTXO RPC wrapper calls did not consistently enforce context deadlines.
-
rpc.Clientandzec.Clienthad mismatched interfaces, forcing split fields and chain-specific branching. - Simulation code still used the old rpc.NewClient signature.
- UTXO fee state (
lastFeeRate,minRelayFeeSats) was shared across scanner/consolidation paths without synchronized access. -
"already in block chain"broadcast handling did not mark signer cache as signed on that branch.
Changes
- Hold vault lock through broadcast in UTXO consolidate flow and signer flow (via lock-capability interface) to eliminate local double-spend risk on concurrent work.
- Add timeout-aware context handling to UTXO RPC wrapper calls (Call and batch paths).
- Pass configured HTTP timeout into UTXO RPC client creation.
- Add
CallContextandBatchCallContexttozec.Client. - Introduce a shared
rpcClientinterface (Call,BatchCall,CallContext,BatchCallContext) and use a single client field for both standard RPC and ZEC RPC implementations. - Update simulation UTXO constructor call to match new RPC client signature.
Additional changes in commit a5dd99b5
- Convert UTXO fee fields to atomics and update all access sites to
Load/Store:minRelayFeeSatslastFeeRate
- Refactor consolidate flow:
- Extract per-vault helper
consolidateVaultUTXOs(...) - Return wrapped errors from helper
- Log once at caller with vault context
- Extract per-vault helper
- In consolidate amount building:
- Use
getUtxoToSpend(..., 0)as count-based probe - Sum via per-UTXO sats conversion (
btcutil.NewAmount) to avoid float accumulation drift
- Use
- In
BroadcastTx, when RPC returns"already in block chain", mark signer cache as signed before returning success. - Add a short code comment documenting why sats-per-UTXO summation is used.
Impact
- Safer concurrent signing/broadcast behavior for UTXO vaults.
- Better failure behavior on slow/stuck RPC calls via deadlines.
- Less duplicated chain-conditional RPC code and cleaner client abstraction.
- Removes unsynchronized shared fee-field access between goroutines.
- Cleaner consolidate error flow (single log location with wrapped context).
- Avoids potential rounding drift in consolidation total amount computation.
- Ensures already-broadcast transactions are handled consistently by always recording them in the signer cache.
Test plan
-
make testpasses -
make lintpasses -
make test-simulationpasses
Edited by ZlyDevMaya