Skip to content

Commit e6de0be

Browse files
committed
Semantic state override object
1 parent 15f27ce commit e6de0be

File tree

2 files changed

+91
-94
lines changed

2 files changed

+91
-94
lines changed

category/rpc/monad_executor.cpp

Lines changed: 51 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <category/core/byte_string.hpp>
2020
#include <category/core/bytes.hpp>
2121
#include <category/core/fiber/priority_pool.hpp>
22+
#include <category/core/int.hpp>
2223
#include <category/core/keccak.hpp>
2324
#include <category/core/likely.h>
2425
#include <category/core/lru/static_lru_cache.hpp>
@@ -69,7 +70,6 @@
6970
#include <cstdlib>
7071
#include <cstring>
7172
#include <filesystem>
72-
#include <map>
7373
#include <memory>
7474
#include <optional>
7575
#include <span>
@@ -81,6 +81,7 @@
8181

8282
#include <string.h>
8383

84+
#include <ankerl/unordered_dense.h>
8485
#include <evmc/evmc.h>
8586
#include <evmc/evmc.hpp>
8687
#include <intx/intx.hpp>
@@ -94,14 +95,16 @@ struct monad_state_override
9495
{
9596
struct monad_state_override_object
9697
{
97-
std::optional<byte_string> balance{std::nullopt};
98+
std::optional<uint256_t> balance{std::nullopt};
9899
std::optional<uint64_t> nonce{std::nullopt};
99100
std::optional<byte_string> code{std::nullopt};
100-
std::map<byte_string, byte_string> state{};
101-
std::map<byte_string, byte_string> state_diff{};
101+
ankerl::unordered_dense::segmented_map<bytes32_t, bytes32_t> state{};
102+
ankerl::unordered_dense::segmented_map<bytes32_t, bytes32_t>
103+
state_diff{};
102104
};
103105

104-
std::map<byte_string, monad_state_override_object> override_sets;
106+
ankerl::unordered_dense::segmented_map<Address, monad_state_override_object>
107+
override_sets;
105108
};
106109

107110
namespace
@@ -183,12 +186,11 @@ namespace
183186
enriched_txn.sc.r = 1;
184187
enriched_txn.sc.s = 1;
185188

186-
BOOST_OUTCOME_TRY(
187-
static_validate_transaction<traits>(
188-
enriched_txn,
189-
header.base_fee_per_gas,
190-
header.excess_blob_gas,
191-
chain.get_chain_id()));
189+
BOOST_OUTCOME_TRY(static_validate_transaction<traits>(
190+
enriched_txn,
191+
header.base_fee_per_gas,
192+
header.excess_blob_gas,
193+
chain.get_chain_id()));
192194

193195
tdb.set_block_and_prefix(block_number, block_id);
194196
BlockState block_state{tdb, vm};
@@ -197,12 +199,8 @@ namespace
197199
{
198200
State state{block_state, incarnation};
199201

200-
for (auto const &[addr, state_delta] :
202+
for (auto const &[address, state_delta] :
201203
state_overrides.override_sets) {
202-
// address
203-
Address address{};
204-
std::memcpy(address.bytes, addr.data(), sizeof(Address));
205-
206204
// This would avoid seg-fault on storage override for
207205
// non-existing accounts
208206
auto const &account = state.recent_account(address);
@@ -211,24 +209,16 @@ namespace
211209
}
212210

213211
if (state_delta.balance.has_value()) {
214-
auto const balance = intx::be::unsafe::load<uint256_t>(
215-
state_delta.balance.value().data());
216-
if (balance >
217-
intx::be::load<uint256_t>(
218-
state.get_current_balance_pessimistic(address))) {
212+
auto const balance = state_delta.balance.value();
213+
auto const pessimistic_balance = intx::be::load<uint256_t>(
214+
state.get_current_balance_pessimistic(address));
215+
if (balance > pessimistic_balance) {
219216
state.add_to_balance(
220-
address,
221-
balance - intx::be::load<uint256_t>(
222-
state.get_current_balance_pessimistic(
223-
address)));
217+
address, balance - pessimistic_balance);
224218
}
225219
else {
226220
state.subtract_from_balance(
227-
address,
228-
intx::be::load<uint256_t>(
229-
state.get_current_balance_pessimistic(
230-
address)) -
231-
balance);
221+
address, pessimistic_balance - balance);
232222
}
233223
}
234224

@@ -237,28 +227,15 @@ namespace
237227
}
238228

239229
if (state_delta.code.has_value()) {
240-
byte_string const code{
241-
state_delta.code.value().data(),
242-
state_delta.code.value().size()};
243-
state.set_code(address, code);
230+
state.set_code(address, state_delta.code.value());
244231
}
245232

