Skip to content

Commit

Permalink
state: Implement fake BLOCKHASH resolution for testing
Browse files Browse the repository at this point in the history
If explict block hashes are not provided, return predefined block hashes
from `Host::get_block_hash()` as `keccak256(str(block_number))`. This is
badly documented convention used in state tests.

Note: the readability of block hash values from `BLOCKHASH` instruction
still applies. I.e. you will get 0 if you ask for a block from
the future or more than 256 blocks older than the current one.
  • Loading branch information
chfast committed Sep 4, 2023
1 parent 778dfcb commit 51ccacb
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 6 deletions.
5 changes: 4 additions & 1 deletion test/state/host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,10 @@ bytes32 Host::get_block_hash(int64_t block_number) const noexcept
it != m_block.known_block_hashes.end())
return it->second;

return {};
// Convention for testing: if the block hash in unknown return the predefined "fake" value.
// https://github.com/ethereum/go-ethereum/blob/v1.12.2/tests/state_test_util.go#L432
const auto s = std::to_string(block_number);
return keccak256({reinterpret_cast<const uint8_t*>(s.data()), s.size()});
}

void Host::emit_log(const address& addr, const uint8_t* data, size_t data_size,
Expand Down
2 changes: 1 addition & 1 deletion test/unittests/evm_state_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ TEST_P(evm, blockhash)
host.block_hash.bytes[13] = 0x13;

host.tx_context.block_number = 0;
const auto code = push(0) + OP_BLOCKHASH + ret_top();
const auto code = blockhash(0) + ret_top();
execute(code);
EXPECT_EQ(result.status_code, EVMC_SUCCESS);
EXPECT_EQ(gas_used, 38);
Expand Down
16 changes: 12 additions & 4 deletions test/unittests/state_transition_block_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,25 @@ TEST_F(state_transition, known_block_hash)
{2, 0x0000000000000000000000000000000000000000000000000000000000000111_bytes32}};
block.number = 5;

const auto code =
push(1) + OP_BLOCKHASH + push(0) + OP_SSTORE + push(2) + OP_BLOCKHASH + push(1) + OP_SSTORE;

tx.to = To;
pre.insert(*tx.to, {.nonce = 1, .code = code});
pre.insert(*tx.to, {.nonce = 1, .code = sstore(0, blockhash(1)) + sstore(1, blockhash(2))});
expect.post[To].storage[0x00_bytes32] =
0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421_bytes32;
expect.post[To].storage[0x01_bytes32] =
0x0000000000000000000000000000000000000000000000000000000000000111_bytes32;
}

TEST_F(state_transition, known_block_hash_fake)
{
block.number = 2;
tx.to = To;
pre.insert(*tx.to, {.nonce = 1, .code = sstore(0, blockhash(0)) + sstore(1, blockhash(1))});
expect.post[To].storage[0x00_bytes32] =
0x044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d_bytes32;
expect.post[To].storage[0x01_bytes32] =
0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6_bytes32;
}

TEST_F(state_transition, block_apply_ommers_reward)
{
rev = EVMC_LONDON;
Expand Down
5 changes: 5 additions & 0 deletions test/utils/bytecode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,11 @@ inline bytecode tload(bytecode index)
return index + OP_TLOAD;
}

inline bytecode blockhash(bytecode number)
{
return number + OP_BLOCKHASH;
}

template <Opcode kind>
struct call_instruction
{
Expand Down

0 comments on commit 51ccacb

Please sign in to comment.