Skip to content

Commit

Permalink
Merge pull request #224 from rustaceanrob/control-example-11-22
Browse files Browse the repository at this point in the history
Add example for `filter-control`
  • Loading branch information
rustaceanrob authored Nov 27, 2024
2 parents 4898d6b + 5ead7fc commit 50cef27
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 6 deletions.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,8 @@ path = "example/rescan.rs"
name = "tor"
path = "example/tor.rs"
required-features = ["tor"]

[[example]]
name = "managed"
path = "example/managed.rs"
required-features = ["filter-control"]
78 changes: 78 additions & 0 deletions example/managed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//! Kyoto supports checking filters directly, as protocols like silent payments will have
//! many possible scripts to check. Enable the `filter-control` feature to check filters
//! manually in your program.

use kyoto::core::messages::NodeMessage;
use kyoto::{chain::checkpoints::HeaderCheckpoint, core::builder::NodeBuilder};
use kyoto::{AddrV2, Address, Network, ServiceFlags, TrustedPeer};
use std::collections::HashSet;
use std::{net::Ipv4Addr, str::FromStr};

const NETWORK: Network = Network::Signet;
const RECOVERY_HEIGHT: u32 = 170_000;
const ADDR: &str = "tb1q9pvjqz5u5sdgpatg3wn0ce438u5cyv85lly0pc";

#[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(ADDR)
.unwrap()
.require_network(NETWORK)
.unwrap()
.into();
let mut addresses = HashSet::new();
addresses.insert(address);
// Add preferred peers to connect to
let peer = TrustedPeer::new(
AddrV2::Ipv4(Ipv4Addr::new(23, 137, 57, 100)),
None,
ServiceFlags::P2P_V2,
);
// 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)
// 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();

tokio::task::spawn(async move { node.run().await });

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::Synced(_) => break,
NodeMessage::ConnectionsMet => {
tracing::info!("Connected to all required peers");
}
NodeMessage::IndexedFilter(mut filter) => {
let height = filter.height();
tracing::info!("Checking filter {}", height);
if filter.contains_any(&addresses).await {
let hash = filter.block_hash();
tracing::info!("Found script at {}!", hash);
break;
}
}
_ => (),
}
}
}
let _ = sender.shutdown().await;
tracing::info!("Shutting down");
}
7 changes: 3 additions & 4 deletions example/signet.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
//! The following configuration is likely a common set-up for most users.
//! New peers are stored in a local database, and the node connects to multiple peers
//! to improve the anonymity set when broadcasting transactions to the Bitcoin network.
//! Usual sync on Signet.

use kyoto::core::messages::NodeMessage;
use kyoto::{chain::checkpoints::HeaderCheckpoint, core::builder::NodeBuilder};
Expand All @@ -13,6 +11,7 @@ use std::{

const NETWORK: Network = Network::Signet;
const RECOVERY_HEIGHT: u32 = 170_000;
const ADDR: &str = "tb1q9pvjqz5u5sdgpatg3wn0ce438u5cyv85lly0pc";

#[tokio::main]
async fn main() {
Expand All @@ -22,7 +21,7 @@ async fn main() {
// 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("tb1q9pvjqz5u5sdgpatg3wn0ce438u5cyv85lly0pc")
let address = Address::from_str(ADDR)
.unwrap()
.require_network(NETWORK)
.unwrap()
Expand Down
2 changes: 2 additions & 0 deletions example/testnet4.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Usual sync on Testnet.

use kyoto::core::messages::NodeMessage;
use kyoto::{chain::checkpoints::HeaderCheckpoint, core::builder::NodeBuilder};
use kyoto::{Address, Network, PeerStoreSizeConfig, TrustedPeer};
Expand Down
5 changes: 3 additions & 2 deletions example/tor.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! This example demonstrates a limited resource device running with no default features.
//! Note that, without DNS enabled, at least one peer must be provided when building the node.
//! Kyoto allows for use of the Tor protocol to connect to peers.
//! To do so, the `arti` project is used to build a Tor client.
//! Enable Tor connections via the `tor` feature.

use kyoto::chain::checkpoints::SIGNET_HEADER_CP;
use kyoto::core::messages::NodeMessage;
Expand Down

0 comments on commit 50cef27

Please sign in to comment.