Skip to content

Commit

Permalink
Merge pull request #191 from rustaceanrob/testnet4-11-1
Browse files Browse the repository at this point in the history
Testnet4 11 1
  • Loading branch information
rustaceanrob authored Nov 1, 2024
2 parents ec50b74 + 4412c7e commit bed26e6
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 8 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ path = "src/lib.rs"
name = "signet"
path = "example/signet.rs"

[[example]]
name = "testnet"
path = "example/testnet4.rs"

[[example]]
name = "rescan"
path = "example/rescan.rs"
Expand Down
79 changes: 79 additions & 0 deletions example/testnet4.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use kyoto::core::messages::NodeMessage;
use kyoto::{chain::checkpoints::HeaderCheckpoint, core::builder::NodeBuilder};
use kyoto::{Address, Network, TrustedPeer};
use std::collections::HashSet;
use std::{net::Ipv4Addr, str::FromStr};

const NETWORK: Network = Network::Testnet4;
const RECOVERY_HEIGHT: u32 = 0;

// THE TESTNET4 DOES NOT CURRENTLY HAVE PEERS THAT SERVE COMPACT BLOCK FILTERS

#[tokio::main]
async fn main() {
// Add third-party logging
let subscriber = tracing_subscriber::FmtSubscriber::new();
tracing::subscriber::set_global_default(subscriber).unwrap();
// Use a predefined checkpoint
let checkpoint = HeaderCheckpoint::closest_checkpoint_below_height(RECOVERY_HEIGHT, NETWORK);
// Add Bitcoin scripts to scan the blockchain for
let address = Address::from_str("tb1qkqkt3ra8d44lt90t9thgy3lgucsjrtywwgq8yp")
.unwrap()
.require_network(NETWORK)
.unwrap()
.into();
let mut addresses = HashSet::new();
addresses.insert(address);
// Add preferred peers to connect to
let peer = TrustedPeer::from_ip(Ipv4Addr::new(18, 189, 156, 102));
// Create a new node builder
let builder = NodeBuilder::new(NETWORK);
// Add node preferences and build the node/client
let (node, client) = builder
// Add the peers
.add_peer(peer)
// The Bitcoin scripts to monitor
.add_scripts(addresses)
// Only scan blocks strictly after an anchor checkpoint
.anchor_checkpoint(checkpoint)
// The number of connections we would like to maintain
.num_required_peers(1)
// Create the node and client
.build_node()
.unwrap();

// Run the node on a new task
tokio::task::spawn(async move { node.run().await });

// Split the client into components that send messages and listen to messages.
// With this construction, different parts of the program can take ownership of
// specific tasks.
let (sender, mut receiver) = client.split();
// Continually listen for events until the node is synced to its peers.
loop {
if let Ok(message) = receiver.recv().await {
match message {
NodeMessage::Dialog(d) => tracing::info!("{d}"),
NodeMessage::Warning(e) => tracing::warn!("{e}"),
NodeMessage::Block(b) => drop(b),
NodeMessage::BlocksDisconnected(r) => {
for dc in r {
let warning = format!("Block disconnected {}", dc.height);
tracing::warn!(warning);
}
}
NodeMessage::Synced(update) => {
tracing::info!("Synced chain up to block {}", update.tip.height);
tracing::info!("Chain tip: {}", update.tip.hash);
break;
}
NodeMessage::ConnectionsMet => {
tracing::info!("Connected to all required peers");
}
_ => (),
}
}
}
let _ = sender.shutdown().await;
tracing::info!("Shutting down");
}
3 changes: 2 additions & 1 deletion src/chain/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const REORG_LOOKBACK: u32 = 7;
const MAX_HEADER_SIZE: usize = 20_000;
const FILTER_BASIC: u8 = 0x00;

