Skip to content
This repository has been archived by the owner on Jan 11, 2024. It is now read-only.

Commit

Permalink
add relayer cli
Browse files Browse the repository at this point in the history
  • Loading branch information
cryptoAtwill committed Oct 17, 2023
1 parent 249675c commit e9d0c6b
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 11 deletions.
4 changes: 4 additions & 0 deletions ipc/cli/src/commands/checkpoint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
use crate::commands::checkpoint::list_checkpoints::{
ListBottomUpCheckpoints, ListBottomUpCheckpointsArgs,
};
use crate::commands::checkpoint::relayer::{BottomUpRelayer, BottomUpRelayerArgs};
use crate::{CommandLineHandler, GlobalArguments};
use clap::{Args, Subcommand};

mod list_checkpoints;
mod relayer;

#[derive(Debug, Args)]
#[command(name = "checkpoint", about = "checkpoint related commands")]
Expand All @@ -20,11 +22,13 @@ impl CheckpointCommandsArgs {
pub async fn handle(&self, global: &GlobalArguments) -> anyhow::Result<()> {
match &self.command {
Commands::ListBottomup(args) => ListBottomUpCheckpoints::handle(global, args).await,
Commands::Relayer(args) => BottomUpRelayer::handle(global, args).await,
}
}
}

#[derive(Debug, Subcommand)]
pub(crate) enum Commands {
ListBottomup(ListBottomUpCheckpointsArgs),
Relayer(BottomUpRelayerArgs),
}
79 changes: 79 additions & 0 deletions ipc/cli/src/commands/checkpoint/relayer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2022-2023 Protocol Labs
// SPDX-License-Identifier: MIT

use crate::commands::get_subnet_config;
use crate::{CommandLineHandler, GlobalArguments};
use anyhow::anyhow;
use async_trait::async_trait;
use clap::Args;
use fvm_shared::address::Address;
use ipc_identity::EvmKeyStore;
use ipc_provider::checkpoint::BottomUpCheckpointManager;
use ipc_provider::new_evm_keystore_from_path;
use ipc_sdk::subnet_id::SubnetID;
use std::str::FromStr;
use std::sync::{Arc, RwLock};
use std::time::Duration;

const DEFAULT_CHECKPOINT_INTERVAL: u64 = 15;

/// The command to run the bottom up relayer in the background.
pub(crate) struct BottomUpRelayer;

#[async_trait]
impl CommandLineHandler for BottomUpRelayer {
type Arguments = BottomUpRelayerArgs;

async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> {
log::debug!("start bottom up relayer with args: {:?}", arguments);

let config_path = global.config_path();

let mut keystore = new_evm_keystore_from_path(&config_path)?;
let validator = match (arguments.validator.as_ref(), keystore.get_default()?) {
(Some(validator), _) => Address::from_str(validator)?,
(None, Some(addr)) => {
log::info!("using default address: {addr:?}");
Address::try_from(addr)?
}
_ => {
return Err(anyhow!("no validator address provided"));
}
};

let subnet = SubnetID::from_str(&arguments.subnet)?;
let parent = subnet
.parent()
.ok_or_else(|| anyhow!("root does not have parent"))?;

let child = get_subnet_config(&config_path, &subnet)?;
let parent = get_subnet_config(&config_path, &parent)?;

let manager = BottomUpCheckpointManager::new_evm_manager(
parent.clone(),
child.clone(),
Arc::new(RwLock::new(keystore)),
)
.await?;

let interval = Duration::from_secs(
arguments
.checkpoint_interval_sec
.unwrap_or(DEFAULT_CHECKPOINT_INTERVAL),
);
manager.run(validator, interval).await;

Ok(())
}
}

#[derive(Debug, Args)]
#[command(about = "Start the bottom up relayer")]
pub(crate) struct BottomUpRelayerArgs {
#[arg(long, short, help = "The subnet id of the checkpointing subnet")]
pub subnet: String,
#[arg(long, short, help = "The number of seconds to submit checkpoint")]
pub checkpoint_interval_sec: Option<u64>,
#[arg(long, short, help = "The hex encoded address of the validator")]
pub validator: Option<String>,
}
18 changes: 17 additions & 1 deletion ipc/cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@ use crate::commands::checkpoint::CheckpointCommandsArgs;
use crate::commands::crossmsg::CrossMsgsCommandsArgs;
use crate::commands::util::UtilCommandsArgs;
use crate::GlobalArguments;
use anyhow::{Context, Result};
use anyhow::{anyhow, Context, Result};

use clap::{Command, CommandFactory, Parser, Subcommand};
use clap_complete::{generate, Generator, Shell};
use fvm_shared::econ::TokenAmount;
use ipc_sdk::ethers_address_to_fil_address;

use ipc_provider::config::{Config, Subnet};
use ipc_sdk::subnet_id::SubnetID;
use std::fmt::Debug;
use std::io;
use std::path::Path;
use std::str::FromStr;

use crate::commands::config::ConfigCommandsArgs;
Expand Down Expand Up @@ -146,6 +149,19 @@ pub(crate) fn require_fil_addr_from_str(s: &str) -> anyhow::Result<fvm_shared::a
Ok(addr)
}

/// Get the subnet configuration from the config path
pub(crate) fn get_subnet_config(
config_path: impl AsRef<Path>,
subnet: &SubnetID,
) -> Result<Subnet> {
let config = Config::from_file(&config_path)?;
Ok(config
.subnets
.get(subnet)
.ok_or_else(|| anyhow!("{subnet} is not configured"))?
.clone())
}

#[cfg(test)]
mod tests {
use crate::f64_to_token_amount;
Expand Down
2 changes: 1 addition & 1 deletion ipc/identity/src/evm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub fn random_eth_key_info() -> KeyInfo {
}

#[cfg(feature = "with-ethers")]
#[derive(Clone, Eq, Hash, PartialEq, Default)]
#[derive(Debug, Clone, Eq, Hash, PartialEq, Default)]
pub struct EthKeyAddress {
inner: ethers::types::Address,
}
Expand Down
16 changes: 7 additions & 9 deletions ipc/provider/src/checkpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,14 @@ impl<T: BottomUpCheckpointRelayer + Send + Sync + 'static> BottomUpCheckpointMan
}

/// Run the bottom up checkpoint submission daemon in the background
pub fn run(self, validator: Address, submission_interval: Duration) {
tokio::spawn(async move {
loop {
if let Err(e) = self.submit_checkpoint(&validator).await {
log::error!("cannot submit checkpoint for validator: {validator} due to {e}");
}

tokio::time::sleep(submission_interval).await;
pub async fn run(self, validator: Address, submission_interval: Duration) {
loop {
if let Err(e) = self.submit_checkpoint(&validator).await {
log::error!("cannot submit checkpoint for validator: {validator} due to {e}");
}
});

tokio::time::sleep(submission_interval).await;
}
}

/// Submit the checkpoint from the target validator address
Expand Down

0 comments on commit e9d0c6b

Please sign in to comment.