Summary
On the s1_dev branch (commit b84cea9, three commits past 26a6564 which introduced
wallet_staking_action), calling wallet_staking_action with CreateNewDelegationBond
consistently fails with:
{"jsonrpc":"2.0","id":1,"error":{"code":-25,"message":"Faucet request for \"CreateNewDelegationBond { amount_zats: 100000, target_finalizer: Pub{ce79} }\" failed: failed to create staking >
The underlying cause appears to be in the wallet's transaction builder, which repeatedly logs:
tx build: couldn't get anchor at BlockHeight(228493)
This recurs continuously (observed over ~10 minutes and ~250+ blocks), including
immediately after Zaino's own status check reports all services Ready:
2026-07-18T15:57:58Z INFO zainodlib::indexer: Zaino status check - ChainState Service: Ready JsonRPC Server: Ready gRPC Server: Ready
2026-07-18T15:58:08Z INFO zainodlib::indexer: Zaino status check - ChainState Service: Ready JsonRPC Server: Ready gRPC Server: Ready
2026-07-18T15:58:35Z zebrad: tx build: couldn't get anchor at BlockHeight(228493)
So this isn't simply "Zaino hasn't caught up yet" — the anchor lookup fails even in a window
where Zaino self-reports Ready.
Ruled out: node still catching up to tip. Initial testing was done while the node was
~6800 blocks behind the estimated chain height, so a first hypothesis was that this was a
sync-lag artifact (wallet scan unable to keep pace with the faster-than-realtime catch-up rate).
This was retested after the node reached full sync (blocks == estimatedheight == 236397,
verificationprogress: 1.0) and the exact same error reproduced immediately:
2026-07-18T21:46:21Z zebrad: tx build: couldn't get anchor at BlockHeight(236394)
At the time of that failure, local tip was 236397 — only 3 blocks ahead of the requested
anchor height, not thousands. So this is not a catch-up/sync-lag issue; the anchor-fetch
problem reproduces at tip.
A related, possibly connected symptom also appeared at tip, from what looks like the
auto-shield logic (moving the shared miner wallet's balance into a user wallet):
TX ERROR: no spend seen for send WalletTxPart { spent_note_count: 0, spent_zats: Zatoshis(0), sent_note_count: 2, sent_zats: Zatoshis(999990000), recv_note_count: 1, recv_zats: Zatoshis(94>
spent_note_count: 0 alongside non-zero sent_note_count/sent_zats looks like a
bookkeeping inconsistency in the wallet's tx-tracking, separate from (but possibly related to)
the anchor lookup failure.
Environment
- Repo:
ShieldedLabs/crosslink_monolith, branch s1_dev, HEAD b84cea9 ("fix compiler error")
- Built with
cargo build --release --bin zebrad (release profile, finished cleanly, no build errors)
- Network:
UnknownTestnet / cTAZ devnet, network_magic = "ClT0" (Crosslink_Testnet_0 / is_clt0)
- Chain state: resynced from the
ctaz-zebra-cache-20260715T233602Z-h226122-bft9536-strict-verified snapshot, independently verified block-for-block against the public explorer up to the >
zebrad run via systemd (Restart=always), internal_miner = true, disable_the_headless_wallet = false, disable_zaino = false
Steps to reproduce
- Start
zebrad fresh (deleted secret.seed so the headless "user_wallet" gets a newly generated, private seed — not the shared workshop one). New wallet addresses on this run:
USER WALLET T-ADDRESS: tmN227oXVaNDtMRK3KTmRq7pe1imvABrmBS
USER WALLET ADDRESS: utest1905l6hjrhfek8y4d0h90stxgknpml778r30fvvm74yfcd2f6a8x29mtap8mz5nwqd094q3dda4ne87z5tvcuvhud8vca0n5egvgdhx2z
- Fund it via the built-in faucet RPC:
curl -s -X POST -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"requestfaucetdonation","params":[{"address":"utest1905l6hjrhfek8y4d0h90stxgknpml778r30fvvm74yfcd2f6a8x29mtap8mz5nwqd094q3dda4ne87z5tvcuvhud8vca0n>
http://127.0.0.1:8232/
Response: {"amount":50000000} (at chain height 228236).
- Wait for confirmation (waited well over ten minutes; chain advanced ~250+ blocks).
- Repeatedly call:
curl -s -X POST -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"wallet_staking_action","params":[{"CreateNewDelegationBond":{"amount_zats":100000,"target_finalizer":"2c17982d6fa4065013156f7ee5094b58d14e1c94131>
http://127.0.0.1:8232/
(finalizer ID taken from a live get_tfl_roster_zec response)
- Every call, across ~25+ attempts spanning >10 minutes and both before and after Zaino reported Ready, returned the same "failed to create staking transaction from notes" error, correlat>
- Waited for the node to reach full sync (
verificationprogress: 1.0, blocks == estimatedheight) and retried the identical wallet_staking_action call. Same error, same `tx build: cou>
Secondary observation (separate from the anchor bug, but found in the same session)
The built-in headless miner wallet (miner_wallet) is derived from a hardcoded literal
BIP-39 mnemonic in wallet/src/lib.rs:
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
This is the standard all-zero BIP-39 test vector used across the industry — its private key
is public knowledge, not unique per node. Its transparent address
(tmRB9AEVsxNAQsqtJPqJUje9KCaAijpS77z on this network) shows getaddressbalance history of
~215,878 ctaz received against only ~10 ctaz currently held — i.e. the large majority of
everything ever mined to this address has already been swept out, consistent with it being
sweepable by anyone who recognizes the test mnemonic (which is trivial — it's the most common
placeholder phrase in crypto tooling). Worth flagging separately since it means any real value
sent to "the default miner wallet" on this devnet is not actually safe, even though the coins
themselves are only test-value.
Suggested next steps for maintainers
- Reproduce with verbose/debug logging around the anchor-fetch path in the wallet tx builder
(wallet/src/lib.rs, the stake_orchard_to_finalizer / continue_proposed_tx flow) to see
exactly which height is requested vs. what Zaino has committed at that instant.
- Consider whether the anchor lookup should retry against the current tree state rather than
a specific height that may already be stale by the time the request lands, given how fast
this devnet produces blocks. Note this reproduces at full sync too (3 blocks behind live tip),
so it's not purely a catch-up artifact.
- Look at whether the
TX ERROR: no spend seen for send bookkeeping mismatch (zero
spent_note_count alongside non-zero sent_note_count/sent_zats) is upstream of the
anchor failure — e.g. the wallet losing track of which notes back a pending send.
- Consider replacing the hardcoded
miner_wallet test mnemonic with a per-node generated seed
(like user_wallet already uses) if this wallet is ever meant to hold anything beyond
disposable shared test funds.
Summary
On the
s1_devbranch (commitb84cea9, three commits past26a6564which introducedwallet_staking_action), callingwallet_staking_actionwithCreateNewDelegationBondconsistently fails with:
The underlying cause appears to be in the wallet's transaction builder, which repeatedly logs:
This recurs continuously (observed over ~10 minutes and ~250+ blocks), including
immediately after Zaino's own status check reports all services Ready:
So this isn't simply "Zaino hasn't caught up yet" — the anchor lookup fails even in a window
where Zaino self-reports Ready.
Ruled out: node still catching up to tip. Initial testing was done while the node was
~6800 blocks behind the estimated chain height, so a first hypothesis was that this was a
sync-lag artifact (wallet scan unable to keep pace with the faster-than-realtime catch-up rate).
This was retested after the node reached full sync (
blocks == estimatedheight == 236397,verificationprogress: 1.0) and the exact same error reproduced immediately:At the time of that failure, local tip was 236397 — only 3 blocks ahead of the requested
anchor height, not thousands. So this is not a catch-up/sync-lag issue; the anchor-fetch
problem reproduces at tip.
A related, possibly connected symptom also appeared at tip, from what looks like the
auto-shield logic (moving the shared miner wallet's balance into a user wallet):
spent_note_count: 0alongside non-zerosent_note_count/sent_zatslooks like abookkeeping inconsistency in the wallet's tx-tracking, separate from (but possibly related to)
the anchor lookup failure.
Environment
ShieldedLabs/crosslink_monolith, branchs1_dev, HEADb84cea9("fix compiler error")cargo build --release --bin zebrad(release profile, finished cleanly, no build errors)UnknownTestnet/ cTAZ devnet,network_magic = "ClT0"(Crosslink_Testnet_0 /is_clt0)ctaz-zebra-cache-20260715T233602Z-h226122-bft9536-strict-verifiedsnapshot, independently verified block-for-block against the public explorer up to the >zebradrun via systemd (Restart=always),internal_miner = true,disable_the_headless_wallet = false,disable_zaino = falseSteps to reproduce
zebradfresh (deletedsecret.seedso the headless "user_wallet" gets a newly generated, private seed — not the shared workshop one). New wallet addresses on this run:USER WALLET T-ADDRESS: tmN227oXVaNDtMRK3KTmRq7pe1imvABrmBSUSER WALLET ADDRESS: utest1905l6hjrhfek8y4d0h90stxgknpml778r30fvvm74yfcd2f6a8x29mtap8mz5nwqd094q3dda4ne87z5tvcuvhud8vca0n5egvgdhx2z{"amount":50000000}(at chain height 228236).get_tfl_roster_zecresponse)verificationprogress: 1.0,blocks == estimatedheight) and retried the identicalwallet_staking_actioncall. Same error, same `tx build: cou>Secondary observation (separate from the anchor bug, but found in the same session)
The built-in headless miner wallet (
miner_wallet) is derived from a hardcoded literalBIP-39 mnemonic in
wallet/src/lib.rs:This is the standard all-zero BIP-39 test vector used across the industry — its private key
is public knowledge, not unique per node. Its transparent address
(
tmRB9AEVsxNAQsqtJPqJUje9KCaAijpS77zon this network) showsgetaddressbalancehistory of~215,878 ctaz received against only ~10 ctaz currently held — i.e. the large majority of
everything ever mined to this address has already been swept out, consistent with it being
sweepable by anyone who recognizes the test mnemonic (which is trivial — it's the most common
placeholder phrase in crypto tooling). Worth flagging separately since it means any real value
sent to "the default miner wallet" on this devnet is not actually safe, even though the coins
themselves are only test-value.
Suggested next steps for maintainers
(
wallet/src/lib.rs, thestake_orchard_to_finalizer/continue_proposed_txflow) to seeexactly which height is requested vs. what Zaino has committed at that instant.
a specific height that may already be stale by the time the request lands, given how fast
this devnet produces blocks. Note this reproduces at full sync too (3 blocks behind live tip),
so it's not purely a catch-up artifact.
TX ERROR: no spend seen for sendbookkeeping mismatch (zerospent_note_countalongside non-zerosent_note_count/sent_zats) is upstream of theanchor failure — e.g. the wallet losing track of which notes back a pending send.
miner_wallettest mnemonic with a per-node generated seed(like
user_walletalready uses) if this wallet is ever meant to hold anything beyonddisposable shared test funds.