4
4
#pragma once
5
5
6
6
#include " baseline.hpp"
7
+ #include " constants.hpp"
7
8
#include " eof.hpp"
8
9
#include " execution_state.hpp"
9
10
#include " instructions_traits.hpp"
@@ -128,6 +129,27 @@ inline bool check_memory(
128
129
return check_memory (gas_left, memory, offset, static_cast <uint64_t >(size));
129
130
}
130
131
132
+ constexpr bool is_code_delegated (bytes_view code) noexcept
133
+ {
134
+ return code.starts_with (DELEGATION_MAGIC);
135
+ }
136
+
137
+ inline std::optional<evmc::address> get_delegate_address (
138
+ const evmc::address& addr, const evmc::HostContext& host) noexcept
139
+ {
140
+ std::array<uint8_t , std::size (DELEGATION_MAGIC)> prefix;
141
+ host.copy_code (addr, 0 , prefix.data (), prefix.size ());
142
+
143
+ if (!is_code_delegated (bytes_view{prefix.data (), prefix.size ()}))
144
+ return {};
145
+
146
+ assert (host.get_code_size (addr) == std::size (DELEGATION_MAGIC) + std::size (addr.bytes ));
147
+
148
+ evmc::address delegate_address;
149
+ host.copy_code (addr, prefix.size (), delegate_address.bytes , std::size (delegate_address.bytes ));
150
+ return delegate_address;
151
+ }
152
+
131
153
namespace instr ::core
132
154
{
133
155
@@ -518,21 +540,34 @@ inline void blobbasefee(StackTop stack, ExecutionState& state) noexcept
518
540
inline Result extcodesize (StackTop stack, int64_t gas_left, ExecutionState& state) noexcept
519
541
{
520
542
auto & x = stack.top ();
521
- const auto addr = intx::be::trunc <evmc::address>(x);
543
+ auto addr = intx::be::trunc <evmc::address>(x);
522
544
523
545
if (state.rev >= EVMC_BERLIN && state.host .access_account (addr) == EVMC_ACCESS_COLD)
524
546
{
525
547
if ((gas_left -= instr::additional_cold_account_access_cost) < 0 )
526
548
return {EVMC_OUT_OF_GAS, gas_left};
527
549
}
528
550
551
+ if (state.rev >= EVMC_PRAGUE)
552
+ {
553
+ if (const auto delegate_addr = get_delegate_address (addr, state.host ))
554
+ {
555
+ addr = *delegate_addr;
556
+ if (state.host .access_account (addr) == EVMC_ACCESS_COLD)
557
+ {
558
+ if ((gas_left -= instr::additional_cold_account_access_cost) < 0 )
559
+ return {EVMC_OUT_OF_GAS, gas_left};
560
+ }
561
+ }
562
+ }
563
+
529
564
x = state.host .get_code_size (addr);
530
565
return {EVMC_SUCCESS, gas_left};
531
566
}
532
567
533
568
inline Result extcodecopy (StackTop stack, int64_t gas_left, ExecutionState& state) noexcept
534
569
{
535
- const auto addr = intx::be::trunc <evmc::address>(stack.pop ());
570
+ auto addr = intx::be::trunc <evmc::address>(stack.pop ());
536
571
const auto & mem_index = stack.pop ();
537
572
const auto & input_index = stack.pop ();
538
573
const auto & size = stack.pop ();
@@ -550,6 +585,19 @@ inline Result extcodecopy(StackTop stack, int64_t gas_left, ExecutionState& stat
550
585
return {EVMC_OUT_OF_GAS, gas_left};
551
586
}
552
587
588
+ if (state.rev >= EVMC_PRAGUE)
589
+ {
590
+ if (const auto delegate_addr = get_delegate_address (addr, state.host ))
591
+ {
592
+ addr = *delegate_addr;
593
+ if (state.host .access_account (addr) == EVMC_ACCESS_COLD)
594
+ {
595
+ if ((gas_left -= instr::additional_cold_account_access_cost) < 0 )
596
+ return {EVMC_OUT_OF_GAS, gas_left};
597
+ }
598
+ }
599
+ }
600
+
553
601
if (s > 0 )
554
602
{
555
603
const auto src =
@@ -636,14 +684,27 @@ inline Result returndatacopy(StackTop stack, int64_t gas_left, ExecutionState& s
636
684
inline Result extcodehash (StackTop stack, int64_t gas_left, ExecutionState& state) noexcept
637
685
{
638
686
auto & x = stack.top ();
639
- const auto addr = intx::be::trunc <evmc::address>(x);
687
+ auto addr = intx::be::trunc <evmc::address>(x);
640
688
641
689
if (state.rev >= EVMC_BERLIN && state.host .access_account (addr) == EVMC_ACCESS_COLD)
642
690
{
643
691
if ((gas_left -= instr::additional_cold_account_access_cost) < 0 )
644
692
return {EVMC_OUT_OF_GAS, gas_left};
645
693
}
646
694
695
+ if (state.rev >= EVMC_PRAGUE)
696
+ {
697
+ if (const auto delegate_addr = get_delegate_address (addr, state.host ))
698
+ {
699
+ addr = *delegate_addr;
700
+ if (state.host .access_account (addr) == EVMC_ACCESS_COLD)
701
+ {
702
+ if ((gas_left -= instr::additional_cold_account_access_cost) < 0 )
703
+ return {EVMC_OUT_OF_GAS, gas_left};
704
+ }
705
+ }
706
+ }
707
+
647
708
x = intx::be::load<uint256>(state.host .get_code_hash (addr));
648
709
return {EVMC_SUCCESS, gas_left};
649
710
}
0 commit comments