mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-29 00:58:11 -05:00
feat(net): add ForkTransition type (#542)
This commit is contained in:
@@ -470,7 +470,11 @@ where
|
||||
let _ = tx.send(self.fetch_client());
|
||||
}
|
||||
NetworkHandleMessage::StatusUpdate { height, hash, total_difficulty } => {
|
||||
self.swarm.sessions_mut().on_status_update(height, hash, total_difficulty);
|
||||
if let Some(transition) =
|
||||
self.swarm.sessions_mut().on_status_update(height, hash, total_difficulty)
|
||||
{
|
||||
self.swarm.state_mut().update_fork_id(transition.current);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ use reth_eth_wire::{
|
||||
error::EthStreamError,
|
||||
DisconnectReason, HelloMessage, Status, UnauthedEthStream, UnauthedP2PStream,
|
||||
};
|
||||
use reth_primitives::{ForkFilter, PeerId, H256, U256};
|
||||
use reth_primitives::{ForkFilter, ForkTransition, PeerId, H256, U256};
|
||||
use secp256k1::SecretKey;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
@@ -146,11 +146,19 @@ impl SessionManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// Invoked on a received status update
|
||||
pub(crate) fn on_status_update(&mut self, height: u64, hash: H256, total_difficulty: U256) {
|
||||
/// Invoked on a received status update.
|
||||
///
|
||||
/// If the updated activated another fork, this will return a [`ForkTransition`] and updates the
|
||||
/// active [`ForkId`](reth_primitives::ForkId). See also [`ForkFilter::set_head`].
|
||||
pub(crate) fn on_status_update(
|
||||
&mut self,
|
||||
height: u64,
|
||||
hash: H256,
|
||||
total_difficulty: U256,
|
||||
) -> Option<ForkTransition> {
|
||||
self.status.blockhash = hash;
|
||||
self.status.total_difficulty = total_difficulty;
|
||||
self.fork_filter.set_head(height);
|
||||
self.fork_filter.set_head(height)
|
||||
}
|
||||
|
||||
/// An incoming TCP connection was received. This starts the authentication process to turn this
|
||||
|
||||
@@ -216,10 +216,9 @@ where
|
||||
self.state_fetcher.update_peer_block(peer_id, hash, number);
|
||||
}
|
||||
|
||||
/// Invoked on a [`ForkId`] update
|
||||
#[allow(unused)]
|
||||
pub(crate) fn update_fork_id(&mut self, _fork_id: ForkId) {
|
||||
todo!()
|
||||
/// Invoked when a new [`ForkId`] is activated.
|
||||
pub(crate) fn update_fork_id(&mut self, fork_id: ForkId) {
|
||||
self.discovery.update_fork_id(fork_id)
|
||||
}
|
||||
|
||||
/// Invoked after a `NewBlock` message was received by the peer.
|
||||
|
||||
@@ -141,7 +141,7 @@ impl ForkFilter {
|
||||
Self { forks, head, cache }
|
||||
}
|
||||
|
||||
fn set_head_priv(&mut self, head: BlockNumber) -> bool {
|
||||
fn set_head_priv(&mut self, head: BlockNumber) -> Option<ForkTransition> {
|
||||
let recompute_cache = {
|
||||
if head < self.cache.epoch_start {
|
||||
true
|
||||
@@ -152,17 +152,27 @@ impl ForkFilter {
|
||||
}
|
||||
};
|
||||
|
||||
let mut transition = None;
|
||||
|
||||
// recompute the cache
|
||||
if recompute_cache {
|
||||
let past = self.current();
|
||||
|
||||
self.cache = Cache::compute_cache(&self.forks, head);
|
||||
|
||||
transition = Some(ForkTransition { current: self.current(), past })
|
||||
}
|
||||
|
||||
self.head = head;
|
||||
|
||||
recompute_cache
|
||||
transition
|
||||
}
|
||||
|
||||
/// Set the current head
|
||||
pub fn set_head(&mut self, head: BlockNumber) {
|
||||
self.set_head_priv(head);
|
||||
/// Set the current head.
|
||||
///
|
||||
/// If the update updates the current [`ForkId`] it returns a [`ForkTransition`]
|
||||
pub fn set_head(&mut self, head: BlockNumber) -> Option<ForkTransition> {
|
||||
self.set_head_priv(head)
|
||||
}
|
||||
|
||||
/// Return current fork id
|
||||
@@ -232,6 +242,17 @@ impl ForkFilter {
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a transition from one fork to another
|
||||
///
|
||||
/// See also [`ForkFilter::set_head`]
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct ForkTransition {
|
||||
/// The new, active ForkId
|
||||
pub current: ForkId,
|
||||
/// The previously active ForkId before the transition
|
||||
pub past: ForkId,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
struct Cache {
|
||||
// An epoch is a period between forks.
|
||||
@@ -463,28 +484,34 @@ mod tests {
|
||||
|
||||
let mut fork_filter = ForkFilter::new(0, GENESIS_HASH, vec![b1, b2]);
|
||||
|
||||
assert!(!fork_filter.set_head_priv(0));
|
||||
assert!(fork_filter.set_head_priv(0).is_none());
|
||||
assert_eq!(fork_filter.current(), h0);
|
||||
|
||||
assert!(!fork_filter.set_head_priv(1));
|
||||
assert!(fork_filter.set_head_priv(1).is_none());
|
||||
assert_eq!(fork_filter.current(), h0);
|
||||
|
||||
assert!(fork_filter.set_head_priv(b1 + 1));
|
||||
assert_eq!(
|
||||
fork_filter.set_head_priv(b1 + 1).unwrap(),
|
||||
ForkTransition { current: h1, past: h0 }
|
||||
);
|
||||
assert_eq!(fork_filter.current(), h1);
|
||||
|
||||
assert!(!fork_filter.set_head_priv(b1));
|
||||
assert!(fork_filter.set_head_priv(b1).is_none());
|
||||
assert_eq!(fork_filter.current(), h1);
|
||||
|
||||
assert!(fork_filter.set_head_priv(b1 - 1));
|
||||
assert_eq!(
|
||||
fork_filter.set_head_priv(b1 - 1).unwrap(),
|
||||
ForkTransition { current: h0, past: h1 }
|
||||
);
|
||||
assert_eq!(fork_filter.current(), h0);
|
||||
|
||||
assert!(fork_filter.set_head_priv(b1));
|
||||
assert!(fork_filter.set_head_priv(b1).is_some());
|
||||
assert_eq!(fork_filter.current(), h1);
|
||||
|
||||
assert!(!fork_filter.set_head_priv(b2 - 1));
|
||||
assert!(fork_filter.set_head_priv(b2 - 1).is_none());
|
||||
assert_eq!(fork_filter.current(), h1);
|
||||
|
||||
assert!(fork_filter.set_head_priv(b2));
|
||||
assert!(fork_filter.set_head_priv(b2).is_some());
|
||||
assert_eq!(fork_filter.current(), h2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ pub use block::{Block, BlockHashOrNumber, BlockLocked};
|
||||
pub use chain::Chain;
|
||||
pub use constants::{EMPTY_OMMER_ROOT, KECCAK_EMPTY, MAINNET_GENESIS};
|
||||
pub use ethbloom::Bloom;
|
||||
pub use forkid::{ForkFilter, ForkHash, ForkId, ValidationError};
|
||||
pub use forkid::{ForkFilter, ForkHash, ForkId, ForkTransition, ValidationError};
|
||||
pub use hardfork::Hardfork;
|
||||
pub use header::{Header, HeadersDirection, SealedHeader};
|
||||
pub use hex_bytes::Bytes;
|
||||
|
||||
Reference in New Issue
Block a user