Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions crates/astria-cli/src/cli/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@ use clap::Subcommand;
use color_eyre::eyre;

/// Interact with a Sequencer node
// allow: these are one-shot variants. the size doesn't matter as they are
// passed around only once.
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Subcommand)]
pub enum Command {
pub(crate) enum Command {
/// Commands for interacting with Sequencer accounts
CollectWithdrawalEvents(crate::commands::bridge::CollectWithdrawalEvents),
CollectWithdrawals(crate::commands::bridge::collect::WithdrawalEvents),
SubmitWithdrawals(crate::commands::bridge::submit::WithdrawalEvents),
}

impl Command {
pub async fn run(self) -> eyre::Result<()> {
pub(crate) async fn run(self) -> eyre::Result<()> {
match self {
Command::CollectWithdrawalEvents(args) => args.run().await,
Command::CollectWithdrawals(args) => args.run().await,
Command::SubmitWithdrawals(args) => args.run().await,
}
}
}
4 changes: 2 additions & 2 deletions crates/astria-cli/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const DEFAULT_SEQUENCER_CHAIN_ID: &str = "astria-dusk-7";
#[command(name = "astria-cli", version)]
pub struct Cli {
#[command(subcommand)]
pub command: Option<Command>,
pub(crate) command: Option<Command>,
}

impl Cli {
Expand All @@ -34,7 +34,7 @@ impl Cli {

/// Commands that can be run
#[derive(Debug, Subcommand)]
pub enum Command {
pub(crate) enum Command {
Bridge {
#[command(subcommand)]
command: bridge::Command,
Expand Down
64 changes: 32 additions & 32 deletions crates/astria-cli/src/cli/sequencer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use clap::{

/// Interact with a Sequencer node
#[derive(Debug, Subcommand)]
pub enum Command {
pub(crate) enum Command {
/// Commands for interacting with Sequencer accounts
Account {
#[command(subcommand)]
Expand Down Expand Up @@ -43,27 +43,27 @@ pub enum Command {
}

#[derive(Debug, Subcommand)]
pub enum AccountCommand {
pub(crate) enum AccountCommand {
/// Create a new Sequencer account
Create,
Balance(BasicAccountArgs),
Nonce(BasicAccountArgs),
}

#[derive(Debug, Subcommand)]
pub enum AddressCommand {
pub(crate) enum AddressCommand {
/// Construct a bech32m Sequencer address given a public key
Bech32m(Bech32mAddressArgs),
}

#[derive(Debug, Subcommand)]
pub enum BalanceCommand {
pub(crate) enum BalanceCommand {
/// Get the balance of a Sequencer account
Get(BasicAccountArgs),
}

#[derive(Debug, Subcommand)]
pub enum SudoCommand {
pub(crate) enum SudoCommand {
IbcRelayer {
#[command(subcommand)]
command: IbcRelayerChangeCommand,
Expand All @@ -77,23 +77,23 @@ pub enum SudoCommand {
}

#[derive(Debug, Subcommand)]
pub enum IbcRelayerChangeCommand {
pub(crate) enum IbcRelayerChangeCommand {
/// Add IBC Relayer
Add(IbcRelayerChangeArgs),
/// Remove IBC Relayer
Remove(IbcRelayerChangeArgs),
}

#[derive(Debug, Subcommand)]
pub enum FeeAssetChangeCommand {
pub(crate) enum FeeAssetChangeCommand {
/// Add Fee Asset
Add(FeeAssetChangeArgs),
/// Remove Fee Asset
Remove(FeeAssetChangeArgs),
}

#[derive(Args, Debug)]
pub struct BasicAccountArgs {
pub(crate) struct BasicAccountArgs {
/// The url of the Sequencer node
#[arg(
long,
Expand All @@ -106,7 +106,7 @@ pub struct BasicAccountArgs {
}

#[derive(Args, Debug)]
pub struct Bech32mAddressArgs {
pub(crate) struct Bech32mAddressArgs {
/// The hex formatted byte part of the bech32m address
#[arg(long)]
pub(crate) bytes: String,
Expand All @@ -116,7 +116,7 @@ pub struct Bech32mAddressArgs {
}

#[derive(Args, Debug)]
pub struct TransferArgs {
pub(crate) struct TransferArgs {
// The address of the Sequencer account to send amount to
pub(crate) to_address: Address,
// The amount being sent
Expand Down Expand Up @@ -145,17 +145,17 @@ pub struct TransferArgs {
env = "ROLLUP_SEQUENCER_CHAIN_ID",
default_value = crate::cli::DEFAULT_SEQUENCER_CHAIN_ID
)]
pub sequencer_chain_id: String,
pub(crate) sequencer_chain_id: String,
/// The asset to transer.
#[arg(long, default_value = "nria")]
pub asset: asset::Denom,
pub(crate) asset: asset::Denom,
/// The asset to pay the transfer fees with.
#[arg(long, default_value = "nria")]
pub fee_asset: asset::Denom,
pub(crate) fee_asset: asset::Denom,
}

#[derive(Args, Debug)]
pub struct FeeAssetChangeArgs {
pub(crate) struct FeeAssetChangeArgs {
/// The bech32m prefix that will be used for constructing addresses using the private key
#[arg(long, default_value = "astria")]
pub(crate) prefix: String,
Expand All @@ -178,14 +178,14 @@ pub struct FeeAssetChangeArgs {
env = "ROLLUP_SEQUENCER_CHAIN_ID",
default_value = crate::cli::DEFAULT_SEQUENCER_CHAIN_ID
)]
pub sequencer_chain_id: String,
pub(crate) sequencer_chain_id: String,
/// Asset's denomination string
#[arg(long)]
pub(crate) asset: asset::Denom,
}

#[derive(Args, Debug)]
pub struct IbcRelayerChangeArgs {
pub(crate) struct IbcRelayerChangeArgs {
/// The prefix to construct a bech32m address given the private key.
#[arg(long, default_value = "astria")]
pub(crate) prefix: String,
Expand All @@ -208,14 +208,14 @@ pub struct IbcRelayerChangeArgs {
env = "ROLLUP_SEQUENCER_CHAIN_ID",
default_value = crate::cli::DEFAULT_SEQUENCER_CHAIN_ID
)]
pub sequencer_chain_id: String,
pub(crate) sequencer_chain_id: String,
/// The address to add or remove as an IBC relayer
#[arg(long)]
pub(crate) address: Address,
}

#[derive(Args, Debug)]
pub struct InitBridgeAccountArgs {
pub(crate) struct InitBridgeAccountArgs {
/// The bech32m prefix that will be used for constructing addresses using the private key
#[arg(long, default_value = "astria")]
pub(crate) prefix: String,
Expand All @@ -238,21 +238,21 @@ pub struct InitBridgeAccountArgs {
env = "ROLLUP_SEQUENCER_CHAIN_ID",
default_value = crate::cli::DEFAULT_SEQUENCER_CHAIN_ID
)]
pub sequencer_chain_id: String,
pub(crate) sequencer_chain_id: String,
/// Plaintext rollup name (to be hashed into a rollup ID)
/// to initialize the bridge account with.
#[arg(long)]
pub(crate) rollup_name: String,
/// The asset to transer.
#[arg(long, default_value = "nria")]
pub asset: asset::Denom,
pub(crate) asset: asset::Denom,
/// The asset to pay the transfer fees with.
#[arg(long, default_value = "nria")]
pub fee_asset: asset::Denom,
pub(crate) fee_asset: asset::Denom,
}

#[derive(Args, Debug)]
pub struct BridgeLockArgs {
pub(crate) struct BridgeLockArgs {
/// The address of the Sequencer account to lock amount to
pub(crate) to_address: Address,
/// The amount being locked
Expand Down Expand Up @@ -282,23 +282,23 @@ pub struct BridgeLockArgs {
env = "ROLLUP_SEQUENCER_CHAIN_ID",
default_value = crate::cli::DEFAULT_SEQUENCER_CHAIN_ID
)]
pub sequencer_chain_id: String,
pub(crate) sequencer_chain_id: String,
/// The asset to lock.
#[arg(long, default_value = "nria")]
pub asset: asset::Denom,
pub(crate) asset: asset::Denom,
/// The asset to pay the transfer fees with.
#[arg(long, default_value = "nria")]
pub fee_asset: asset::Denom,
pub(crate) fee_asset: asset::Denom,
}

#[derive(Debug, Subcommand)]
pub enum BlockHeightCommand {
pub(crate) enum BlockHeightCommand {
/// Get the current block height of the Sequencer node
Get(BlockHeightGetArgs),
}

#[derive(Args, Debug)]
pub struct BlockHeightGetArgs {
pub(crate) struct BlockHeightGetArgs {
/// The url of the Sequencer node
#[arg(
long,
Expand All @@ -312,11 +312,11 @@ pub struct BlockHeightGetArgs {
env = "ROLLUP_SEQUENCER_CHAIN_ID",
default_value = crate::cli::DEFAULT_SEQUENCER_CHAIN_ID
)]
pub sequencer_chain_id: String,
pub(crate) sequencer_chain_id: String,
}

#[derive(Args, Debug)]
pub struct SudoAddressChangeArgs {
pub(crate) struct SudoAddressChangeArgs {
/// The bech32m prefix that will be used for constructing addresses using the private key
#[arg(long, default_value = "astria")]
pub(crate) prefix: String,
Expand All @@ -339,14 +339,14 @@ pub struct SudoAddressChangeArgs {
env = "ROLLUP_SEQUENCER_CHAIN_ID",
default_value = crate::cli::DEFAULT_SEQUENCER_CHAIN_ID
)]
pub sequencer_chain_id: String,
pub(crate) sequencer_chain_id: String,
/// The new address to take over sudo privileges
#[arg(long)]
pub(crate) address: Address,
}

#[derive(Args, Debug)]
pub struct ValidatorUpdateArgs {
pub(crate) struct ValidatorUpdateArgs {
/// The url of the Sequencer node
#[arg(
long,
Expand All @@ -360,7 +360,7 @@ pub struct ValidatorUpdateArgs {
env = "ROLLUP_SEQUENCER_CHAIN_ID",
default_value = crate::cli::DEFAULT_SEQUENCER_CHAIN_ID
)]
pub sequencer_chain_id: String,
pub(crate) sequencer_chain_id: String,
/// The bech32m prefix that will be used for constructing addresses using the private key
#[arg(long, default_value = "astria")]
pub(crate) prefix: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{
collections::BTreeMap,
path::PathBuf,
sync::Arc,
time::Duration,
Expand Down Expand Up @@ -33,6 +34,7 @@ use clap::Args;
use color_eyre::eyre::{
self,
bail,
ensure,
eyre,
OptionExt as _,
WrapErr as _,
Expand Down Expand Up @@ -61,7 +63,7 @@ use tracing::{
};

#[derive(Args, Debug)]
pub struct CollectWithdrawalEvents {
pub(crate) struct WithdrawalEvents {
/// The websocket endpoint of a geth compatible rollup.
#[arg(long)]
rollup_endpoint: String,
Expand Down Expand Up @@ -93,7 +95,7 @@ pub struct CollectWithdrawalEvents {
output: PathBuf,
}

impl CollectWithdrawalEvents {
impl WithdrawalEvents {
pub(crate) async fn run(self) -> eyre::Result<()> {
let Self {
rollup_endpoint,
Expand Down Expand Up @@ -126,7 +128,7 @@ impl CollectWithdrawalEvents {
.await
.wrap_err("failed initializing stream of rollup blocks")?;

let mut actions = Vec::new();
let mut actions_by_rollup_height = ActionsByRollupHeight::new();
loop {
tokio::select! {
biased;
Expand All @@ -138,15 +140,20 @@ impl CollectWithdrawalEvents {
block = incoming_blocks.next() => {
match block {
Some(Ok(block)) =>
actions.append(&mut BlockToActions {
if let Err(err) = actions_by_rollup_height.convert_and_insert(BlockToActions {
block_provider: block_provider.clone(),
contract_address,
block,
fee_asset: fee_asset.clone(),
rollup_asset_denom: rollup_asset_denom.clone(),
bridge_address,
asset_withdrawal_divisor,
}.run().await),
}).await {
error!(
err = AsRef::<dyn std::error::Error>::as_ref(&err),
"failed converting contract block to Sequencer actions and storing them; exiting stream");
break;
}
Some(Err(error)) => {
error!(
error = AsRef::<dyn std::error::Error>::as_ref(&error),
Expand All @@ -163,13 +170,44 @@ impl CollectWithdrawalEvents {
}
}

write_collected_actions(output_file, &actions).wrap_err("failed to write actions to file")
actions_by_rollup_height
.write_to_file(output_file)
.wrap_err("failed to write actions to file")
}
}

fn write_collected_actions(output_file: std::fs::File, actions: &[Action]) -> eyre::Result<()> {
let writer = std::io::BufWriter::new(output_file);
serde_json::to_writer(writer, actions).wrap_err("failed writing actions to file")
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(transparent)]
pub(crate) struct ActionsByRollupHeight(BTreeMap<u64, Vec<Action>>);

impl ActionsByRollupHeight {
fn new() -> Self {
Self(BTreeMap::new())
}

pub(crate) fn into_inner(self) -> BTreeMap<u64, Vec<Action>> {
self.0
}

async fn convert_and_insert(&mut self, block_to_actions: BlockToActions) -> eyre::Result<()> {
let rollup_height = block_to_actions
.block
.number
.ok_or_eyre("block was missing a number")?
.as_u64();
let actions = block_to_actions.run().await;
ensure!(
self.0.insert(rollup_height, actions).is_none(),
"already collected actions for block at rollup height `{rollup_height}`; no 2 blocks \
with the same height should have been seen",
);
Ok(())
}

fn write_to_file(self, file: std::fs::File) -> eyre::Result<()> {
let writer = std::io::BufWriter::new(file);
serde_json::to_writer(writer, &self.0).wrap_err("failed writing actions to file")
}
}

/// Constructs a block stream from `start` until `maybe_end`, if `Some`.
Expand Down
2 changes: 2 additions & 0 deletions crates/astria-cli/src/commands/bridge/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub(crate) mod collect;
pub(crate) mod submit;
Loading