mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
Introduce StatusEth69 for eth/69 status messages (#14292)
This commit is contained in:
@ -12,7 +12,7 @@
|
||||
extern crate alloc;
|
||||
|
||||
mod status;
|
||||
pub use status::{Status, StatusBuilder};
|
||||
pub use status::{Status, StatusBuilder, StatusEth69};
|
||||
|
||||
pub mod version;
|
||||
pub use version::{EthVersion, ProtocolVersion};
|
||||
|
||||
@ -213,9 +213,97 @@ impl StatusBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
/// Similar to [`Status`], but for `eth/69` version, which does not contain
|
||||
/// the `total_difficulty` field.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
|
||||
#[add_arbitrary_tests(rlp)]
|
||||
pub struct StatusEth69 {
|
||||
/// The current protocol version.
|
||||
/// Here, version is `eth/69`.
|
||||
pub version: EthVersion,
|
||||
|
||||
/// The chain id, as introduced in
|
||||
/// [EIP155](https://eips.ethereum.org/EIPS/eip-155#list-of-chain-ids).
|
||||
pub chain: Chain,
|
||||
|
||||
/// The highest difficulty block hash the peer has seen
|
||||
pub blockhash: B256,
|
||||
|
||||
/// The genesis hash of the peer's chain.
|
||||
pub genesis: B256,
|
||||
|
||||
/// The fork identifier, a [CRC32
|
||||
/// checksum](https://en.wikipedia.org/wiki/Cyclic_redundancy_check#CRC-32_algorithm) for
|
||||
/// identifying the peer's fork as defined by
|
||||
/// [EIP-2124](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2124.md).
|
||||
/// This was added in [`eth/64`](https://eips.ethereum.org/EIPS/eip-2364)
|
||||
pub forkid: ForkId,
|
||||
}
|
||||
|
||||
impl Display for StatusEth69 {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
let hexed_blockhash = hex::encode(self.blockhash);
|
||||
let hexed_genesis = hex::encode(self.genesis);
|
||||
write!(
|
||||
f,
|
||||
"Status {{ version: {}, chain: {}, blockhash: {}, genesis: {}, forkid: {:X?} }}",
|
||||
self.version, self.chain, hexed_blockhash, hexed_genesis, self.forkid
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for StatusEth69 {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
let hexed_blockhash = hex::encode(self.blockhash);
|
||||
let hexed_genesis = hex::encode(self.genesis);
|
||||
if f.alternate() {
|
||||
write!(
|
||||
f,
|
||||
"Status {{\n\tversion: {:?},\n\tchain: {:?},\n\tblockhash: {},\n\tgenesis: {},\n\tforkid: {:X?}\n}}",
|
||||
self.version,
|
||||
self.chain,
|
||||
hexed_blockhash,
|
||||
hexed_genesis,
|
||||
self.forkid
|
||||
)
|
||||
} else {
|
||||
write!(
|
||||
f,
|
||||
"Status {{ version: {:?}, chain: {:?}, blockhash: {}, genesis: {}, forkid: {:X?} }}",
|
||||
self.version,
|
||||
self.chain,
|
||||
hexed_blockhash,
|
||||
hexed_genesis,
|
||||
self.forkid
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <https://etherscan.io/block/0>
|
||||
impl Default for StatusEth69 {
|
||||
fn default() -> Self {
|
||||
Status::default().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Status> for StatusEth69 {
|
||||
fn from(status: Status) -> Self {
|
||||
Self {
|
||||
version: EthVersion::Eth69,
|
||||
chain: status.chain,
|
||||
blockhash: status.blockhash,
|
||||
genesis: status.genesis,
|
||||
forkid: status.forkid,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{EthVersion, Status};
|
||||
use crate::{EthVersion, Status, StatusEth69};
|
||||
use alloy_consensus::constants::MAINNET_GENESIS_HASH;
|
||||
use alloy_genesis::Genesis;
|
||||
use alloy_primitives::{hex, B256, U256};
|
||||
@ -263,6 +351,83 @@ mod tests {
|
||||
assert_eq!(status, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_status_to_statuseth69_conversion() {
|
||||
let status = StatusEth69 {
|
||||
version: EthVersion::Eth69,
|
||||
chain: Chain::from_named(NamedChain::Mainnet),
|
||||
blockhash: B256::from_str(
|
||||
"feb27336ca7923f8fab3bd617fcb6e75841538f71c1bcfc267d7838489d9e13d",
|
||||
)
|
||||
.unwrap(),
|
||||
genesis: MAINNET_GENESIS_HASH,
|
||||
forkid: ForkId { hash: ForkHash([0xb7, 0x15, 0x07, 0x7d]), next: 0 },
|
||||
};
|
||||
let status_converted: StatusEth69 = Status {
|
||||
version: EthVersion::Eth69,
|
||||
chain: Chain::from_named(NamedChain::Mainnet),
|
||||
total_difficulty: U256::from(36206751599115524359527u128),
|
||||
blockhash: B256::from_str(
|
||||
"feb27336ca7923f8fab3bd617fcb6e75841538f71c1bcfc267d7838489d9e13d",
|
||||
)
|
||||
.unwrap(),
|
||||
genesis: MAINNET_GENESIS_HASH,
|
||||
forkid: ForkId { hash: ForkHash([0xb7, 0x15, 0x07, 0x7d]), next: 0 },
|
||||
}
|
||||
.into();
|
||||
assert_eq!(status, status_converted);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encode_eth69_status_message() {
|
||||
let expected = hex!("f84b4501a0feb27336ca7923f8fab3bd617fcb6e75841538f71c1bcfc267d7838489d9e13da0d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3c684b715077d80");
|
||||
let status = StatusEth69 {
|
||||
version: EthVersion::Eth69,
|
||||
chain: Chain::from_named(NamedChain::Mainnet),
|
||||
blockhash: B256::from_str(
|
||||
"feb27336ca7923f8fab3bd617fcb6e75841538f71c1bcfc267d7838489d9e13d",
|
||||
)
|
||||
.unwrap(),
|
||||
genesis: MAINNET_GENESIS_HASH,
|
||||
forkid: ForkId { hash: ForkHash([0xb7, 0x15, 0x07, 0x7d]), next: 0 },
|
||||
};
|
||||
|
||||
let mut rlp_status = vec![];
|
||||
status.encode(&mut rlp_status);
|
||||
assert_eq!(rlp_status, expected);
|
||||
|
||||
let status: StatusEth69 = Status::builder()
|
||||
.chain(Chain::from_named(NamedChain::Mainnet))
|
||||
.blockhash(
|
||||
B256::from_str("feb27336ca7923f8fab3bd617fcb6e75841538f71c1bcfc267d7838489d9e13d")
|
||||
.unwrap(),
|
||||
)
|
||||
.genesis(MAINNET_GENESIS_HASH)
|
||||
.forkid(ForkId { hash: ForkHash([0xb7, 0x15, 0x07, 0x7d]), next: 0 })
|
||||
.build()
|
||||
.into();
|
||||
let mut rlp_status = vec![];
|
||||
status.encode(&mut rlp_status);
|
||||
assert_eq!(rlp_status, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_eth69_status_message() {
|
||||
let data = hex!("0xf84b4501a0feb27336ca7923f8fab3bd617fcb6e75841538f71c1bcfc267d7838489d9e13da0d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3c684b715077d80");
|
||||
let expected = StatusEth69 {
|
||||
version: EthVersion::Eth69,
|
||||
chain: Chain::from_named(NamedChain::Mainnet),
|
||||
blockhash: B256::from_str(
|
||||
"feb27336ca7923f8fab3bd617fcb6e75841538f71c1bcfc267d7838489d9e13d",
|
||||
)
|
||||
.unwrap(),
|
||||
genesis: MAINNET_GENESIS_HASH,
|
||||
forkid: ForkId { hash: ForkHash([0xb7, 0x15, 0x07, 0x7d]), next: 0 },
|
||||
};
|
||||
let status = StatusEth69::decode(&mut &data[..]).unwrap();
|
||||
assert_eq!(status, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encode_network_status_message() {
|
||||
let expected = hex!("f850423884024190faa0f8514c4680ef27700751b08f37645309ce65a449616a3ea966bf39dd935bb27ba00d21840abff46b96c84b2ac9e10e4f5cdaeb5693cb665db62a2f3b02d2d57b5bc6845d43d2fd80");
|
||||
|
||||
Reference in New Issue
Block a user