From a7159a0779a5258912aaf3f4e93d84a68897b9e1 Mon Sep 17 00:00:00 2001 From: Janez Podhostnik Date: Wed, 29 Jul 2026 17:58:44 +0200 Subject: [PATCH] Restore exact EVM updated-register count assertion --- fvm/evm/evm_test.go | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/fvm/evm/evm_test.go b/fvm/evm/evm_test.go index 16525993fc6..9e41a5388b8 100644 --- a/fvm/evm/evm_test.go +++ b/fvm/evm/evm_test.go @@ -2,6 +2,7 @@ package evm_test import ( "bytes" + "crypto/sha256" "encoding/binary" "encoding/hex" "fmt" @@ -2943,12 +2944,9 @@ func TestCadenceOwnedAccountFunctionalities(t *testing.T) { require.NoError(t, err) require.NoError(t, output.Err) assert.Len(t, output.Events, 3) - // This transaction must update state. The exact number of updated registers varies - // slightly between runs: the test environment uses a random block ID, which selects - // the UUID partition register (`uuid` vs `uuid_N`) and thereby also the atree slab - // layout. Hence, we only check that state was updated at all - in contrast to - // `dryCall` below, which must not update any registers. - assert.NotEmpty(t, state.UpdatedRegisterIDs()) + // this transaction must update state - in contrast to the dry-run call below, + // which must not update any registers + assertUpdatedRegisterCount(t, ctx, state, 13) assert.Equal( t, flow.EventType("A.f8d6e0586b0a20c7.EVM.TransactionExecuted"), @@ -3096,12 +3094,9 @@ func TestCadenceOwnedAccountFunctionalities(t *testing.T) { require.NoError(t, err) require.NoError(t, output.Err) assert.Len(t, output.Events, 3) - // This transaction must update state. The exact number of updated registers varies - // slightly between runs: the test environment uses a random block ID, which selects - // the UUID partition register (`uuid` vs `uuid_N`) and thereby also the atree slab - // layout. Hence, we only check that state was updated at all - in contrast to - // `dryCall` below, which must not update any registers. - assert.NotEmpty(t, state.UpdatedRegisterIDs()) + // this transaction must update state - in contrast to the dry-run call below, + // which must not update any registers + assertUpdatedRegisterCount(t, ctx, state, 13) assert.Equal( t, flow.EventType("A.f8d6e0586b0a20c7.EVM.TransactionExecuted"), @@ -7189,6 +7184,25 @@ func getEVMAccountNonce( return uint64(val) } +// assertUpdatedRegisterCount asserts that the execution updated exactly the expected number of +// registers. `countNonZeroPartition` is the expected count for a block whose ID selects a +// non-zero UUID partition (see `environment.uuidPartition` with txnIndex 0, as used by these +// tests): such blocks use a fresh `uuid_N` register. A block selecting partition 0 (probability +// 1/256) reuses the legacy `uuid` register instead, updating one register fewer. +func assertUpdatedRegisterCount( + t *testing.T, + ctx fvm.Context, + state *snapshot.ExecutionSnapshot, + countNonZeroPartition int, +) { + expected := countNonZeroPartition + blockID := ctx.BlockHeader.ID() + if sha256.Sum256(blockID[:])[0] == 0 { + expected-- + } + assert.Len(t, state.UpdatedRegisterIDs(), expected) +} + func RunWithNewEnvironment( t *testing.T, chain flow.Chain,