Skip to content

Commit

Permalink
feat: bsc p2p network (#8061)
Browse files Browse the repository at this point in the history
Co-authored-by: Matthias Seitz <[email protected]>
  • Loading branch information
Quertyy and mattsse authored May 22, 2024
1 parent 5eb41d4 commit cd039d3
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 1 deletion.
15 changes: 15 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ members = [
"examples/custom-inspector/",
"examples/exex/*",
"examples/db-access",
"examples/bsc-p2p",
"testing/ef-tests/",
"testing/testing-utils",
]
Expand Down
9 changes: 9 additions & 0 deletions crates/ethereum-forks/src/forkid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,15 @@ impl ForkFilter {
self.cache.fork_id
}

/// Manually set the current fork id.
///
/// Caution: this disregards all configured fork filters and is reset on the next head update.
/// This is useful for testing or to connect to networks over p2p where only the latest forkid
/// is known.
pub fn set_current_fork_id(&mut self, fork_id: ForkId) {
self.cache.fork_id = fork_id;
}

/// Check whether the provided `ForkId` is compatible based on the validation rules in
/// `EIP-2124`.
///
Expand Down
3 changes: 2 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ to make a PR!
| Example | Description |
| --------------------------- | ----------------------------------------------------------------- |
| [Manual P2P](./manual-p2p) | Illustrates how to connect and communicate with a peer |
| [Polygon P2P](./manual-p2p) | Illustrates how to connect and communicate with a peer on Polygon |
| [Polygon P2P](./polygon-p2p) | Illustrates how to connect and communicate with a peer on Polygon |
| [BSC P2P](./bsc-p2p) | Illustrates how to connect and communicate with a peer on Binance Smart Chain |

## Misc

Expand Down
22 changes: 22 additions & 0 deletions examples/bsc-p2p/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "bsc-p2p"
version = "0.0.0"
publish = false
edition.workspace = true
license.workspace = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
reth-discv4 = { workspace = true, features = ["test-utils"] }
reth-network = { workspace = true, features = ["test-utils"] }
reth-network-api.workspace = true
reth-primitives.workspace = true
reth-tracing.workspace = true

secp256k1 = { workspace = true, features = ["global-context", "rand-std", "recovery"] }

tokio.workspace = true
tokio-stream.workspace = true

serde_json.workspace = true
38 changes: 38 additions & 0 deletions examples/bsc-p2p/src/chainspec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use reth_primitives::{
b256, BaseFeeParams, Chain, ChainSpec, ForkCondition, Hardfork, NodeRecord, B256,
};

use std::{collections::BTreeMap, sync::Arc};

pub const SHANGHAI_TIME: u64 = 1705996800;

pub(crate) fn bsc_chain_spec() -> Arc<ChainSpec> {
const GENESIS: B256 = b256!("0d21840abff46b96c84b2ac9e10e4f5cdaeb5693cb665db62a2f3b02d2d57b5b");

ChainSpec {
chain: Chain::from_id(56),
genesis: serde_json::from_str(include_str!("./genesis.json")).expect("deserialize genesis"),
genesis_hash: Some(GENESIS),
paris_block_and_final_difficulty: None,
hardforks: BTreeMap::from([(Hardfork::Shanghai, ForkCondition::Timestamp(SHANGHAI_TIME))]),
deposit_contract: None,
base_fee_params: reth_primitives::BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()),
prune_delete_limit: 0,
}
.into()
}

/// BSC mainnet bootnodes <https://github.com/bnb-chain/bsc/blob/master/params/bootnodes.go#L23>
static BOOTNODES: [&str; 7] = [
"enode://ba88d1a8a5e849bec0eb7df9eabf059f8edeae9a9eb1dcf51b7768276d78b10d4ceecf0cde2ef191ced02f66346d96a36ca9da7d73542757d9677af8da3bad3f@54.198.97.197:30311",
"enode://433c8bfdf53a3e2268ccb1b829e47f629793291cbddf0c76ae626da802f90532251fc558e2e0d10d6725e759088439bf1cd4714716b03a259a35d4b2e4acfa7f@52.69.102.73:30311",
"enode://571bee8fb902a625942f10a770ccf727ae2ba1bab2a2b64e121594a99c9437317f6166a395670a00b7d93647eacafe598b6bbcef15b40b6d1a10243865a3e80f@35.73.84.120:30311",
"enode://fac42fb0ba082b7d1eebded216db42161163d42e4f52c9e47716946d64468a62da4ba0b1cac0df5e8bf1e5284861d757339751c33d51dfef318be5168803d0b5@18.203.152.54:30311",
"enode://3063d1c9e1b824cfbb7c7b6abafa34faec6bb4e7e06941d218d760acdd7963b274278c5c3e63914bd6d1b58504c59ec5522c56f883baceb8538674b92da48a96@34.250.32.100:30311",
"enode://ad78c64a4ade83692488aa42e4c94084516e555d3f340d9802c2bf106a3df8868bc46eae083d2de4018f40e8d9a9952c32a0943cd68855a9bc9fd07aac982a6d@34.204.214.24:30311",
"enode://5db798deb67df75d073f8e2953dad283148133acb520625ea804c9c4ad09a35f13592a762d8f89056248f3889f6dcc33490c145774ea4ff2966982294909b37a@107.20.191.97:30311",
];

