The blockhash cache added in #19 guards against duplicate transactions by tracking which serialized transactions were already signed against each blockhash. That set lives in module state, so it is per-process.
Two independent processes using the same wallet can still collide:
- The default RPC caches
getLatestBlockhash for 30s server-side, so concurrent processes routinely receive the same blockhash.
- If both then build a payment with identical economics — same amount, same recipient, same fee payer — the transaction message is byte-identical.
- ed25519 is deterministic, so both carry the same signature, and Solana rejects the second as already-processed.
Same-priced repeat calls are ordinary agent behavior, so identical economics across processes is not a corner case.
This is pre-existing, not introduced by #19 — before the cache, two processes could independently fetch the same server-cached blockhash and hit exactly the same collision. #19 closed the single-process case and left this one unchanged. Worth stating plainly rather than leaving it implied by "the guard is process-local".
Only worth fixing if concurrent same-wallet workers are a real deployment shape. If so, the options are a shared nonce source (file lock, Redis) or biasing the fee nonce by a per-process salt so two processes cannot land on the same value.
Noted in the #19 description, which is now merged and buried — hence this issue.
Related: BlockRunAI/blockrun-mcp#89 (the Base-side scope gap in the same area).
The blockhash cache added in #19 guards against duplicate transactions by tracking which serialized transactions were already signed against each blockhash. That set lives in module state, so it is per-process.
Two independent processes using the same wallet can still collide:
getLatestBlockhashfor 30s server-side, so concurrent processes routinely receive the same blockhash.Same-priced repeat calls are ordinary agent behavior, so identical economics across processes is not a corner case.
This is pre-existing, not introduced by #19 — before the cache, two processes could independently fetch the same server-cached blockhash and hit exactly the same collision. #19 closed the single-process case and left this one unchanged. Worth stating plainly rather than leaving it implied by "the guard is process-local".
Only worth fixing if concurrent same-wallet workers are a real deployment shape. If so, the options are a shared nonce source (file lock, Redis) or biasing the fee nonce by a per-process salt so two processes cannot land on the same value.
Noted in the #19 description, which is now merged and buried — hence this issue.
Related: BlockRunAI/blockrun-mcp#89 (the Base-side scope gap in the same area).