@@ -2,15 +2,20 @@ use std::{convert::Infallible, time::SystemTime};
2
2
3
3
use anyhow:: anyhow;
4
4
use edr_eth:: {
5
- block:: { BlobGas , BlockOptions } ,
5
+ block:: { miner_reward , BlobGas , BlockOptions } ,
6
6
remote:: { PreEip1898BlockSpec , RpcClient } ,
7
7
signature:: secret_key_from_str,
8
8
spec:: chain_hardfork_activations,
9
9
trie:: KECCAK_NULL_RLP ,
10
10
withdrawal:: Withdrawal ,
11
11
Address , HashMap , SpecId , U256 ,
12
12
} ;
13
- use edr_evm:: { alloy_primitives:: U160 , Block , MineOrdering , RemoteBlock } ;
13
+ use edr_evm:: {
14
+ alloy_primitives:: U160 ,
15
+ blockchain:: { Blockchain , ForkedBlockchain } ,
16
+ state:: IrregularState ,
17
+ Block , BlockBuilder , CfgEnv , RandomHashGenerator , RemoteBlock ,
18
+ } ;
14
19
15
20
use super :: * ;
16
21
use crate :: { config:: MiningConfig , requests:: hardhat:: rpc_types:: ForkConfig } ;
@@ -106,53 +111,70 @@ pub async fn run_full_block(url: String, block_number: u64, chain_id: u64) -> an
106
111
RemoteBlock :: new ( block, Arc :: new ( rpc_client) , runtime. clone ( ) ) ?
107
112
} ;
108
113
114
+ let rpc_client = RpcClient :: new ( & url, default_config. cache_dir . clone ( ) , None ) ?;
115
+ let mut irregular_state = IrregularState :: default ( ) ;
116
+ let state_root_generator = Arc :: new ( parking_lot:: Mutex :: new ( RandomHashGenerator :: with_seed (
117
+ edr_defaults:: STATE_ROOT_HASH_SEED ,
118
+ ) ) ) ;
119
+ let hardfork_activation_overrides = HashMap :: new ( ) ;
120
+
109
121
let hardfork_activations =
110
122
chain_hardfork_activations ( chain_id) . ok_or ( anyhow ! ( "Unsupported chain id" ) ) ?;
111
123
112
- let hardfork = hardfork_activations
124
+ let spec_id = hardfork_activations
113
125
. hardfork_at_block_number ( block_number)
114
126
. ok_or ( anyhow ! ( "Unsupported block number" ) ) ?;
115
127
128
+ let blockchain = ForkedBlockchain :: new (
129
+ runtime. clone ( ) ,
130
+ Some ( chain_id) ,
131
+ spec_id,
132
+ rpc_client,
133
+ Some ( block_number - 1 ) ,
134
+ & mut irregular_state,
135
+ state_root_generator,
136
+ & hardfork_activation_overrides,
137
+ )
138
+ . await ?;
139
+
140
+ let mut cfg = CfgEnv :: default ( ) ;
141
+ cfg. chain_id = chain_id;
142
+ cfg. spec_id = spec_id;
143
+ cfg. disable_eip3607 = true ;
144
+
145
+ let parent = blockchain. last_block ( ) ?;
116
146
let replay_header = replay_block. header ( ) ;
117
- let block_gas_limit = replay_header. gas_limit ;
118
-
119
- let config = ProviderConfig {
120
- block_gas_limit,
121
- chain_id,
122
- coinbase : replay_header. beneficiary ,
123
- hardfork,
124
- initial_base_fee_per_gas : None ,
125
- mining : MiningConfig {
126
- auto_mine : false ,
127
- interval : None ,
128
- mem_pool : MemPoolConfig {
129
- // Use first-in, first-out to replay the transaction in the exact same order
130
- order : MineOrdering :: Fifo ,
131
- } ,
132
- } ,
133
- network_id : 1 ,
134
- ..default_config
135
- } ;
136
147
137
- let logger = Box :: < NoopLogger > :: default ( ) ;
138
- let noop_subscription = Box :: new ( |_| ( ) ) ;
148
+ let mut builder = BlockBuilder :: new (
149
+ cfg,
150
+ parent. header ( ) ,
151
+ BlockOptions {
152
+ beneficiary : Some ( replay_header. beneficiary ) ,
153
+ gas_limit : Some ( replay_header. gas_limit ) ,
154
+ extra_data : Some ( replay_header. extra_data . clone ( ) ) ,
155
+ mix_hash : Some ( replay_header. mix_hash ) ,
156
+ nonce : Some ( replay_header. nonce ) ,
157
+ parent_beacon_block_root : replay_header. parent_beacon_block_root ,
158
+ state_root : Some ( replay_header. state_root ) ,
159
+ timestamp : Some ( replay_header. timestamp ) ,
160
+ withdrawals : replay_block. withdrawals ( ) . map ( <[ Withdrawal ] >:: to_vec) ,
161
+ ..BlockOptions :: default ( )
162
+ } ,
163
+ None ,
164
+ ) ?;
139
165
140
- let mut provider_data = ProviderData :: new ( runtime, logger, noop_subscription, None , config) ?;
166
+ let mut state =
167
+ blockchain. state_at_block_number ( block_number - 1 , irregular_state. state_overrides ( ) ) ?;
141
168
142
169
for transaction in replay_block. transactions ( ) {
143
- provider_data . send_transaction ( transaction. clone ( ) ) ?;
170
+ builder . add_transaction ( & blockchain , & mut state , transaction. clone ( ) , None ) ?;
144
171
}
145
172
146
- let mined_block = provider_data. mine_and_commit_block ( BlockOptions {
147
- extra_data : Some ( replay_header. extra_data . clone ( ) ) ,
148
- mix_hash : Some ( replay_header. mix_hash ) ,
149
- nonce : Some ( replay_header. nonce ) ,
150
- parent_beacon_block_root : replay_header. parent_beacon_block_root ,
151
- state_root : Some ( replay_header. state_root ) ,
152
- timestamp : Some ( replay_header. timestamp ) ,
153
- withdrawals : replay_block. withdrawals ( ) . map ( <[ Withdrawal ] >:: to_vec) ,
154
- ..BlockOptions :: default ( )
155
- } ) ?;
173
+ let rewards = vec ! [ (
174
+ replay_header. beneficiary,
175
+ miner_reward( spec_id) . unwrap_or( U256 :: ZERO ) ,
176
+ ) ] ;
177
+ let mined_block = builder. finalize ( & mut state, rewards) ?;
156
178
157
179
let mined_header = mined_block. block . header ( ) ;
158
180
assert_eq ! ( mined_header, replay_header) ;
0 commit comments