@@ -74,24 +74,35 @@ 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+ return is_eof_container (code) ? code.substr (0 , 2 ) : code;
85+ }
86+ } // namespace
87+
7788size_t Host::get_code_size (const address& addr) const noexcept
7889{
7990 const auto * const acc = m_state.find (addr);
80- return (acc != nullptr ) ? acc->code .size () : 0 ;
91+ return (acc != nullptr ) ? extcode ( acc->code ) .size () : 0 ;
8192}
8293
8394bytes32 Host::get_code_hash (const address& addr) const noexcept
8495{
8596 // TODO: Cache code hash. It will be needed also to compute the MPT hash.
8697 const auto * const acc = m_state.find (addr);
87- return (acc != nullptr && !acc->is_empty ()) ? keccak256 (acc->code ) : bytes32{};
98+ return (acc != nullptr && !acc->is_empty ()) ? keccak256 (extcode ( acc->code ) ) : bytes32{};
8899}
89100
90101size_t Host::copy_code (const address& addr, size_t code_offset, uint8_t * buffer_data,
91102 size_t buffer_size) const noexcept
92103{
93104 const auto * const acc = m_state.find (addr);
94- const auto code = (acc != nullptr ) ? bytes_view{ acc->code } : bytes_view{};
105+ const auto code = (acc != nullptr ) ? extcode ( acc->code ) : bytes_view{};
95106 const auto code_slice = code.substr (std::min (code_offset, code.size ()));
96107 const auto num_bytes = std::min (buffer_size, code_slice.size ());
97108 std::copy_n (code_slice.begin (), num_bytes, buffer_data);
0 commit comments