@@ -74,24 +74,38 @@ uint256be Host::get_balance(const address& addr) const noexcept
7474 return (acc != nullptr ) ? intx::be::store<uint256be>(acc->balance ) : uint256be{};
7575}
7676
77+ namespace
78+ {
79+ // For EXTCODE* instructions if the target is an EOF account, then only return EF00.
80+ // While we only do this if the caller is legacy, it is not a problem doing this
81+ // unconditionally, because EOF contracts dot no have EXTCODE* instructions.
82+ bytes_view extcode (bytes_view code) noexcept
83+ {
84+ if (code.size () >= 2 && code[0 ] == 0xEF && code[1 ] == 0x00 )
85+ return code.substr (2 );
86+
87+ return code;
88+ }
89+ } // namespace
90+
7791size_t Host::get_code_size (const address& addr) const noexcept
7892{
7993 const auto * const acc = m_state.find (addr);
80- return (acc != nullptr ) ? acc->code .size () : 0 ;
94+ return (acc != nullptr ) ? extcode ( acc->code ) .size () : 0 ;
8195}
8296
8397bytes32 Host::get_code_hash (const address& addr) const noexcept
8498{
8599 // TODO: Cache code hash. It will be needed also to compute the MPT hash.
86100 const auto * const acc = m_state.find (addr);
87- return (acc != nullptr && !acc->is_empty ()) ? keccak256 (acc->code ) : bytes32{};
101+ return (acc != nullptr && !acc->is_empty ()) ? keccak256 (extcode ( acc->code ) ) : bytes32{};
88102}
89103
90104size_t Host::copy_code (const address& addr, size_t code_offset, uint8_t * buffer_data,
91105 size_t buffer_size) const noexcept
92106{
93107 const auto * const acc = m_state.find (addr);
94- const auto code = (acc != nullptr ) ? bytes_view{ acc->code } : bytes_view{};
108+ const auto code = (acc != nullptr ) ? extcode ( acc->code ) : bytes_view{};
95109 const auto code_slice = code.substr (std::min (code_offset, code.size ()));
96110 const auto num_bytes = std::min (buffer_size, code_slice.size ());
97111 std::copy_n (code_slice.begin (), num_bytes, buffer_data);
0 commit comments