Skip to content

Commit 4ae13b7

Browse files
committed
Prefetch access list in parallel
1 parent f269912 commit 4ae13b7

File tree

4 files changed

+106
-0
lines changed

4 files changed

+106
-0
lines changed

category/execution/ethereum/execute_block.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,71 @@ Result<std::vector<Receipt>> execute_block(
341341

342342
execute_block_header<traits>(chain, block_state, block.header);
343343

344+
auto const access_list_begin = std::chrono::steady_clock::now();
345+
{
346+
size_t count = 0;
347+
for (auto const &tx : block.transactions) {
348+
count += tx.access_list.size();
349+
}
350+
std::shared_ptr<boost::fibers::promise<void>[]> promises{
351+
new boost::fibers::promise<void>[count]};
352+
size_t i = 0;
353+
for (auto const &tx : block.transactions) {
354+
for (auto const &ae : tx.access_list) {
355+
MONAD_ASSERT(i < count);
356+
priority_pool.submit(
357+
i, [promises, i, addr = ae.a, &block_state]() {
358+
block_state.read_account(addr);
359+
promises[i].set_value();
360+
});
361+
++i;
362+
}
363+
}
364+
MONAD_ASSERT(i == count);
365+
block_metrics.set_access_list_addrs(count);
366+
for (size_t j = 0; j < count; ++j) {
367+
promises[j].get_future().wait();
368+
}
369+
}
370+
{
371+
size_t count = 0;
372+
for (auto const &tx : block.transactions) {
373+
for (auto const &ae : tx.access_list) {
374+
count += ae.keys.size();
375+
}
376+
}
377+
std::shared_ptr<boost::fibers::promise<void>[]> promises{
378+
new boost::fibers::promise<void>[count]};
379+
size_t i = 0;
380+
for (auto const &tx : block.transactions) {
381+
for (auto const &ae : tx.access_list) {
382+
Address const addr = ae.a;
383+
auto const account = block_state.read_account(addr);
384+
Incarnation const incarnation = account.has_value()
385+
? account->incarnation
386+
: Incarnation{0, 0};
387+
for (auto const &key : ae.keys) {
388+
MONAD_ASSERT(i < count);
389+
priority_pool.submit(
390+
i,
391+
[promises, i, addr, incarnation, key, &block_state]() {
392+
block_state.read_storage(addr, incarnation, key);
393+
promises[i].set_value();
394+
});
395+
++i;
396+
}
397+
}
398+
}
399+
MONAD_ASSERT(i == count);
400+
block_metrics.set_access_list_keys(count);
401+
for (size_t j = 0; j < count; ++j) {
402+
promises[j].get_future().wait();
403+
}
404+
}
405+
block_metrics.set_access_list_time(
406+
std::chrono::duration_cast<std::chrono::microseconds>(
407+
std::chrono::steady_clock::now() - access_list_begin));
408+
344409
BOOST_OUTCOME_TRY(
345410
auto const retvals,
346411
execute_block_transactions<traits>(

category/execution/ethereum/metrics/block_metrics.hpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ class BlockMetrics
2525
{
2626
uint32_t n_retries_{0};
2727
std::chrono::microseconds tx_exec_time_{1};
28+
std::chrono::microseconds access_list_time_{1};
29+
size_t n_access_list_addrs_{0};
30+
size_t n_access_list_keys_{0};
2831

2932
public:
3033
void inc_retries()
@@ -42,10 +45,40 @@ class BlockMetrics
4245
tx_exec_time_ = exec_time;
4346
}
4447

48+
void set_access_list_time(std::chrono::microseconds const access_list_time)
49+
{
50+
access_list_time_ = access_list_time;
51+
}
52+
53+
void set_access_list_addrs(size_t const count)
54+
{
55+
n_access_list_addrs_ = count;
56+
}
57+
58+
void set_access_list_keys(size_t const count)
59+
{
60+
n_access_list_keys_ = count;
61+
}
62+
4563
std::chrono::microseconds tx_exec_time() const
4664
{
4765
return tx_exec_time_;
4866
}
67+
68+
std::chrono::microseconds access_list_time() const
69+
{
70+
return access_list_time_;
71+
}
72+
73+
size_t access_list_addrs() const
74+
{
75+
return n_access_list_addrs_;
76+
}
77+
78+
size_t access_list_keys() const
79+
{
80+
return n_access_list_keys_;
81+
}
4982
};
5083

5184
MONAD_NAMESPACE_END

cmd/monad/runloop_ethereum.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ Result<void> process_ethereum_block(
183183
LOG_INFO(
184184
"__exec_block,bl={:8},ts={}"
185185
",tx={:5},rt={:4},rtp={:5.2f}%"
186+
",ala={:3},alk={:4},alt={:>7}"
186187
",sr={:>7},txe={:>8},cmt={:>8},tot={:>8},tpse={:5},tps={:5}"
187188
",gas={:9},gpse={:4},gps={:3}{}{}{}",
188189
block.header.number,
@@ -193,6 +194,9 @@ Result<void> process_ethereum_block(
193194
block_metrics.num_retries(),
194195
100.0 * (double)block_metrics.num_retries() /
195196
std::max(1.0, (double)block.transactions.size()),
197+
block_metrics.access_list_addrs(),
198+
block_metrics.access_list_keys(),
199+
block_metrics.access_list_time(),
196200
sender_recovery_time,
197201
block_metrics.tx_exec_time(),
198202
commit_time,

cmd/monad/runloop_monad.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ Result<BlockExecOutput> propose_block(
326326
LOG_INFO(
327327
"__exec_block,bl={:8},id={},ts={}"
328328
",tx={:5},rt={:4},rtp={:5.2f}%"
329+
",ala={:3},alk={:4},alt={:>7}"
329330
",sr={:>7},txe={:>8},cmt={:>8},tot={:>8},tpse={:5},tps={:5}"
330331
",gas={:9},gpse={:4},gps={:3}{}{}{}",
331332
block.header.number,
@@ -337,6 +338,9 @@ Result<BlockExecOutput> propose_block(
337338
block_metrics.num_retries(),
338339
100.0 * (double)block_metrics.num_retries() /
339340
std::max(1.0, (double)block.transactions.size()),
341+
block_metrics.access_list_addrs(),
342+
block_metrics.access_list_keys(),
343+
block_metrics.access_list_time(),
340344
sender_recovery_time,
341345
block_metrics.tx_exec_time(),
342346
commit_time,

0 commit comments

Comments
 (0)