246233
auto const update_state =
247-
[&](std::map<byte_string, byte_string> const &diff) {
234+
[&address = address, &state = state](
235+
ankerl::unordered_dense::
236+
segmented_map<bytes32_t, bytes32_t> const &diff) {
248237
for (auto const &[key, value] : diff) {
249-
bytes32_t storage_key;
250-
bytes32_t storage_value;
251-
std::memcpy(
252-
storage_key.bytes,
253-
key.data(),
254-
sizeof(bytes32_t));
255-
std::memcpy(
256-
storage_value.bytes,
257-
value.data(),
258-
sizeof(bytes32_t));
259-
260-
state.set_storage(
261-
address, storage_key, storage_value);
238+
state.set_storage(address, key, value);
262239
}
263240
};
264241

@@ -351,7 +328,8 @@ void add_override_address(
351328

352329
MONAD_ASSERT(addr);
353330
MONAD_ASSERT(addr_len == sizeof(Address));
354-
byte_string const address{addr, addr + addr_len};
331+
Address address;
332+
std::memcpy(address.bytes, addr, sizeof(Address));
355333

356334
MONAD_ASSERT(m->override_sets.find(address) == m->override_sets.end());
357335
m->override_sets.emplace(address, StateOverrideObj{});
@@ -366,12 +344,14 @@ void set_override_balance(
366344

367345
MONAD_ASSERT(addr);
368346
MONAD_ASSERT(addr_len == sizeof(Address));
369-
byte_string const address{addr, addr + addr_len};
347+
Address address;
348+
std::memcpy(address.bytes, addr, sizeof(Address));
370349
MONAD_ASSERT(m->override_sets.find(address) != m->override_sets.end());
371350

372351
MONAD_ASSERT(balance);
373352
MONAD_ASSERT(balance_len == sizeof(uint256_t));
374-
m->override_sets[address].balance = {balance, balance + balance_len};
353+
m->override_sets[address].balance =
354+
intx::be::unsafe::load<uint256_t>(balance);
375355
}
376356

377357
void set_override_nonce(
@@ -382,7 +362,8 @@ void set_override_nonce(
382362

383363
MONAD_ASSERT(addr);
384364
MONAD_ASSERT(addr_len == sizeof(Address));
385-
byte_string const address{addr, addr + addr_len};
365+
Address address;
366+
std::memcpy(address.bytes, addr, sizeof(Address));
386367
MONAD_ASSERT(m->override_sets.find(address) != m->override_sets.end());
387368

388369
m->override_sets[address].nonce = nonce;
@@ -396,7 +377,8 @@ void set_override_code(
396377

397378
MONAD_ASSERT(addr);
398379
MONAD_ASSERT(addr_len == sizeof(Address));
399-
byte_string const address{addr, addr + addr_len};
380+
Address address;
381+
std::memcpy(address.bytes, addr, sizeof(Address));
400382
MONAD_ASSERT(m->override_sets.find(address) != m->override_sets.end());
401383

402384
MONAD_ASSERT(code);
@@ -412,18 +394,23 @@ void set_override_state_diff(
412394

413395
MONAD_ASSERT(addr);
414396
MONAD_ASSERT(addr_len == sizeof(Address));
415-
byte_string const address{addr, addr + addr_len};
397+
Address address;
398+
std::memcpy(address.bytes, addr, sizeof(Address));
416399
MONAD_ASSERT(m->override_sets.find(address) != m->override_sets.end());
417400

418401
MONAD_ASSERT(key);
419402
MONAD_ASSERT(key_len == sizeof(bytes32_t));
420-
byte_string const k{key, key + key_len};
403+
bytes32_t k;
404+
std::memcpy(k.bytes, key, sizeof(bytes32_t));
421405

422406
MONAD_ASSERT(value);
407+
MONAD_ASSERT(value_len == sizeof(bytes32_t));
408+
bytes32_t v;
409+
std::memcpy(v.bytes, value, sizeof(bytes32_t));
423410

424411
auto &state_object = m->override_sets[address].state_diff;
425412
MONAD_ASSERT(state_object.find(k) == state_object.end());
426-
state_object.emplace(k, byte_string{value, value + value_len});
413+
state_object.emplace(k, v);
427414
}
428415

429416
void set_override_state(
@@ -435,18 +422,23 @@ void set_override_state(
435422

436423
MONAD_ASSERT(addr);
437424
MONAD_ASSERT(addr_len == sizeof(Address));
438-
byte_string const address{addr, addr + addr_len};
425+
Address address;
426+
std::memcpy(address.bytes, addr, sizeof(Address));
439427
MONAD_ASSERT(m->override_sets.find(address) != m->override_sets.end());
440428

441429
MONAD_ASSERT(key);
442430
MONAD_ASSERT(key_len == sizeof(bytes32_t));
443-
byte_string const k{key, key + key_len};
431+
bytes32_t k;
432+
std::memcpy(k.bytes, key, sizeof(bytes32_t));
444433

445434
MONAD_ASSERT(value);
435+
MONAD_ASSERT(value_len == sizeof(bytes32_t));
436+
bytes32_t v;
437+
std::memcpy(v.bytes, value, sizeof(bytes32_t));
446438

447439
auto &state_object = m->override_sets[address].state;
448440
MONAD_ASSERT(state_object.find(k) == state_object.end());
449-
state_object.emplace(k, byte_string{value, value + value_len});
441+
state_object.emplace(k, v);
450442
}
451443

452444
void monad_executor_result_release(monad_executor_result *const result)

0 commit comments

Comments
 (0)