Skip to content

Node: make dependent-context var and log reads see pending dependent txs - #2168

Open
profinch wants to merge 2 commits into
BeamMW:masterfrom
profinch:dependent-context-pending-txs
Open

profinch wants to merge 2 commits into
BeamMW:masterfrom
profinch:dependent-context-pending-txs

Conversation

@profinch

Copy link
Copy Markdown

App shaders that read contract vars or logs through a dependent context got confirmed state only, while tx validation on that context applies its pending txs first. A contract call quoted this way signs for funds the contract no longer moves, and the kernel fails CheckSigs. Hit with an AMM trade built on top of someone else's pending trade in the same pool.

Vars (commit 1): ContractVarsEnum runs inside ExecInDependentContext but reads NodeDB, while the pending txs' var changes live only in BlockInterpretCtx::Storage::m_Vars (applied with m_Temporary). New NodeProcessor::EnumContractVars walks the temporary storage with Storage::FindVarEx inside a dependent context and the DB otherwise.

Logs (commit 2): same for ContractLogsEnum; temporary logs were not kept anywhere. ExecInDependentContext now sets m_KeepTempLogs, OnLog keeps them in m_vTempLogs (popped on undo), and the new NodeProcessor::EnumContractLogs merges them into the DB walk in DB order.

Tests: TestDependentTxs reads the vault account and the vault logs while the deposit is still pending and expects the deposited amount.

Patches authored by @Maxnflaxl, opened on their behalf (account suspended).

🤖 Generated with Claude Code

Maxnflaxl added 2 commits October 25, 2026 00:05
App shaders that read contract vars through a dependent context got
confirmed state, while tx validation on that context applies its pending
txs first. A contract call quoted this way signs for funds the contract
no longer moves, and the kernel fails CheckSigs. We hit it with an AMM
trade built on top of someone else's pending trade in the same pool.

Cause: ContractVarsEnum runs its worker inside ExecInDependentContext,
but the worker reads NodeDB. DependentContextSwitch applies the pending
txs with m_Temporary set, so their var changes stay in
BlockInterpretCtx::Storage::m_Vars and never reach the DB.

Fix: NodeProcessor::EnumContractVars. Inside ExecInDependentContext it
walks the temporary storage with Storage::FindVarEx, the same DB plus
m_Vars lookup contract execution uses. Outside it reads the DB as
before. ContractVarsEnum calls it.

Test: TestDependentTxs reads the vault account while the deposit is
still pending and expects the deposited amount.
Same bug for logs: ContractLogsEnum runs inside ExecInDependentContext
but reads NodeDB only. Here the pending txs' logs aren't kept anywhere,
not even in memory: Storage::OnLog writes to NodeDB only when
!m_Temporary.

Fix: ExecInDependentContext sets BlockInterpretCtx::m_KeepTempLogs, so
OnLog keeps temporary logs in m_vTempLogs and the Log undo pops them.
NodeProcessor::EnumContractLogs merges them into the DB walk in the DB's
order: by position, or by key then position. They all sit at the next
height, so they follow DB logs of the same key. ContractLogsEnum calls
it.

Test: TestDependentTxs reads the vault logs while the deposit is still
pending and expects the deposited amount.
@profinch
profinch force-pushed the dependent-context-pending-txs branch from 7eec8fa to dd41921 Compare October 24, 2026 23:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant