openmina_bootstrap_sandbox/
main.rs1#![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 }
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 } }
136}