#[allow(unused)]
#[derive(Debug)]
pub(crate) struct Chain<H: HeaderStore> {
header_chain: HeaderChain,
Expand Down Expand Up @@ -358,7 +359,7 @@ impl<H: HeaderStore> Chain<H> {
}

// All the headers connect with each other and is the difficulty adjustment not absurd
if !header_batch.connected_with_valid_bits(&self.params).await {
if !header_batch.connected().await {
return Err(HeaderSyncError::HeadersNotConnected);
}

Expand Down
36 changes: 36 additions & 0 deletions src/chain/checkpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,34 @@ pub const SIGNET_HEADER_CP: &[(Height, &str)] = &[
),
];

/// Known block hashes for Testnet4.
pub const TESTNET4_HEADER_CP: &[(Height, &str)] = &[
(
0,
"00000000da84f2bafbbc53dee25a72ae507ff4914b867c565be350b0da8bf043",
),
(
10_000,
"000000000037079ff4c37eed57d00eb9ddfde8737b559ffa4101b11e76c97466",
),
(
20_000,
"0000000000003a28386161143be8e7cdc3d857021986c4d0ee140d852a155b59",
),
(
30_000,
"000000000000000095a56b41da7618b40949a3aef84059732ff1b045cb44fbbf",
),
(
40_000,
"000000000000000c1a1fad82b0e133f4772802b6dff7a95990580ae2e15c634f",
),
(
50_000,
"00000000e2c8c94ba126169a88997233f07a9769e2b009fb10cad0e893eff2cb",
),
];

/// Known block hashes on the Bitcoin blockchain.
pub const MAINNET_HEADER_CP: &[(Height, &str)] = &[
(
Expand Down Expand Up @@ -481,6 +509,13 @@ impl HeaderCheckpoint {
})
.collect(),
Network::Testnet => panic!("unimplemented network"),
Network::Testnet4 => TESTNET4_HEADER_CP
.iter()
.copied()
.map(|(height, hash)| {
HeaderCheckpoint::new(height, BlockHash::from_str(hash).unwrap())
})
.collect(),
Network::Signet => SIGNET_HEADER_CP
.iter()
.copied()
Expand Down Expand Up @@ -521,6 +556,7 @@ impl HeaderCheckpoints {
let cp_list = match network {
Network::Bitcoin => MAINNET_HEADER_CP.to_vec(),
Network::Testnet => panic!("unimplemented network"),
Network::Testnet4 => TESTNET4_HEADER_CP.to_vec(),
Network::Signet => SIGNET_HEADER_CP.to_vec(),
Network::Regtest => REGTEST_HEADER_CP.to_vec(),
_ => unreachable!(),
Expand Down
10 changes: 3 additions & 7 deletions src/chain/header_batch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bitcoin::{block::Header, params::Params, Target};
use bitcoin::block::Header;

use crate::{
impl_sourceless_error,
Expand All @@ -20,15 +20,11 @@ impl HeadersBatch {
}

// Are they all logically connected?
pub(crate) async fn connected_with_valid_bits(&self, params: &Params) -> bool {
pub(crate) async fn connected(&self) -> bool {
self.batch
.iter()
.zip(self.batch.iter().skip(1))
.all(|(first, second)| {
let transition = Target::from_compact(first.bits).max_transition_threshold(params);
first.block_hash().eq(&second.prev_blockhash)
&& Target::from_compact(second.bits).le(&transition)
})
.all(|(first, second)| first.block_hash().eq(&second.prev_blockhash))
}

// Are all the blocks of sufficient work and meet their own target?
Expand Down
1 change: 1 addition & 0 deletions src/network/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ impl<'a> Dns<'a> {
Network::Testnet => TESTNET_SEEDS.to_vec(),
Network::Signet => SIGNET_SEEDS.to_vec(),
Network::Regtest => Vec::with_capacity(0),
Network::Testnet4 => Vec::with_capacity(0),
_ => unreachable!(),
};
Self { seeds }
Expand Down
2 changes: 2 additions & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ pub(crate) fn params_from_network(network: &Network) -> Params {
match network {
Network::Bitcoin => Params::new(*network),
Network::Testnet => panic!("unimplemented network"),
Network::Testnet4 => Params::new(*network),
Network::Signet => Params::new(*network),
Network::Regtest => Params::new(*network),
_ => unreachable!(),
Expand All @@ -118,6 +119,7 @@ pub(crate) fn default_port_from_network(network: &Network) -> u16 {
match network {
Network::Bitcoin => 8333,
Network::Testnet => 18333,
Network::Testnet4 => 48333,
Network::Signet => 38333,
Network::Regtest => 18444,
_ => unreachable!(),
Expand Down

0 comments on commit bed26e6

Please sign in to comment.