3131#include < category/mpt/db.hpp>
3232#include < category/mpt/ondisk_db_config.hpp>
3333#include < category/rpc/eth_call.h>
34+ #include < category/vm/utils/evm-as.hpp>
3435#include < test_resource_data.h>
3536
3637#include < boost/fiber/future/promise.hpp>
@@ -1796,4 +1797,248 @@ TEST_F(EthCallFixture, prestate_state_overrides)
17961797
17971798 monad_state_override_destroy (state_override);
17981799 monad_eth_call_executor_destroy (executor);
1799- }
1800+ }
1801+
1802+ TEST_F (EthCallFixture, prestate_override_state)
1803+ {
1804+
1805+ static constexpr Address CONTRACT_ADDR =
1806+ 0xcccccccccccccccccccccccccccccccccccccccc_address;
1807+
1808+ using namespace monad ::vm::utils;
1809+ auto eb = evm_as::latest ()
1810+ .push (1 )
1811+ .sload ()
1812+ .push0 ()
1813+ .sload ()
1814+ .add ()
1815+ .push0 ()
1816+ .mstore ()
1817+ .push (32 )
1818+ .push0 ()
1819+ .return_ ();
1820+ std::vector<uint8_t > bytecode_container{};
1821+ ASSERT_TRUE (evm_as::validate (eb));
1822+ evm_as::compile (eb, bytecode_container);
1823+ byte_string_view bytecode_view{
1824+ bytecode_container.data (), bytecode_container.size ()};
1825+ auto const code_hash = to_bytes (keccak256 (bytecode_view));
1826+ auto const compiled_code = vm::make_shared_intercode (bytecode_view);
1827+
1828+ bytes32_t storage_key = to_bytes (to_big_endian (uint256_t {0 }));
1829+ bytes32_t storage_value = to_bytes (to_big_endian (uint256_t {64 }));
1830+
1831+ bytes32_t other_storage_key = to_bytes (to_big_endian (uint256_t {1 }));
1832+ bytes32_t other_storage_value = to_bytes (to_big_endian (uint256_t {128 }));
1833+
1834+ bytes32_t untouched_storage_key = to_bytes (to_big_endian (uint256_t {2 }));
1835+ bytes32_t untouched_storage_value = to_bytes (to_big_endian (uint256_t {256 }));
1836+
1837+ StateDeltas deltas{
1838+ {CONTRACT_ADDR,
1839+ StateDelta{
1840+ .account =
1841+ AccountDelta{
1842+ std::nullopt ,
1843+ Account{
1844+ .balance = 0x0 ,
1845+ .code_hash = code_hash,
1846+ .nonce = 1 ,
1847+ }},
1848+ .storage =
1849+ StorageDeltas{{storage_key, {bytes32_t {}, storage_value}}}}}};
1850+
1851+ commit_sequential (
1852+ tdb, deltas, {{code_hash, compiled_code}}, BlockHeader{.number = 0 });
1853+
1854+ auto const storage = tdb.read_storage (
1855+ CONTRACT_ADDR,
1856+ Incarnation{0 , 0 },
1857+ to_bytes (to_big_endian (uint256_t {0 })));
1858+ ASSERT_EQ (storage, to_bytes (to_big_endian (uint256_t {uint64_t {64 }})));
1859+
1860+ for (uint64_t i = 1 ; i < 256 ; ++i) {
1861+ commit_sequential (tdb, {}, {}, BlockHeader{.number = i});
1862+ }
1863+
1864+ static constexpr auto from = Address{};
1865+
1866+ Transaction tx{.gas_limit = 200000u , .to = CONTRACT_ADDR};
1867+ BlockHeader header{.number = 256 };
1868+
1869+ commit_sequential (tdb, {}, {}, header);
1870+
1871+ auto const rlp_tx = to_vec (rlp::encode_transaction (tx));
1872+ auto const rlp_header = to_vec (rlp::encode_block_header (header));
1873+ auto const rlp_sender =
1874+ to_vec (rlp::encode_address (std::make_optional (from)));
1875+ auto const rlp_block_id = to_vec (rlp_finalized_id);
1876+
1877+ auto executor = create_executor (dbname.string ());
1878+
1879+ // Test 'state' override option. It should wipe the existing and update the
1880+ // given slots.
1881+ struct callback_context ctx_state;
1882+ {
1883+ auto state_override = monad_state_override_create ();
1884+ add_override_address (
1885+ state_override, CONTRACT_ADDR.bytes , sizeof (Address));
1886+ set_override_state (
1887+ state_override,
1888+ CONTRACT_ADDR.bytes ,
1889+ sizeof (Address),
1890+ other_storage_key.bytes ,
1891+ sizeof (bytes32_t ),
1892+ other_storage_value.bytes ,
1893+ sizeof (bytes32_t ));
1894+ set_override_state (
1895+ state_override,
1896+ CONTRACT_ADDR.bytes ,
1897+ sizeof (Address),
1898+ untouched_storage_key.bytes ,
1899+ sizeof (bytes32_t ),
1900+ untouched_storage_value.bytes ,
1901+ sizeof (bytes32_t ));
1902+
1903+ boost::fibers::future<void > f = ctx_state.promise .get_future ();
1904+ monad_eth_call_executor_submit (
1905+ executor,
1906+ CHAIN_CONFIG_MONAD_DEVNET,
1907+ rlp_tx.data (),
1908+ rlp_tx.size (),
1909+ rlp_header.data (),
1910+ rlp_header.size (),
1911+ rlp_sender.data (),
1912+ rlp_sender.size (),
1913+ header.number ,
1914+ rlp_block_id.data (),
1915+ rlp_block_id.size (),
1916+ state_override,
1917+ complete_callback,
1918+ (void *)&ctx_state,
1919+ PRESTATE_TRACER,
1920+ true );
1921+ f.get ();
1922+
1923+ ASSERT_TRUE (ctx_state.result ->status_code == EVMC_SUCCESS);
1924+ ASSERT_EQ (ctx_state.result ->output_data_len , sizeof (bytes32_t ));
1925+
1926+ bytes32_t result;
1927+ std::memcpy (
1928+ result.bytes , ctx_state.result ->output_data , sizeof (bytes32_t ));
1929+
1930+ bytes32_t expected = to_bytes (to_big_endian (uint256_t {uint64_t {128 }}));
1931+
1932+ EXPECT_EQ (result, expected);
1933+
1934+ std::vector<uint8_t > const encoded_prestate_trace (
1935+ ctx_state.result ->encoded_trace ,
1936+ ctx_state.result ->encoded_trace +
1937+ ctx_state.result ->encoded_trace_len );
1938+
1939+ auto const expected_json = R"( {
1940+ "0x0000000000000000000000000000000000000000": {
1941+ "balance": "0x0"
1942+ },
1943+ "0xcccccccccccccccccccccccccccccccccccccccc": {
1944+ "balance": "0x0",
1945+ "code": "0x6001545f54015f5260205ff3",
1946+ "nonce": 1,
1947+ "storage": {
1948+ "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000",
1949+ "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000080"
1950+ }
1951+ }
1952+ })" ;
1953+
1954+ EXPECT_EQ (
1955+ nlohmann::json::parse (expected_json),
1956+ nlohmann::json::from_cbor (encoded_prestate_trace));
1957+
1958+ monad_state_override_destroy (state_override);
1959+ }
1960+
1961+ // Similar to above, but test state diff override. It should keep existing
1962+ // and update the given slots.
1963+ struct callback_context ctx_statediff;
1964+ {
1965+ auto state_override = monad_state_override_create ();
1966+ add_override_address (
1967+ state_override, CONTRACT_ADDR.bytes , sizeof (Address));
1968+ set_override_state_diff (
1969+ state_override,
1970+ CONTRACT_ADDR.bytes ,
1971+ sizeof (Address),
1972+ other_storage_key.bytes ,
1973+ sizeof (bytes32_t ),
1974+ other_storage_value.bytes ,
1975+ sizeof (bytes32_t ));
1976+ set_override_state_diff (
1977+ state_override,
1978+ CONTRACT_ADDR.bytes ,
1979+ sizeof (Address),
1980+ untouched_storage_key.bytes ,
1981+ sizeof (bytes32_t ),
1982+ untouched_storage_value.bytes ,
1983+ sizeof (bytes32_t ));
1984+
1985+ boost::fibers::future<void > f = ctx_statediff.promise .get_future ();
1986+ monad_eth_call_executor_submit (
1987+ executor,
1988+ CHAIN_CONFIG_MONAD_DEVNET,
1989+ rlp_tx.data (),
1990+ rlp_tx.size (),
1991+ rlp_header.data (),
1992+ rlp_header.size (),
1993+ rlp_sender.data (),
1994+ rlp_sender.size (),
1995+ header.number ,
1996+ rlp_block_id.data (),
1997+ rlp_block_id.size (),
1998+ state_override,
1999+ complete_callback,
2000+ (void *)&ctx_statediff,
2001+ PRESTATE_TRACER,
2002+ true );
2003+ f.get ();
2004+
2005+ ASSERT_TRUE (ctx_statediff.result ->status_code == EVMC_SUCCESS);
2006+ ASSERT_EQ (ctx_statediff.result ->output_data_len , sizeof (bytes32_t ));
2007+
2008+ bytes32_t result;
2009+ std::memcpy (
2010+ result.bytes , ctx_statediff.result ->output_data , sizeof (bytes32_t ));
2011+
2012+ bytes32_t expected = to_bytes (to_big_endian (uint256_t {uint64_t {192 }}));
2013+
2014+ EXPECT_EQ (result, expected);
2015+
2016+ std::vector<uint8_t > const encoded_prestate_trace (
2017+ ctx_statediff.result ->encoded_trace ,
2018+ ctx_statediff.result ->encoded_trace +
2019+ ctx_statediff.result ->encoded_trace_len );
2020+
2021+ auto const expected_json = R"( {
2022+ "0x0000000000000000000000000000000000000000": {
2023+ "balance": "0x0"
2024+ },
2025+ "0xcccccccccccccccccccccccccccccccccccccccc": {
2026+ "balance": "0x0",
2027+ "code": "0x6001545f54015f5260205ff3",
2028+ "nonce": 1,
2029+ "storage": {
2030+ "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000040",
2031+ "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000080"
2032+ }
2033+ }
2034+ })" ;
2035+
2036+ EXPECT_EQ (
2037+ nlohmann::json::parse (expected_json),
2038+ nlohmann::json::from_cbor (encoded_prestate_trace));
2039+
2040+ monad_state_override_destroy (state_override);
2041+ }
2042+
2043+ monad_eth_call_executor_destroy (executor);
2044+ }
0 commit comments