From 4d4d4b58688e1bfa5d3c2de7cc31673c40fb0421 Mon Sep 17 00:00:00 2001 From: Ash Manning Date: Mon, 8 Jul 2024 18:15:46 +0800 Subject: [PATCH] add network option, fix bug when submitting blocks, bump version --- Cargo.lock | 36 +++++++++++++++++++++++++----- Cargo.toml | 2 +- app/Cargo.toml | 2 +- app/app.rs | 1 + app/cli.rs | 7 +++++- lib/Cargo.toml | 3 +++ lib/archive.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/net/mod.rs | 32 ++++++++++++++++++-------- lib/node/mod.rs | 8 ++++--- lib/types/mod.rs | 8 +++++++ 10 files changed, 136 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd9229e..97662fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3779,7 +3779,7 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "plain_bitnames" -version = "0.8.1" +version = "0.8.2" dependencies = [ "addr", "anyhow", @@ -3792,6 +3792,7 @@ dependencies = [ "bs58", "byteorder", "bytes", + "clap", "ed25519-dalek", "ed25519-dalek-bip32", "educe", @@ -3813,6 +3814,7 @@ dependencies = [ "serde_json", "serde_with", "sha256", + "strum 0.26.3", "thiserror", "tiny-bip39", "tokio", @@ -3825,7 +3827,7 @@ dependencies = [ [[package]] name = "plain_bitnames_app" -version = "0.8.1" +version = "0.8.2" dependencies = [ "anyhow", "async_zmq", @@ -3853,7 +3855,7 @@ dependencies = [ "poll-promise", "serde", "shlex", - "strum", + "strum 0.25.0", "tempfile", "test-log", "thiserror", @@ -3868,7 +3870,7 @@ dependencies = [ [[package]] name = "plain_bitnames_app_cli" -version = "0.8.1" +version = "0.8.2" dependencies = [ "anyhow", "bip300301", @@ -3883,7 +3885,7 @@ dependencies = [ [[package]] name = "plain_bitnames_app_rpc_api" -version = "0.8.1" +version = "0.8.2" dependencies = [ "bip300301", "jsonrpsee", @@ -4871,7 +4873,16 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" dependencies = [ - "strum_macros", + "strum_macros 0.25.3", +] + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros 0.26.4", ] [[package]] @@ -4887,6 +4898,19 @@ dependencies = [ "syn 2.0.68", ] +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.68", +] + [[package]] name = "subtle" version = "2.6.0" diff --git a/Cargo.toml b/Cargo.toml index 2c786e4..e2a5d90 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ members = [ [workspace.package] authors = [ "Ash Manning " ] edition = "2021" -version = "0.8.1" +version = "0.8.2" [workspace.dependencies.bip300301] git = "https://github.com/Ash-L2L/bip300301.git" diff --git a/app/Cargo.toml b/app/Cargo.toml index 9195b7e..3162319 100644 --- a/app/Cargo.toml +++ b/app/Cargo.toml @@ -30,7 +30,7 @@ itertools = "0.11.0" include_path = "0.1.1" jsonrpsee = { version = "0.20.0", features = ["server"] } parking_lot = "0.12.1" -plain_bitnames = { path = "../lib" } +plain_bitnames = { path = "../lib", features = ["clap"] } plain_bitnames_app_cli = { path = "../cli" } plain_bitnames_app_rpc_api = { path = "../rpc-api" } poll-promise = { version = "0.3.0", features = ["tokio"] } diff --git a/app/app.rs b/app/app.rs index 50c43fb..09c6c02 100644 --- a/app/app.rs +++ b/app/app.rs @@ -123,6 +123,7 @@ impl App { config.net_addr, &config.datadir, config.main_addr, + config.network, &config.main_password, &config.main_user, local_pool.clone(), diff --git a/app/cli.rs b/app/cli.rs index 0b6d30e..8fb5099 100644 --- a/app/cli.rs +++ b/app/cli.rs @@ -6,7 +6,7 @@ use std::{ }; use clap::{Arg, Parser}; -use plain_bitnames::node::THIS_SIDECHAIN; +use plain_bitnames::{node::THIS_SIDECHAIN, types::Network}; const fn ipv4_socket_addr(ipv4_octets: [u8; 4], port: u16) -> SocketAddr { let [a, b, c, d] = ipv4_octets; @@ -131,6 +131,9 @@ pub(super) struct Cli { /// Socket address to use for P2P networking #[arg(default_value_t = DEFAULT_NET_ADDR, long, short)] net_addr: SocketAddr, + /// Set the network. Setting this may affect other defaults. + #[arg(default_value_t, long, value_enum)] + network: Network, /// Socket address to host the RPC server #[arg(default_value_t = DEFAULT_RPC_ADDR, long, short)] rpc_addr: SocketAddr, @@ -158,6 +161,7 @@ pub struct Config { pub mnemonic_seed_phrase_path: Option, pub main_user: String, pub net_addr: SocketAddr, + pub network: Network, pub rpc_addr: SocketAddr, #[cfg(all(not(target_os = "windows"), feature = "zmq"))] pub zmq_addr: SocketAddr, @@ -191,6 +195,7 @@ impl Cli { main_user: self.user_main, mnemonic_seed_phrase_path: self.mnemonic_seed_phrase_path, net_addr: self.net_addr, + network: self.network, rpc_addr: self.rpc_addr, #[cfg(all(not(target_os = "windows"), feature = "zmq"))] zmq_addr: self.zmq_addr, diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 3a33662..632e00c 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -15,6 +15,7 @@ borsh = { version = "1.3.1", features = ["derive"] } bs58 = { version = "0.5.0", features = ["check"] } byteorder = "1.4.3" bytes = "1.4.0" +clap = { version = "4.5.4", features = ["derive"], optional = true } ed25519-dalek = { version = "2.1.1", features = ["batch", "serde"] } ed25519-dalek-bip32 = "0.3.0" educe = { version = "0.4.23", features = ["Hash"] } @@ -36,6 +37,7 @@ serde = { version = "1.0.179", features = ["derive"] } serde_json = "1.0.113" serde_with = { version = "3.4.0", default-features = false } sha256 = "1.2.2" +strum = { version = "0.26.3", features = ["derive"], optional = true} thiserror = "1.0.44" tiny-bip39 = "1.0.0" tokio = { version = "1.29.1", features = ["rt-multi-thread", "sync"] } @@ -51,6 +53,7 @@ rev = "61748742c2a91be4be24a227d109fd93492f7484" optional = true [features] +clap = ["dep:clap", "dep:strum"] zmq = ["dep:async_zmq"] [lib] diff --git a/lib/archive.rs b/lib/archive.rs index c9b150a..e2c42eb 100644 --- a/lib/archive.rs +++ b/lib/archive.rs @@ -723,6 +723,64 @@ impl Archive { &block_hash, &exponential_ancestors, )?; + // Populate BMM verifications + { + let mut bmm_results = self.get_bmm_results(rwtxn, block_hash)?; + let parent_bmm_results = + self.get_bmm_results(rwtxn, header.prev_side_hash)?; + let main_blocks = + self.get_main_successors(rwtxn, header.prev_main_hash)?; + for main_block in main_blocks { + let Some(commitment) = + self.get_main_bmm_commitment(rwtxn, main_block)? + else { + tracing::trace!(%block_hash, "Failed BMM @ {main_block}: missing commitment"); + bmm_results.insert(main_block, BmmResult::Failed); + continue; + }; + if commitment != block_hash { + tracing::trace!(%block_hash, "Failed BMM @ {main_block}: commitment to other block ({commitment})"); + bmm_results.insert(main_block, BmmResult::Failed); + continue; + } + let main_header = self.get_main_header(rwtxn, main_block)?; + if header.prev_main_hash != main_header.prev_blockhash { + tracing::trace!(%block_hash, "Failed BMM @ {main_block}: should be impossible?"); + bmm_results.insert(main_block, BmmResult::Failed); + continue; + } + if header.prev_side_hash == BlockHash::default() { + tracing::trace!(%block_hash, "Verified BMM @ {main_block}: no parent"); + bmm_results.insert(main_block, BmmResult::Verified); + continue; + } + // Check if there is a valid BMM commitment to the parent in the + // main ancestry + let main_ancestry_contains_valid_bmm_commitment_to_parent = + parent_bmm_results + .iter() + .map(Ok) + .transpose_into_fallible() + .any(|(bmm_block, bmm_result)| { + let parent_verified = *bmm_result + == BmmResult::Verified + && self.is_main_descendant( + rwtxn, *bmm_block, main_block, + )?; + Result::::Ok(parent_verified) + })?; + if main_ancestry_contains_valid_bmm_commitment_to_parent { + tracing::trace!(%block_hash, "Verified BMM @ {main_block}: verified parent"); + bmm_results.insert(main_block, BmmResult::Verified); + continue; + } else { + tracing::trace!(%block_hash, "Failed BMM @ {main_block}: no valid BMM commitment to parent in main ancestry"); + bmm_results.insert(main_block, BmmResult::Failed); + continue; + } + } + self.bmm_results.put(rwtxn, &block_hash, &bmm_results)?; + } Ok(()) } diff --git a/lib/net/mod.rs b/lib/net/mod.rs index c0cb801..d670b19 100644 --- a/lib/net/mod.rs +++ b/lib/net/mod.rs @@ -15,8 +15,10 @@ use quinn::{ClientConfig, Endpoint, ServerConfig}; use tokio_stream::StreamNotifyClose; use crate::{ - archive::Archive, node::THIS_SIDECHAIN, state::State, - types::AuthorizedTransaction, + archive::Archive, + node::THIS_SIDECHAIN, + state::State, + types::{AuthorizedTransaction, Network}, }; mod peer; @@ -78,6 +80,21 @@ pub fn make_client_endpoint(bind_addr: SocketAddr) -> Result { pub type PeerInfoRx = mpsc::UnboundedReceiver<(SocketAddr, Option)>; +const SIGNET_SEED_NODE_ADDRS: &[SocketAddr] = { + const SEED_NODE_ADDR: SocketAddr = SocketAddr::new( + std::net::IpAddr::V4(std::net::Ipv4Addr::new(172, 105, 148, 135)), + 4000 + THIS_SIDECHAIN as u16, + ); + &[SEED_NODE_ADDR] +}; + +const fn seed_node_addrs(network: Network) -> &'static [SocketAddr] { + match network { + Network::Signet => SIGNET_SEED_NODE_ADDRS, + Network::Regtest => &[], + } +} + // State. // Archive. @@ -165,6 +182,7 @@ impl Net { pub fn new( env: &heed::Env, archive: Archive, + network: Network, state: State, bind_addr: SocketAddr, ) -> Result<(Self, PeerInfoRx), Error> { @@ -178,13 +196,9 @@ impl Net { None => { let known_peers = env.create_database(&mut rwtxn, Some("known_peers"))?; - const SEED_NODE_ADDR: SocketAddr = SocketAddr::new( - std::net::IpAddr::V4(std::net::Ipv4Addr::new( - 172, 105, 148, 135, - )), - 4000 + THIS_SIDECHAIN as u16, - ); - known_peers.put(&mut rwtxn, &SEED_NODE_ADDR, &())?; + for seed_node_addr in seed_node_addrs(network) { + known_peers.put(&mut rwtxn, seed_node_addr, &())?; + } known_peers } }; diff --git a/lib/node/mod.rs b/lib/node/mod.rs index 3ed9b09..f29a051 100644 --- a/lib/node/mod.rs +++ b/lib/node/mod.rs @@ -20,8 +20,8 @@ use crate::{ types::{ Address, Authorized, AuthorizedTransaction, BitName, BitNameData, Block, BlockHash, BmmResult, Body, FilledOutput, FilledTransaction, - GetValue, Header, OutPoint, SpentOutput, Tip, Transaction, TxIn, Txid, - WithdrawalBundle, + GetValue, Header, Network, OutPoint, SpentOutput, Tip, Transaction, + TxIn, Txid, WithdrawalBundle, }, util::Watchable, }; @@ -152,10 +152,12 @@ pub struct Node { } impl Node { + #[allow(clippy::too_many_arguments)] pub fn new( bind_addr: SocketAddr, datadir: &Path, main_addr: SocketAddr, + network: Network, password: &str, user: &str, local_pool: LocalPoolHandle, @@ -194,7 +196,7 @@ impl Node { drivechain.clone(), ); let (net, peer_info_rx) = - Net::new(&env, archive.clone(), state.clone(), bind_addr)?; + Net::new(&env, archive.clone(), network, state.clone(), bind_addr)?; let net_task = NetTaskHandle::new( local_pool.clone(), diff --git a/lib/types/mod.rs b/lib/types/mod.rs index c39d6f3..ca9ccd3 100644 --- a/lib/types/mod.rs +++ b/lib/types/mod.rs @@ -519,3 +519,11 @@ impl Default for Tip { } } } + +#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)] +#[cfg_attr(feature = "clap", derive(clap::ValueEnum, strum::Display))] +pub enum Network { + #[default] + Signet, + Regtest, +}