openmina_bootstrap_sandbox/
main.rs

1#![forbid(unsafe_code)]
2
3mod behaviour;
4use self::behaviour::Behaviour;
5
6mod client;
7
8mod snarked_ledger;
9
10mod bootstrap;
11
12mod record;
13mod replay;
14
15use std::{env, path::PathBuf};
16
17use libp2p::Multiaddr;
18use libp2p_rpc_behaviour::BehaviourBuilder;
19use mina_transport::ed25519::SecretKey;
20use structopt::StructOpt;
21
22#[derive(StructOpt)]
23struct Args {
24    #[structopt(long, default_value = "target/record")]
25    path: PathBuf,
26    #[structopt(
27        long,
28        default_value = "/coda/0.0.1/29936104443aaf264a7f0192ac64b1c7173198c1ed404c1bcff5e562e05eb7f6"
29    )]
30    chain_id: String,
31    #[structopt(long)]
32    listen: Vec<Multiaddr>,
33    #[structopt(long)]
34    peer: Vec<Multiaddr>,
35    #[structopt(subcommand)]
36    cmd: Command,
37}
38
39#[derive(StructOpt)]
40enum Command {
41    Again {
42        height: u32,
43    },
44    Record {
45        #[structopt(long)]
46        bootstrap: bool,
47    },
48    Replay {
49        height: u32,
50    },
51    // Test {
52    //     height: u32,
53    //     url: String,
54    // },
55    // TestGraphql {
56    //     height: u32,
57    //     url: String,
58    //     #[structopt(long)]
59    //     verbose: bool,
60    // },
61    // Archive {
62    //     state: String,
63    // },
64    // ApplyArchive,
65}
66#[tokio::main]
67async fn main() {
68    env_logger::init();
69
70    let Args {
71        path,
72        chain_id,
73        listen,
74        peer,
75        cmd,
76    } = Args::from_args();
77
78    let sk = env::var("OPENMINA_P2P_SEC_KEY")
79        .map(|key| {
80            let mut bytes = bs58::decode(key).with_check(Some(0x80)).into_vec().unwrap();
81            SecretKey::try_from_bytes(&mut bytes[1..]).unwrap()
82        })
83        .unwrap_or_else(|_| {
84            let mut bytes = rand::random::<[u8; 32]>();
85            log::info!(
86                "{}",
87                bs58::encode(&bytes).with_check_version(0x80).into_string()
88            );
89            SecretKey::try_from_bytes(&mut bytes).unwrap()
90        });
91
92    let local_key: libp2p::identity::Keypair = mina_transport::ed25519::Keypair::from(sk).into();
93    log::info!("{}", local_key.public().to_peer_id());
94
95    let identify = libp2p::identify::Behaviour::new(libp2p::identify::Config::new(
96        "ipfs/0.1.0".into(),
97        local_key.public(),
98    ));
99
100    match cmd {
101        Command::Again { height } => bootstrap::again(&path, height).await,
102        Command::Record { bootstrap } => {
103            let rpc = BehaviourBuilder::default().build();
104            let behaviour = Behaviour { rpc, identify };
105            let swarm =
106                mina_transport::swarm(local_key, chain_id.as_bytes(), listen, peer, behaviour);
107
108            record::run(swarm, &path, bootstrap).await
109        }
110        Command::Replay { height } => {
111            use mina_p2p_messages::rpc::{
112                AnswerSyncLedgerQueryV2, GetAncestryV2, GetBestTipV2,
113                GetStagedLedgerAuxAndPendingCoinbasesAtHashV2, GetTransitionChainProofV1ForV2,
114                GetTransitionChainV2,
115            };
116
117            let rpc = BehaviourBuilder::default()
118                .register_method::<GetBestTipV2>()
119                .register_method::<GetAncestryV2>()
120                .register_method::<GetStagedLedgerAuxAndPendingCoinbasesAtHashV2>()
121                .register_method::<AnswerSyncLedgerQueryV2>()
122                .register_method::<GetTransitionChainV2>()
123                .register_method::<GetTransitionChainProofV1ForV2>()
124                .build();
125            let behaviour = Behaviour { rpc, identify };
126
127            let swarm =
128                mina_transport::swarm(local_key, chain_id.as_bytes(), listen, [], behaviour);
129
130            replay::run(swarm, &path, height).await
131        } // Command::Test { .. } => unimplemented!(),
132          // Command::TestGraphql { .. } => unimplemented!(),
133          // Command::Archive { .. } => unimplemented!(),
134          // Command::ApplyArchive => unimplemented!(),
135    }
136}