use ipfrs_network::{Bitswap, BitswapEvent, BitswapMessage};
use libp2p::PeerId;
use multihash_codetable::{Code, MultihashDigest};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
println!("=== Bitswap Protocol Example ===\n");
println!("1. Creating Bitswap instances for two peers");
let mut peer1_bitswap = Bitswap::new();
let mut peer2_bitswap = Bitswap::new();
let peer1_id = PeerId::random();
let peer2_id = PeerId::random();
println!(" Peer 1: {}", peer1_id);
println!(" Peer 2: {}\n", peer2_id);
let block1_hash = Code::Sha2_256.digest(b"Hello, IPFS!");
let block1_cid = cid::Cid::new_v1(0x55, block1_hash);
let block1_data = b"Hello, IPFS!".to_vec();
let block2_hash = Code::Sha2_256.digest(b"Distributed storage is awesome");
let block2_cid = cid::Cid::new_v1(0x55, block2_hash);
let block2_data = b"Distributed storage is awesome".to_vec();
println!("2. Initial setup");
println!(" Peer 1 has block: {}", block1_cid);
println!(" Peer 2 has block: {}\n", block2_cid);
peer1_bitswap.have(block1_cid).await?;
peer1_bitswap.want(block2_cid).await?;
peer2_bitswap.have(block2_cid).await?;
peer2_bitswap.want(block1_cid).await?;
let mut peer1_events = peer1_bitswap
.take_event_receiver()
.expect("Failed to get event receiver");
let mut peer2_events = peer2_bitswap
.take_event_receiver()
.expect("Failed to get event receiver");
println!("3. Peer 1 sends Want message for block2 to Peer 2");
let response = peer2_bitswap
.handle_message(BitswapMessage::Want(block2_cid), peer1_id)
.await?;
match response {
Some(BitswapMessage::Have(cid)) => {
println!(" ✓ Peer 2 responded: Has block {}\n", cid);
}
Some(BitswapMessage::DontHave(cid)) => {
println!(" ✗ Peer 2 responded: Doesn't have block {}\n", cid);
}
_ => println!(" No response\n"),
}
println!("4. Peer 2 sends Want message for block1 to Peer 1");
let response = peer1_bitswap
.handle_message(BitswapMessage::Want(block1_cid), peer2_id)
.await?;
match response {
Some(BitswapMessage::Have(cid)) => {
println!(" ✓ Peer 1 responded: Has block {}\n", cid);
}
Some(BitswapMessage::DontHave(cid)) => {
println!(" ✗ Peer 1 responded: Doesn't have block {}\n", cid);
}
_ => println!(" No response\n"),
}
println!("5. Peer 2 sends block2 to Peer 1");
let block_message = peer2_bitswap
.send_block(block2_cid, block2_data.clone(), peer1_id)
.await?;
peer1_bitswap
.handle_message(block_message, peer2_id)
.await?;
println!(" ✓ Block sent and received\n");
println!("6. Peer 1 sends block1 to Peer 2");
let block_message = peer1_bitswap
.send_block(block1_cid, block1_data.clone(), peer2_id)
.await?;
peer2_bitswap
.handle_message(block_message, peer1_id)
.await?;
println!(" ✓ Block sent and received\n");
println!("7. Processing events");
println!(" Peer 1 events:");
while let Ok(event) = peer1_events.try_recv() {
match event {
BitswapEvent::BlockReceived { cid, data, from } => {
println!(
" - Received block {} ({} bytes) from {}",
cid,
data.len(),
from
);
}
BitswapEvent::BlockSent { cid, to } => {
println!(" - Sent block {} to {}", cid, to);
}
BitswapEvent::BlockRequested { cid, from } => {
println!(" - Block {} requested by {}", cid, from);
}
BitswapEvent::BlockNotFound { cid, peer } => {
println!(" - Block {} not found at peer {}", cid, peer);
}
}
}
println!(" Peer 2 events:");
while let Ok(event) = peer2_events.try_recv() {
match event {
BitswapEvent::BlockReceived { cid, data, from } => {
println!(
" - Received block {} ({} bytes) from {}",
cid,
data.len(),
from
);
}
BitswapEvent::BlockSent { cid, to } => {
println!(" - Sent block {} to {}", cid, to);
}
BitswapEvent::BlockRequested { cid, from } => {
println!(" - Block {} requested by {}", cid, from);
}
BitswapEvent::BlockNotFound { cid, peer } => {
println!(" - Block {} not found at peer {}", cid, peer);
}
}
}
println!();
println!("8. Final statistics");
let stats1 = peer1_bitswap.stats().await;
println!(" Peer 1:");
println!(" - Want list size: {}", stats1.want_list_size);
println!(" - Have list size: {}", stats1.have_list_size);
println!(" - Pending requests: {}", stats1.pending_requests);
println!(
" - Peers with pending: {}",
stats1.peers_with_pending_requests
);
let stats2 = peer2_bitswap.stats().await;
println!(" Peer 2:");
println!(" - Want list size: {}", stats2.want_list_size);
println!(" - Have list size: {}", stats2.have_list_size);
println!(" - Pending requests: {}", stats2.pending_requests);
println!(
" - Peers with pending: {}",
stats2.peers_with_pending_requests
);
println!("\n=== Example completed successfully ===");
Ok(())
}