Skip to content

Commit d789f3c

Browse files
Wodannfvictorio
andauthored
fix: use block builder to replay blocks (#4940)
Co-authored-by: Franco Victorio <[email protected]>
1 parent bf1e97c commit d789f3c

File tree

5 files changed

+110
-39
lines changed

5 files changed

+110
-39
lines changed

.github/workflows/test-recent-mainnet-block.yml

+1-2
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@ jobs:
3535
uses: actions-rs/cargo@v1
3636
env:
3737
RUSTFLAGS: ${{ matrix.RUSTFLAGS }}
38-
ALCHEMY_URL: ${{ secrets.ALCHEMY_URL }}
3938
with:
4039
command: replay-block
41-
args: -u $ALCHEMY_URL -c 1
40+
args: -u ${{ secrets.ALCHEMY_URL }} -c 1
4241

4342
- name: Notify failures
4443
if: failure()

crates/edr_napi/index.js

+43
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,49 @@ switch (platform) {
237237
loadError = e
238238
}
239239
break
240+
case 'riscv64':
241+
if (isMusl()) {
242+
localFileExisted = existsSync(
243+
join(__dirname, 'edr.linux-riscv64-musl.node')
244+
)
245+
try {
246+
if (localFileExisted) {
247+
nativeBinding = require('./edr.linux-riscv64-musl.node')
248+
} else {
249+
nativeBinding = require('@nomicfoundation/edr-linux-riscv64-musl')
250+
}
251+
} catch (e) {
252+
loadError = e
253+
}
254+
} else {
255+
localFileExisted = existsSync(
256+
join(__dirname, 'edr.linux-riscv64-gnu.node')
257+
)
258+
try {
259+
if (localFileExisted) {
260+
nativeBinding = require('./edr.linux-riscv64-gnu.node')
261+
} else {
262+
nativeBinding = require('@nomicfoundation/edr-linux-riscv64-gnu')
263+
}
264+
} catch (e) {
265+
loadError = e
266+
}
267+
}
268+
break
269+
case 's390x':
270+
localFileExisted = existsSync(
271+
join(__dirname, 'edr.linux-s390x-gnu.node')
272+
)
273+
try {
274+
if (localFileExisted) {
275+
nativeBinding = require('./edr.linux-s390x-gnu.node')
276+
} else {
277+
nativeBinding = require('@nomicfoundation/edr-linux-s390x-gnu')
278+
}
279+
} catch (e) {
280+
loadError = e
281+
}
282+
break
240283
default:
241284
throw new Error(`Unsupported architecture on Linux: ${arch}`)
242285
}

crates/edr_provider/src/data.rs

+7
Original file line numberDiff line numberDiff line change
@@ -3721,6 +3721,13 @@ mod tests {
37213721
chain_id: 1,
37223722
url: get_alchemy_url(),
37233723
},
3724+
// This block contains a sequence of transaction that first raise
3725+
// an empty account's balance and then decrease it
3726+
mainnet_19318016 => {
3727+
block_number: 19_318_016,
3728+
chain_id: 1,
3729+
url: get_alchemy_url(),
3730+
},
37243731
// This block has both EIP-2930 and EIP-1559 transactions
37253732
goerli_merge => {
37263733
block_number: 7_728_449,

crates/edr_provider/src/test_utils.rs

+58-36
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@ use std::{convert::Infallible, time::SystemTime};
22

33
use anyhow::anyhow;
44
use edr_eth::{
5-
block::{BlobGas, BlockOptions},
5+
block::{miner_reward, BlobGas, BlockOptions},
66
remote::{PreEip1898BlockSpec, RpcClient},
77
signature::secret_key_from_str,
88
spec::chain_hardfork_activations,
99
trie::KECCAK_NULL_RLP,
1010
withdrawal::Withdrawal,
1111
Address, HashMap, SpecId, U256,
1212
};
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+
};
1419

1520
use super::*;
1621
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
106111
RemoteBlock::new(block, Arc::new(rpc_client), runtime.clone())?
107112
};
108113

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+
109121
let hardfork_activations =
110122
chain_hardfork_activations(chain_id).ok_or(anyhow!("Unsupported chain id"))?;
111123

112-
let hardfork = hardfork_activations
124+
let spec_id = hardfork_activations
113125
.hardfork_at_block_number(block_number)
114126
.ok_or(anyhow!("Unsupported block number"))?;
115127

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()?;
116146
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-
};
136147

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+
)?;
139165

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())?;
141168

142169
for transaction in replay_block.transactions() {
143-
provider_data.send_transaction(transaction.clone())?;
170+
builder.add_transaction(&blockchain, &mut state, transaction.clone(), None)?;
144171
}
145172

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)?;
156178

157179
let mined_header = mined_block.block.header();
158180
assert_eq!(mined_header, replay_header);

packages/hardhat-core/test/internal/hardhat-network/helpers/constants.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export const UNISWAP_FACTORY_ADDRESS = Address.fromString(
2121
);
2222

2323
export const EMPTY_ACCOUNT_ADDRESS = Address.fromString(
24-
"0x1234567890abcdef1234567890abcdef12345678"
24+
"0x246a566a96ae9fa8dcf04d4c6c094c7c492f018f"
2525
);
2626

2727
// top Ether holder as of 24.08.2020

0 commit comments

Comments
 (0)