mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(storage, tree): respect Transaction Lookup pruning in the blockchain tree (#4410)
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -5817,6 +5817,7 @@ dependencies = [
|
||||
name = "reth-provider"
|
||||
version = "0.1.0-alpha.8"
|
||||
dependencies = [
|
||||
"assert_matches",
|
||||
"auto_impl",
|
||||
"derive_more",
|
||||
"itertools 0.11.0",
|
||||
|
||||
@ -156,3 +156,4 @@ c-kzg = { git = "https://github.com/ethereum/c-kzg-4844" }
|
||||
### misc-testing
|
||||
proptest = "1.0"
|
||||
arbitrary = "1.1"
|
||||
assert_matches = "1.5.0"
|
||||
|
||||
@ -193,7 +193,7 @@ impl Command {
|
||||
let provider_rw = factory.provider_rw()?;
|
||||
|
||||
// Insert block, state and hashes
|
||||
provider_rw.insert_block(block.clone(), None)?;
|
||||
provider_rw.insert_block(block.clone(), None, None)?;
|
||||
block_state.write_to_db(provider_rw.tx_ref(), block.number)?;
|
||||
let storage_lists = provider_rw.changed_storages_with_range(block.number..=block.number)?;
|
||||
let storages = provider_rw.plainstate_storages(storage_lists)?;
|
||||
|
||||
@ -185,7 +185,7 @@ impl Command {
|
||||
continue
|
||||
}
|
||||
};
|
||||
provider_rw.insert_block(sealed_block.block, Some(sealed_block.senders))?;
|
||||
provider_rw.insert_block(sealed_block.block, Some(sealed_block.senders), None)?;
|
||||
}
|
||||
|
||||
// Check if any of hashing or merkle stages aren't on the same block number as
|
||||
|
||||
@ -267,6 +267,9 @@ impl<Ext: RethCliExt> NodeCommand<Ext> {
|
||||
let metrics_listener = MetricsListener::new(metrics_rx);
|
||||
ctx.task_executor.spawn_critical("metrics listener task", metrics_listener);
|
||||
|
||||
let prune_config =
|
||||
self.pruning.prune_config(Arc::clone(&self.chain))?.or(config.prune.clone());
|
||||
|
||||
// configure blockchain tree
|
||||
let tree_externals = TreeExternals::new(
|
||||
db.clone(),
|
||||
@ -284,6 +287,7 @@ impl<Ext: RethCliExt> NodeCommand<Ext> {
|
||||
tree_externals,
|
||||
canon_state_notification_sender.clone(),
|
||||
tree_config,
|
||||
prune_config.clone().map(|config| config.parts),
|
||||
)?
|
||||
.with_sync_metrics_tx(metrics_tx.clone()),
|
||||
);
|
||||
@ -365,9 +369,6 @@ impl<Ext: RethCliExt> NodeCommand<Ext> {
|
||||
None
|
||||
};
|
||||
|
||||
let prune_config =
|
||||
self.pruning.prune_config(Arc::clone(&self.chain))?.or(config.prune.clone());
|
||||
|
||||
// Configure the pipeline
|
||||
let (mut pipeline, client) = if self.dev.dev {
|
||||
info!(target: "reth::cli", "Starting Reth in dev mode");
|
||||
|
||||
@ -40,7 +40,7 @@ reth-interfaces = { workspace = true, features = ["test-utils"] }
|
||||
reth-primitives = { workspace = true , features = ["test-utils"] }
|
||||
reth-provider = { workspace = true, features = ["test-utils"] }
|
||||
parking_lot.workspace = true
|
||||
assert_matches = "1.5"
|
||||
assert_matches.workspace = true
|
||||
tokio = { workspace = true, features = ["macros", "sync"] }
|
||||
|
||||
[features]
|
||||
|
||||
@ -16,7 +16,7 @@ use reth_interfaces::{
|
||||
Error,
|
||||
};
|
||||
use reth_primitives::{
|
||||
BlockHash, BlockNumHash, BlockNumber, ForkBlock, Hardfork, Receipt, SealedBlock,
|
||||
BlockHash, BlockNumHash, BlockNumber, ForkBlock, Hardfork, PruneModes, Receipt, SealedBlock,
|
||||
SealedBlockWithSenders, SealedHeader, U256,
|
||||
};
|
||||
use reth_provider::{
|
||||
@ -93,6 +93,7 @@ pub struct BlockchainTree<DB: Database, C: Consensus, EF: ExecutorFactory> {
|
||||
metrics: TreeMetrics,
|
||||
/// Metrics for sync stages.
|
||||
sync_metrics_tx: Option<MetricEventsSender>,
|
||||
prune_modes: Option<PruneModes>,
|
||||
}
|
||||
|
||||
/// A container that wraps chains and block indices to allow searching for block hashes across all
|
||||
@ -110,6 +111,7 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
|
||||
externals: TreeExternals<DB, C, EF>,
|
||||
canon_state_notification_sender: CanonStateNotificationSender,
|
||||
config: BlockchainTreeConfig,
|
||||
prune_modes: Option<PruneModes>,
|
||||
) -> Result<Self, Error> {
|
||||
let max_reorg_depth = config.max_reorg_depth();
|
||||
|
||||
@ -145,6 +147,7 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
|
||||
canon_state_notification_sender,
|
||||
metrics: Default::default(),
|
||||
sync_metrics_tx: None,
|
||||
prune_modes,
|
||||
})
|
||||
}
|
||||
|
||||
@ -1048,7 +1051,11 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
|
||||
let (blocks, state) = chain.into_inner();
|
||||
|
||||
provider
|
||||
.append_blocks_with_post_state(blocks.into_blocks().collect(), state)
|
||||
.append_blocks_with_post_state(
|
||||
blocks.into_blocks().collect(),
|
||||
state,
|
||||
self.prune_modes.as_ref(),
|
||||
)
|
||||
.map_err(|e| BlockExecutionError::CanonicalCommit { inner: e.to_string() })?;
|
||||
|
||||
provider.commit()?;
|
||||
@ -1173,7 +1180,7 @@ mod tests {
|
||||
let factory = ProviderFactory::new(&db, MAINNET.clone());
|
||||
let provider = factory.provider_rw().unwrap();
|
||||
|
||||
provider.insert_block(genesis, None).unwrap();
|
||||
provider.insert_block(genesis, None, None).unwrap();
|
||||
|
||||
// insert first 10 blocks
|
||||
for i in 0..10 {
|
||||
@ -1279,7 +1286,7 @@ mod tests {
|
||||
let config = BlockchainTreeConfig::new(1, 2, 3, 2);
|
||||
let (sender, mut canon_notif) = tokio::sync::broadcast::channel(10);
|
||||
let mut tree =
|
||||
BlockchainTree::new(externals, sender, config).expect("failed to create tree");
|
||||
BlockchainTree::new(externals, sender, config, None).expect("failed to create tree");
|
||||
|
||||
// genesis block 10 is already canonical
|
||||
assert!(tree.make_canonical(&H256::zero()).is_ok());
|
||||
|
||||
@ -46,4 +46,4 @@ reth-tracing = { path = "../../tracing" }
|
||||
reth-revm = { path = "../../revm" }
|
||||
reth-downloaders = { path = "../../net/downloaders" }
|
||||
|
||||
assert_matches = "1.5"
|
||||
assert_matches.workspace = true
|
||||
|
||||
@ -1880,7 +1880,9 @@ mod tests {
|
||||
BeaconForkChoiceUpdateError,
|
||||
};
|
||||
use assert_matches::assert_matches;
|
||||
use reth_primitives::{stage::StageCheckpoint, ChainSpec, ChainSpecBuilder, H256, MAINNET};
|
||||
use reth_primitives::{
|
||||
stage::StageCheckpoint, ChainSpec, ChainSpecBuilder, PruneModes, H256, MAINNET,
|
||||
};
|
||||
use reth_provider::{BlockWriter, ProviderFactory};
|
||||
use reth_rpc_types::engine::{
|
||||
ExecutionPayloadV1, ForkchoiceState, ForkchoiceUpdated, PayloadStatus,
|
||||
@ -2056,7 +2058,7 @@ mod tests {
|
||||
let factory = ProviderFactory::new(db, chain);
|
||||
let provider = factory.provider_rw().unwrap();
|
||||
blocks
|
||||
.try_for_each(|b| provider.insert_block(b.clone(), None).map(|_| ()))
|
||||
.try_for_each(|b| provider.insert_block(b.clone(), None, None).map(|_| ()))
|
||||
.expect("failed to insert");
|
||||
provider.commit().unwrap();
|
||||
}
|
||||
|
||||
@ -463,7 +463,7 @@ where
|
||||
let config = BlockchainTreeConfig::new(1, 2, 3, 2);
|
||||
let (canon_state_notification_sender, _) = tokio::sync::broadcast::channel(3);
|
||||
let tree = ShareableBlockchainTree::new(
|
||||
BlockchainTree::new(externals, canon_state_notification_sender, config)
|
||||
BlockchainTree::new(externals, canon_state_notification_sender, config, None)
|
||||
.expect("failed to create tree"),
|
||||
);
|
||||
let shareable_db = ProviderFactory::new(db.clone(), self.base_config.chain_spec.clone());
|
||||
|
||||
@ -16,5 +16,5 @@ reth-provider.workspace = true
|
||||
[dev-dependencies]
|
||||
reth-interfaces = { workspace = true, features = ["test-utils"] }
|
||||
reth-provider = { workspace = true, features = ["test-utils"] }
|
||||
assert_matches = "1.5.0"
|
||||
assert_matches.workspace = true
|
||||
mockall = "0.11.3"
|
||||
|
||||
@ -42,7 +42,7 @@ reth-db = { path = "../../storage/db", features = ["test-utils"] }
|
||||
reth-interfaces = { workspace = true, features = ["test-utils"] }
|
||||
reth-tracing = { path = "../../tracing" }
|
||||
|
||||
assert_matches = "1.5.0"
|
||||
assert_matches.workspace = true
|
||||
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
|
||||
reth-rlp.workspace = true
|
||||
itertools.workspace = true
|
||||
|
||||
@ -85,7 +85,7 @@ revm-primitives = { workspace = true, features = ["arbitrary"] }
|
||||
arbitrary = { workspace = true, features = ["derive"] }
|
||||
proptest.workspace = true
|
||||
proptest-derive = "0.3"
|
||||
assert_matches = "1.5.0"
|
||||
assert_matches.workspace = true
|
||||
toml = "0.7.4"
|
||||
|
||||
# necessary so we don't hit a "undeclared 'std'":
|
||||
|
||||
@ -49,6 +49,11 @@ impl PruneMode {
|
||||
PruneMode::Before(n) => *n > block,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the prune mode is [`PruneMode::Full`].
|
||||
pub fn is_full(&self) -> bool {
|
||||
matches!(self, Self::Full)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@ -34,4 +34,4 @@ reth-stages = { path = "../stages", features = ["test-utils"] }
|
||||
|
||||
# misc
|
||||
|
||||
assert_matches = "1.5.0"
|
||||
assert_matches.workspace = true
|
||||
|
||||
@ -34,4 +34,4 @@ reth-rlp.workspace = true
|
||||
reth-interfaces = { workspace = true, features = ["test-utils"] }
|
||||
reth-provider = { workspace = true, features = ["test-utils"] }
|
||||
reth-payload-builder = { workspace = true, features = ["test-utils"] }
|
||||
assert_matches = "1.5.0"
|
||||
assert_matches.workspace = true
|
||||
|
||||
@ -70,6 +70,6 @@ futures.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
jsonrpsee = { workspace = true, features = ["client"] }
|
||||
assert_matches = "1.5.0"
|
||||
assert_matches.workspace = true
|
||||
tempfile = "3.5.0"
|
||||
reth-interfaces = { workspace = true, features = ["test-utils"] }
|
||||
|
||||
@ -61,7 +61,7 @@ reth-trie = { path = "../trie", features = ["test-utils"] }
|
||||
|
||||
itertools.workspace = true
|
||||
tokio = { workspace = true, features = ["rt", "sync", "macros"] }
|
||||
assert_matches = "1.5.0"
|
||||
assert_matches.workspace = true
|
||||
rand.workspace = true
|
||||
paste = "1.0"
|
||||
|
||||
|
||||
@ -526,8 +526,8 @@ mod tests {
|
||||
let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap();
|
||||
let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice();
|
||||
let block = SealedBlock::decode(&mut block_rlp).unwrap();
|
||||
provider.insert_block(genesis, None).unwrap();
|
||||
provider.insert_block(block.clone(), None).unwrap();
|
||||
provider.insert_block(genesis, None, None).unwrap();
|
||||
provider.insert_block(block.clone(), None, None).unwrap();
|
||||
provider.commit().unwrap();
|
||||
|
||||
let previous_stage_checkpoint = ExecutionCheckpoint {
|
||||
@ -562,8 +562,8 @@ mod tests {
|
||||
let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap();
|
||||
let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice();
|
||||
let block = SealedBlock::decode(&mut block_rlp).unwrap();
|
||||
provider.insert_block(genesis, None).unwrap();
|
||||
provider.insert_block(block.clone(), None).unwrap();
|
||||
provider.insert_block(genesis, None, None).unwrap();
|
||||
provider.insert_block(block.clone(), None, None).unwrap();
|
||||
provider.commit().unwrap();
|
||||
|
||||
let previous_stage_checkpoint = ExecutionCheckpoint {
|
||||
@ -598,8 +598,8 @@ mod tests {
|
||||
let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap();
|
||||
let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice();
|
||||
let block = SealedBlock::decode(&mut block_rlp).unwrap();
|
||||
provider.insert_block(genesis, None).unwrap();
|
||||
provider.insert_block(block.clone(), None).unwrap();
|
||||
provider.insert_block(genesis, None, None).unwrap();
|
||||
provider.insert_block(block.clone(), None, None).unwrap();
|
||||
provider.commit().unwrap();
|
||||
|
||||
let previous_checkpoint = StageCheckpoint { block_number: 1, stage_checkpoint: None };
|
||||
@ -632,8 +632,8 @@ mod tests {
|
||||
let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap();
|
||||
let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice();
|
||||
let block = SealedBlock::decode(&mut block_rlp).unwrap();
|
||||
provider.insert_block(genesis, None).unwrap();
|
||||
provider.insert_block(block.clone(), None).unwrap();
|
||||
provider.insert_block(genesis, None, None).unwrap();
|
||||
provider.insert_block(block.clone(), None, None).unwrap();
|
||||
provider.commit().unwrap();
|
||||
|
||||
// insert pre state
|
||||
@ -742,8 +742,8 @@ mod tests {
|
||||
let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap();
|
||||
let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice();
|
||||
let block = SealedBlock::decode(&mut block_rlp).unwrap();
|
||||
provider.insert_block(genesis, None).unwrap();
|
||||
provider.insert_block(block.clone(), None).unwrap();
|
||||
provider.insert_block(genesis, None, None).unwrap();
|
||||
provider.insert_block(block.clone(), None, None).unwrap();
|
||||
provider.commit().unwrap();
|
||||
|
||||
// variables
|
||||
@ -820,8 +820,8 @@ mod tests {
|
||||
let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap();
|
||||
let mut block_rlp = hex!("f9025ff901f7a0c86e8cc0310ae7c531c758678ddbfd16fc51c8cef8cec650b032de9869e8b94fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa050554882fbbda2c2fd93fdc466db9946ea262a67f7a76cc169e714f105ab583da00967f09ef1dfed20c0eacfaa94d5cd4002eda3242ac47eae68972d07b106d192a0e3c8b47fbfc94667ef4cceb17e5cc21e3b1eebd442cebb27f07562b33836290db90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001830f42408238108203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f862f860800a83061a8094095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba072ed817487b84ba367d15d2f039b5fc5f087d0a8882fbdf73e8cb49357e1ce30a0403d800545b8fc544f92ce8124e2255f8c3c6af93f28243a120585d4c4c6a2a3c0").as_slice();
|
||||
let block = SealedBlock::decode(&mut block_rlp).unwrap();
|
||||
provider.insert_block(genesis, None).unwrap();
|
||||
provider.insert_block(block.clone(), None).unwrap();
|
||||
provider.insert_block(genesis, None, None).unwrap();
|
||||
provider.insert_block(block.clone(), None, None).unwrap();
|
||||
provider.commit().unwrap();
|
||||
|
||||
// variables
|
||||
|
||||
@ -95,7 +95,7 @@ impl AccountHashingStage {
|
||||
let blocks = random_block_range(&mut rng, opts.blocks.clone(), H256::zero(), opts.txs);
|
||||
|
||||
for block in blocks {
|
||||
provider.insert_block(block, None).unwrap();
|
||||
provider.insert_block(block, None, None).unwrap();
|
||||
}
|
||||
let mut accounts = random_eoa_account_range(&mut rng, opts.accounts);
|
||||
{
|
||||
|
||||
@ -81,8 +81,8 @@ mod tests {
|
||||
let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap();
|
||||
let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice();
|
||||
let block = SealedBlock::decode(&mut block_rlp).unwrap();
|
||||
provider.insert_block(genesis, None).unwrap();
|
||||
provider.insert_block(block.clone(), None).unwrap();
|
||||
provider.insert_block(genesis, None, None).unwrap();
|
||||
provider.insert_block(block.clone(), None, None).unwrap();
|
||||
|
||||
// Fill with bogus blocks to respect PruneMode distance.
|
||||
let mut head = block.hash;
|
||||
@ -90,7 +90,7 @@ mod tests {
|
||||
for block_number in 2..=tip {
|
||||
let nblock = random_block(&mut rng, block_number, Some(head), Some(0), Some(0));
|
||||
head = nblock.hash;
|
||||
provider.insert_block(nblock, None).unwrap();
|
||||
provider.insert_block(nblock, None, None).unwrap();
|
||||
}
|
||||
provider.commit().unwrap();
|
||||
|
||||
|
||||
@ -76,7 +76,7 @@ serde_json.workspace = true
|
||||
|
||||
paste = "1.0"
|
||||
|
||||
assert_matches = "1.5.0"
|
||||
assert_matches.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
vergen = { version = "8.0.0", features = ["git", "gitcl"] }
|
||||
|
||||
@ -40,6 +40,7 @@ reth-rlp.workspace = true
|
||||
reth-trie = { path = "../../trie", features = ["test-utils"] }
|
||||
parking_lot.workspace = true
|
||||
tempfile = "3.3"
|
||||
assert_matches.workspace = true
|
||||
|
||||
[features]
|
||||
test-utils = ["reth-rlp"]
|
||||
|
||||
@ -393,12 +393,16 @@ impl<DB: Database> PruneCheckpointReader for ProviderFactory<DB> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::ProviderFactory;
|
||||
use crate::{BlockHashReader, BlockNumReader};
|
||||
use crate::{BlockHashReader, BlockNumReader, BlockWriter, TransactionsProvider};
|
||||
use assert_matches::assert_matches;
|
||||
use reth_db::{
|
||||
test_utils::{create_test_rw_db, ERROR_TEMPDIR},
|
||||
DatabaseEnv,
|
||||
};
|
||||
use reth_primitives::{ChainSpecBuilder, H256};
|
||||
use reth_primitives::{
|
||||
hex_literal::hex, ChainSpecBuilder, PruneMode, PruneModes, SealedBlock, H256,
|
||||
};
|
||||
use reth_rlp::Decodable;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[test]
|
||||
@ -449,4 +453,36 @@ mod tests {
|
||||
provider_rw.block_hash(0).unwrap();
|
||||
provider.block_hash(0).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn insert_block_with_prune_modes() {
|
||||
let chain_spec = ChainSpecBuilder::mainnet().build();
|
||||
let db = create_test_rw_db();
|
||||
let factory = ProviderFactory::new(db, Arc::new(chain_spec));
|
||||
|
||||
let mut block_rlp = hex!("f9025ff901f7a0c86e8cc0310ae7c531c758678ddbfd16fc51c8cef8cec650b032de9869e8b94fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa050554882fbbda2c2fd93fdc466db9946ea262a67f7a76cc169e714f105ab583da00967f09ef1dfed20c0eacfaa94d5cd4002eda3242ac47eae68972d07b106d192a0e3c8b47fbfc94667ef4cceb17e5cc21e3b1eebd442cebb27f07562b33836290db90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001830f42408238108203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f862f860800a83061a8094095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba072ed817487b84ba367d15d2f039b5fc5f087d0a8882fbdf73e8cb49357e1ce30a0403d800545b8fc544f92ce8124e2255f8c3c6af93f28243a120585d4c4c6a2a3c0").as_slice();
|
||||
let block = SealedBlock::decode(&mut block_rlp).unwrap();
|
||||
|
||||
{
|
||||
let provider = factory.provider_rw().unwrap();
|
||||
assert_matches!(provider.insert_block(block.clone(), None, None), Ok(_));
|
||||
assert_matches!(provider.transaction_id(block.body[0].hash), Ok(Some(0)));
|
||||
}
|
||||
|
||||
{
|
||||
let provider = factory.provider_rw().unwrap();
|
||||
assert_matches!(
|
||||
provider.insert_block(
|
||||
block.clone(),
|
||||
None,
|
||||
Some(&PruneModes {
|
||||
transaction_lookup: Some(PruneMode::Full),
|
||||
..PruneModes::none()
|
||||
})
|
||||
),
|
||||
Ok(_)
|
||||
);
|
||||
assert_matches!(provider.transaction_id(block.body[0].hash), Ok(None));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,10 +31,10 @@ use reth_primitives::{
|
||||
stage::{StageCheckpoint, StageId},
|
||||
trie::Nibbles,
|
||||
Account, Address, Block, BlockHash, BlockHashOrNumber, BlockNumber, BlockWithSenders,
|
||||
ChainInfo, ChainSpec, Hardfork, Head, Header, PruneCheckpoint, PrunePart, Receipt, SealedBlock,
|
||||
SealedBlockWithSenders, SealedHeader, StorageEntry, TransactionMeta, TransactionSigned,
|
||||
TransactionSignedEcRecovered, TransactionSignedNoHash, TxHash, TxNumber, Withdrawal, H256,
|
||||
U256,
|
||||
ChainInfo, ChainSpec, Hardfork, Head, Header, PruneCheckpoint, PruneModes, PrunePart, Receipt,
|
||||
SealedBlock, SealedBlockWithSenders, SealedHeader, StorageEntry, TransactionMeta,
|
||||
TransactionSigned, TransactionSignedEcRecovered, TransactionSignedNoHash, TxHash, TxNumber,
|
||||
Withdrawal, H256, U256,
|
||||
};
|
||||
use reth_revm_primitives::{
|
||||
config::revm_spec,
|
||||
@ -1871,6 +1871,7 @@ impl<'this, TX: DbTxMut<'this> + DbTx<'this>> BlockWriter for DatabaseProvider<'
|
||||
&self,
|
||||
block: SealedBlock,
|
||||
senders: Option<Vec<Address>>,
|
||||
prune_modes: Option<&PruneModes>,
|
||||
) -> Result<StoredBlockBodyIndices> {
|
||||
let block_number = block.number;
|
||||
self.tx.put::<tables::CanonicalHeaders>(block.number, block.hash())?;
|
||||
@ -1922,7 +1923,14 @@ impl<'this, TX: DbTxMut<'this> + DbTx<'this>> BlockWriter for DatabaseProvider<'
|
||||
let hash = transaction.hash();
|
||||
self.tx.put::<tables::TxSenders>(next_tx_num, sender)?;
|
||||
self.tx.put::<tables::Transactions>(next_tx_num, transaction.into())?;
|
||||
self.tx.put::<tables::TxHashNumber>(hash, next_tx_num)?;
|
||||
|
||||
if prune_modes
|
||||
.and_then(|modes| modes.transaction_lookup)
|
||||
.filter(|prune_mode| prune_mode.is_full())
|
||||
.is_none()
|
||||
{
|
||||
self.tx.put::<tables::TxHashNumber>(hash, next_tx_num)?;
|
||||
}
|
||||
next_tx_num += 1;
|
||||
}
|
||||
|
||||
@ -1949,6 +1957,7 @@ impl<'this, TX: DbTxMut<'this> + DbTx<'this>> BlockWriter for DatabaseProvider<'
|
||||
&self,
|
||||
blocks: Vec<SealedBlockWithSenders>,
|
||||
state: PostState,
|
||||
prune_modes: Option<&PruneModes>,
|
||||
) -> Result<()> {
|
||||
if blocks.is_empty() {
|
||||
return Ok(())
|
||||
@ -1966,7 +1975,7 @@ impl<'this, TX: DbTxMut<'this> + DbTx<'this>> BlockWriter for DatabaseProvider<'
|
||||
// Insert the blocks
|
||||
for block in blocks {
|
||||
let (block, senders) = block.into_components();
|
||||
self.insert_block(block, Some(senders))?;
|
||||
self.insert_block(block, Some(senders), prune_modes)?;
|
||||
}
|
||||
|
||||
// Write state and changesets to the database.
|
||||
|
||||
@ -7,7 +7,8 @@ use reth_db::models::StoredBlockBodyIndices;
|
||||
use reth_interfaces::Result;
|
||||
use reth_primitives::{
|
||||
Address, Block, BlockHashOrNumber, BlockId, BlockNumber, BlockNumberOrTag, BlockWithSenders,
|
||||
ChainSpec, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, H256,
|
||||
ChainSpec, Header, PruneModes, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader,
|
||||
H256,
|
||||
};
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
@ -242,6 +243,7 @@ pub trait BlockWriter: Send + Sync {
|
||||
&self,
|
||||
block: SealedBlock,
|
||||
senders: Option<Vec<Address>>,
|
||||
prune_modes: Option<&PruneModes>,
|
||||
) -> Result<StoredBlockBodyIndices>;
|
||||
|
||||
/// Appends a batch of sealed blocks to the blockchain, including sender information, and
|
||||
@ -254,6 +256,7 @@ pub trait BlockWriter: Send + Sync {
|
||||
///
|
||||
/// - `blocks`: Vector of `SealedBlockWithSenders` instances to append.
|
||||
/// - `state`: Post-state information to update after appending.
|
||||
/// - `prune_modes`: Optional pruning configuration.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
@ -263,5 +266,6 @@ pub trait BlockWriter: Send + Sync {
|
||||
&self,
|
||||
blocks: Vec<SealedBlockWithSenders>,
|
||||
state: PostState,
|
||||
prune_modes: Option<&PruneModes>,
|
||||
) -> Result<()>;
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ paste = "1.0"
|
||||
rand = "0.8"
|
||||
proptest.workspace = true
|
||||
criterion = "0.5"
|
||||
assert_matches = "1.5"
|
||||
assert_matches.workspace = true
|
||||
|
||||
[features]
|
||||
default = ["serde"]
|
||||
|
||||
@ -48,6 +48,7 @@ async fn main() -> eyre::Result<()> {
|
||||
externals,
|
||||
canon_state_notification_sender,
|
||||
tree_config,
|
||||
None,
|
||||
)?);
|
||||
|
||||
BlockchainProvider::new(factory, tree)?
|
||||
|
||||
@ -81,6 +81,7 @@ impl Case for BlockchainTestCase {
|
||||
provider.insert_block(
|
||||
SealedBlock::new(case.genesis_block_header.clone().into(), BlockBody::default()),
|
||||
None,
|
||||
None,
|
||||
)?;
|
||||
case.pre.write_to_db(provider.tx_ref())?;
|
||||
|
||||
@ -88,7 +89,7 @@ impl Case for BlockchainTestCase {
|
||||
for block in case.blocks.iter() {
|
||||
let decoded = SealedBlock::decode(&mut block.rlp.as_ref())?;
|
||||
last_block = Some(decoded.number);
|
||||
provider.insert_block(decoded, None)?;
|
||||
provider.insert_block(decoded, None, None)?;
|
||||
}
|
||||
|
||||
// Call execution stage
|
||||
|
||||
Reference in New Issue
Block a user