mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: Use consistent pending block in RPC/Blockchaintree (#2767)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -4681,6 +4681,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"aquamarine",
|
||||
"assert_matches",
|
||||
"linked_hash_set",
|
||||
"lru 0.10.0",
|
||||
"parking_lot 0.12.1",
|
||||
"reth-db",
|
||||
|
||||
@ -19,6 +19,7 @@ reth-interfaces = { path = "../interfaces" }
|
||||
reth-db = { path = "../storage/db" }
|
||||
reth-provider = { path = "../storage/provider" }
|
||||
|
||||
|
||||
# common
|
||||
parking_lot = { version = "0.12"}
|
||||
lru = "0.10"
|
||||
@ -26,6 +27,7 @@ tracing = { workspace = true }
|
||||
|
||||
# mics
|
||||
aquamarine = "0.3.0"
|
||||
linked_hash_set = "0.1.4"
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
use super::chain::BlockChainId;
|
||||
use crate::canonical_chain::CanonicalChain;
|
||||
use linked_hash_set::LinkedHashSet;
|
||||
use reth_primitives::{BlockHash, BlockNumHash, BlockNumber, SealedBlockWithSenders};
|
||||
use reth_provider::Chain;
|
||||
use std::collections::{btree_map, hash_map, BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
@ -21,8 +22,13 @@ pub struct BlockIndices {
|
||||
/// `number_to_block` as those are chain specific indices.
|
||||
canonical_chain: CanonicalChain,
|
||||
/// Index needed when discarding the chain, so we can remove connected chains from tree.
|
||||
///
|
||||
/// This maintains insertion order for all child blocks, so
|
||||
/// [BlockIndices::pending_block_num_hash] returns always the same block: the first child block
|
||||
/// we inserted.
|
||||
///
|
||||
/// NOTE: It contains just blocks that are forks as a key and not all blocks.
|
||||
fork_to_child: HashMap<BlockHash, HashSet<BlockHash>>,
|
||||
fork_to_child: HashMap<BlockHash, LinkedHashSet<BlockHash>>,
|
||||
/// Utility index for Block number to block hash(s).
|
||||
///
|
||||
/// This maps all blocks with same block number to their hash.
|
||||
@ -60,7 +66,7 @@ impl BlockIndices {
|
||||
}
|
||||
|
||||
/// Return fork to child indices
|
||||
pub fn fork_to_child(&self) -> &HashMap<BlockHash, HashSet<BlockHash>> {
|
||||
pub fn fork_to_child(&self) -> &HashMap<BlockHash, LinkedHashSet<BlockHash>> {
|
||||
&self.fork_to_child
|
||||
}
|
||||
|
||||
@ -69,11 +75,13 @@ impl BlockIndices {
|
||||
&self.blocks_to_chain
|
||||
}
|
||||
|
||||
/// Returns the hash and number of the pending block (the first block in the
|
||||
/// [Self::pending_blocks]) set.
|
||||
/// Returns the hash and number of the pending block.
|
||||
///
|
||||
/// It is possible that multiple child blocks for the canonical tip exist.
|
||||
/// This will always return the _first_ child we recorded for the canonical tip.
|
||||
pub(crate) fn pending_block_num_hash(&self) -> Option<BlockNumHash> {
|
||||
let canonical_tip = self.canonical_tip();
|
||||
let hash = self.fork_to_child.get(&canonical_tip.hash)?.iter().next().copied()?;
|
||||
let hash = self.fork_to_child.get(&canonical_tip.hash)?.front().copied()?;
|
||||
Some(BlockNumHash { number: canonical_tip.number + 1, hash })
|
||||
}
|
||||
|
||||
@ -132,7 +140,7 @@ impl BlockIndices {
|
||||
}
|
||||
let first = chain.first();
|
||||
// add parent block -> block index
|
||||
self.fork_to_child.entry(first.parent_hash).or_default().insert(first.hash());
|
||||
self.fork_to_child.entry(first.parent_hash).or_default().insert_if_absent(first.hash());
|
||||
}
|
||||
|
||||
/// Get the chain ID the block belongs to
|
||||
|
||||
@ -1021,10 +1021,10 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::block_buffer::BufferedBlocks;
|
||||
|
||||
use super::*;
|
||||
use crate::block_buffer::BufferedBlocks;
|
||||
use assert_matches::assert_matches;
|
||||
use linked_hash_set::LinkedHashSet;
|
||||
use reth_db::{
|
||||
mdbx::{test_utils::create_test_rw_db, Env, WriteMap},
|
||||
transaction::DbTxMut,
|
||||
@ -1129,7 +1129,11 @@ mod tests {
|
||||
assert_eq!(*tree.block_indices.blocks_to_chain(), block_to_chain);
|
||||
}
|
||||
if let Some(fork_to_child) = self.fork_to_child {
|
||||
assert_eq!(*tree.block_indices.fork_to_child(), fork_to_child);
|
||||
let mut x: HashMap<BlockHash, LinkedHashSet<BlockHash>> = HashMap::new();
|
||||
for (key, hash_set) in fork_to_child.into_iter() {
|
||||
x.insert(key, hash_set.into_iter().collect());
|
||||
}
|
||||
assert_eq!(*tree.block_indices.fork_to_child(), x);
|
||||
}
|
||||
if let Some(pending_blocks) = self.pending_blocks {
|
||||
let (num, hashes) = tree.block_indices.pending_blocks();
|
||||
|
||||
Reference in New Issue
Block a user