openmina_gossipsub_sandbox/
main.rs

1use std::{
2    fs::{self, File},
3    io::Write,
4    path::PathBuf,
5};
6
7use libp2p::{futures::StreamExt, gossipsub, swarm::SwarmEvent, Multiaddr};
8use mina_transport::ed25519::SecretKey;
9use structopt::StructOpt;
10
11#[derive(StructOpt)]
12struct Args {
13    #[structopt(long, default_value = "target/gossipsub")]
14    path: PathBuf,
15    #[structopt(
16        long,
17        default_value = "fd7d111973bf5a9e3e87384f560fdead2f272589ca00b6d9e357fca9839631da"
18    )]
19    chain_id: String,
20    #[structopt(long)]
21    listen: Vec<Multiaddr>,
22    #[structopt(long)]
23    peer: Vec<Multiaddr>,
24}
25
26#[tokio::main]
27async fn main() {
28    env_logger::init();
29
30    let Args {
31        path,
32        chain_id,
33        listen,
34        mut peer,
35    } = Args::from_args();
36
37    let default_peer = [
38        "/dns4/seed-1.berkeley.o1test.net/tcp/10000/p2p/12D3KooWAdgYL6hv18M3iDBdaK1dRygPivSfAfBNDzie6YqydVbs",
39        "/ip4/34.135.63.47/tcp/10001/p2p/12D3KooWLjs54xHzVmMmGYb7W5RVibqbwD1co7M2ZMfPgPm7iAag",
40        "/dns4/seed-3.berkeley.o1test.net/tcp/10002/p2p/12D3KooWEiGVAFC7curXWXiGZyMWnZK9h8BKr88U8D5PKV3dXciv",
41
42        "/ip4/65.21.29.250/tcp/8302/p2p/12D3KooWAMKZM7ysxRka2RfQWxCXXFTopjZ1eZcwtSi4VPgcufaS",
43        "/ip4/176.9.123.23/tcp/8302/p2p/12D3KooWDKdHVbnkM7GJYML6ogYR5KmHUj9Ngnq1Lk42xcXnf2sx",
44        "/ip4/158.69.119.191/tcp/8302/p2p/12D3KooWFfPswpKr6jDpRXXiTzTkphsUquvftiwYSnNTXSoFd3pu",
45        "/ip4/51.222.104.199/tcp/8302/p2p/12D3KooWG9RB23qjbCiwjgZj2Rkyn5R94e6kqVw4cGLk6362wPPR",
46
47        "/ip4/65.21.123.88/tcp/8302/p2p/12D3KooWLKSM9oHWU7qwL7Ci75wunkjXpRmK6j5xq527zGw554AF",
48        "/ip4/65.109.123.166/tcp/8302/p2p/12D3KooWGc9vwL9DUvoLdBFPSQGCT2QTULskzhmXcn8zg2j3jdFF",
49        "/ip4/176.9.64.21/tcp/8302/p2p/12D3KooWG9owTshte2gR3joP4sgwAfdoV9bQeeB5y9R3QUprKLdJ",
50        "/ip4/35.238.71.15/tcp/65454/p2p/12D3KooWHdUVpCZ9KcF5hNBrwf2uy7BaPDKrxyHJAaM5epJgQucX",
51        "/ip4/35.224.199.118/tcp/25493/p2p/12D3KooWGbjV7ptpzLu4BuykKfEsF4ebLyR8gZAMUissMToKGVDQ",
52        "/ip4/35.193.28.252/tcp/37470/p2p/12D3KooWFcCiQqrzBVLEkPdpkHDgWr6AkSMthT96agKYBBVuRhHg",
53        "/ip4/142.132.154.120/tcp/58654/p2p/12D3KooWMPxTu24mCpi3TwmkU4fJk7a8TQ4agFZeTHQRi8KCc3nj",
54        "/ip4/65.108.121.245/tcp/8302/p2p/12D3KooWGQ4g2eY44n5JLqymi8KC55GbnujAFeXNQrmNKSq4NYrv",
55        "/ip4/65.109.123.173/tcp/8302/p2p/12D3KooWMd8K8FFd76cacUEE6sSzUPr7wj71TvMqGdFSgrpv923k",
56        "/ip4/65.109.123.235/tcp/8302/p2p/12D3KooWBK3vz1inMubXCUeDF4Min6eG5418toceG8QvNPWRW1Gz",
57        "/ip4/34.172.208.246/tcp/46203/p2p/12D3KooWNafCBobFGSdJyYonvSCB5KDzW3JZYnVBF6q22yhcXGjM",
58        "/ip4/34.29.40.184/tcp/7528/p2p/12D3KooWJoVjUsnDosW3Ae78V4CSf5SSe9Wyetr5DxutmMMfwdp8",
59        "/ip4/34.122.249.235/tcp/55894/p2p/12D3KooWMpGyhYHbzVeqYnxGHQQYmQNtYcoMLLZZmYRPvAJKxXXm",
60        "/ip4/35.232.20.138/tcp/10000/p2p/12D3KooWAdgYL6hv18M3iDBdaK1dRygPivSfAfBNDzie6YqydVbs",
61        "/ip4/88.198.230.168/tcp/8302/p2p/12D3KooWGA7AS91AWNtGEBCBk64kgirtTiyaXDTyDtKPTjpefNL9",
62        "/ip4/35.224.199.118/tcp/10360/p2p/12D3KooWDnC4XrJzas3heuz4LUehZjf2WJyfob2XEodrYL3soaf4",
63        "/ip4/34.123.4.144/tcp/10002/p2p/12D3KooWEiGVAFC7curXWXiGZyMWnZK9h8BKr88U8D5PKV3dXciv",
64        "/ip4/34.170.114.52/tcp/10001/p2p/12D3KooWLjs54xHzVmMmGYb7W5RVibqbwD1co7M2ZMfPgPm7iAag",
65        "/ip4/34.172.208.246/tcp/54351/p2p/12D3KooWEhCm8FVcqZSkXKNhuBPmsEfJGeqSmUxNQhpemZkENfik",
66        "/ip4/34.29.161.11/tcp/10946/p2p/12D3KooWCntSrMqSiovXcVfMZ56aYbzpZoh4mi7gJJNiZBmzXrpa",
67        "/ip4/35.238.71.15/tcp/23676/p2p/12D3KooWENsfMszNYBRfHZJUEAvXKThmZU3nijWVbLivq33AE2Vk",
68    ].map(|s| s.parse().unwrap());
69    if peer.is_empty() {
70        peer.extend(default_peer);
71    }
72
73    let sk = SecretKey::generate();
74
75    let local_key: libp2p::identity::Keypair = mina_transport::ed25519::Keypair::from(sk).into();
76    log::info!("{}", local_key.public().to_peer_id());
77
78    let message_authenticity = gossipsub::MessageAuthenticity::Signed(local_key.clone());
79    let gossipsub_config = gossipsub::ConfigBuilder::default()
80        .max_transmit_size(1024 * 1024 * 32)
81        .build()
82        .expect("the config must be a valid constant");
83    let behaviour: gossipsub::Behaviour =
84        gossipsub::Behaviour::new(message_authenticity, gossipsub_config)
85            .expect("strict validation mode must be compatible with this `message_authenticity`");
86
87    let mut swarm = mina_transport::swarm(
88        local_key,
89        chain_id.as_bytes(),
90        listen,
91        peer.iter().cloned(),
92        behaviour,
93    );
94
95    let topic = gossipsub::IdentTopic::new("coda/consensus-messages/0.0.1");
96    swarm.behaviour_mut().subscribe(&topic).unwrap();
97    for peer in peer {
98        for protocol in peer.iter() {
99            if let libp2p::multiaddr::Protocol::P2p(peer_id) = protocol {
100                swarm.behaviour_mut().add_explicit_peer(&peer_id);
101            }
102        }
103    }
104
105    fs::create_dir_all(&path).unwrap();
106    let mut file = File::create(path.join("snark_pool_diff")).unwrap();
107    while let Some(event) = swarm.next().await {
108        match event {
109            SwarmEvent::Behaviour(gossipsub::Event::Message { message, .. }) => {
110                // GossipNetMessageV2::SnarkPoolDiff
111                if message.data[8] == 1 {
112                    file.write_all(&message.data).unwrap();
113                }
114            }
115            SwarmEvent::Behaviour(gossipsub::Event::Subscribed { peer_id, topic }) => {
116                log::info!("{peer_id} {topic}");
117            }
118            SwarmEvent::ConnectionEstablished { .. } => {}
119            _ => {}
120        }
121    }
122}