@@ -383,4 +383,42 @@ TEST_CASE("Empty suicide beneficiary") {
383383 CHECK (!state.read_account (suicide_beneficiary));
384384}
385385
386+ TEST_CASE (" CHAINID instruction" ) {
387+ // Set chain_id to a value other than 1
388+ ChainConfig config = kMainnetConfig ;
389+ config.chain_id = 42 ;
390+
391+ Block block{};
392+ block.header .number = 20'000'000 ; // PUSH0 enabled
393+ block.header .gas_limit = 50'000 ;
394+ const auto caller = 0x5ed8cee6b63b1c6afce3ad7c92f4fd7e1b8fad9f_address;
395+
396+ const auto code = *from_hex (" 465955" ); // SSTORE(0, CHAINID)
397+
398+ Transaction txn{};
399+ txn.to = 0xc0de_address;
400+ txn.gas_limit = block.header .gas_limit ;
401+ txn.set_sender (caller);
402+
403+ SECTION (" protected" ) {
404+ txn.chain_id = config.chain_id ; // chain id matches in a valid transaction
405+ }
406+ SECTION (" legacy" ) {
407+ txn.chain_id = std::nullopt ; // valid legacy transaction may not have the chain id
408+ }
409+
410+ InMemoryState state;
411+
412+ ExecutionProcessor processor{block, *protocol::rule_set_factory (config), state, config, true };
413+ processor.evm ().state ().add_to_balance (caller, kEther );
414+ processor.evm ().state ().set_code (*txn.to , code);
415+
416+ Receipt receipt;
417+ processor.execute_transaction (txn, receipt);
418+ CHECK (receipt.success );
419+
420+ const auto v = processor.evm ().state ().get_current_storage (*txn.to , 0x00_bytes32);
421+ CHECK (v == evmc::bytes32{config.chain_id });
422+ }
423+
386424} // namespace silkworm
0 commit comments