pub(crate) fn boot_nodes() -> Vec<NodeRecord> {
BOOTNODES[..].iter().map(|s| s.parse().unwrap()).collect()
}
82 changes: 82 additions & 0 deletions examples/bsc-p2p/src/genesis.json

Large diffs are not rendered by default.

91 changes: 91 additions & 0 deletions examples/bsc-p2p/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//! Example for how hook into the bsc p2p network
//!
//! Run with
//!
//! ```not_rust
//! cargo run -p bsc-p2p
//! ```
//!
//! This launch the regular reth node overriding the engine api payload builder with our custom.
//!
//! Credits to: <https://blog.merkle.io/blog/fastest-transaction-network-eth-polygon-bsc>
#![cfg_attr(not(test), warn(unused_crate_dependencies))]

use chainspec::{boot_nodes, bsc_chain_spec};
use reth_discv4::Discv4ConfigBuilder;
use reth_network::{NetworkConfig, NetworkEvent, NetworkEvents, NetworkManager};
use reth_network_api::PeersInfo;
use reth_primitives::{ForkHash, ForkId};
use reth_tracing::{
tracing::info, tracing_subscriber::filter::LevelFilter, LayerInfo, LogFormat, RethTracer,
Tracer,
};
use secp256k1::{rand, SecretKey};
use std::{
net::{Ipv4Addr, SocketAddr},
time::Duration,
};
use tokio_stream::StreamExt;

pub mod chainspec;

#[tokio::main]
async fn main() {
// The ECDSA private key used to create our enode identifier.
let secret_key = SecretKey::new(&mut rand::thread_rng());

let _ = RethTracer::new()
.with_stdout(LayerInfo::new(
LogFormat::Terminal,
LevelFilter::INFO.to_string(),
"".to_string(),
Some("always".to_string()),
))
.init();

// The local address we want to bind to
let local_addr = SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 30303);

// The network configuration
let mut net_cfg = NetworkConfig::builder(secret_key)
.chain_spec(bsc_chain_spec())
.listener_addr(local_addr)
.build_with_noop_provider()
.set_discovery_v4(
Discv4ConfigBuilder::default()
.add_boot_nodes(boot_nodes())
// Set Discv4 lookup interval to 1 second
.lookup_interval(Duration::from_secs(1))
.build(),
);

// latest BSC forkId, we need to override this to allow connections from BSC nodes
let fork_id = ForkId { hash: ForkHash([0x07, 0xb5, 0x43, 0x28]), next: 0 };
net_cfg.fork_filter.set_current_fork_id(fork_id);
let net_manager = NetworkManager::new(net_cfg).await.unwrap();

// The network handle is our entrypoint into the network.
let net_handle = net_manager.handle().clone();
let mut events = net_handle.event_listener();

// NetworkManager is a long running task, let's spawn it
tokio::spawn(net_manager);
info!("Looking for BSC peers...");

while let Some(evt) = events.next().await {
// For the sake of the example we only print the session established event
// with the chain specific details
match evt {
NetworkEvent::SessionEstablished { status, client_version, peer_id, .. } => {
info!(peers=%net_handle.num_connected_peers() , %peer_id, chain = %status.chain, ?client_version, "Session established with a new peer.");
}
NetworkEvent::SessionClosed { peer_id, reason } => {
info!(peers=%net_handle.num_connected_peers() , %peer_id, ?reason, "Session closed.");
}

_ => {}
}
}
// We will be disconnected from peers since we are not able to answer to network requests
}

0 comments on commit cd039d3

Please sign in to comment.