Skip to content

Commit

Permalink
Add transaction saving and broadcasting feature
Browse files Browse the repository at this point in the history
This adds:
  - `pcli tx --offline <FILE> <COMMAND>`
  - `pcli tx broadcast <FILE>`
The first will save the transaction to a file after signing, the second
will broadcast the result of the first command.

Closes #4660.
  • Loading branch information
cronokirby authored and conorsch committed Jun 25, 2024
1 parent 5997033 commit 97505dc
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 6 deletions.
6 changes: 3 additions & 3 deletions crates/bin/pcli/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub use tx::TxCmd;
pub use validator::ValidatorCmd;
pub use view::ViewCmd;

use self::ceremony::CeremonyCmd;
use self::{ceremony::CeremonyCmd, tx::TxCmdWithOptions};

mod ceremony;
mod debug;
Expand Down Expand Up @@ -51,8 +51,8 @@ pub enum Command {
#[clap(subcommand, display_order = 300, visible_alias = "v")]
View(ViewCmd),
/// Create and broadcast a transaction.
#[clap(subcommand, display_order = 400, visible_alias = "tx")]
Transaction(TxCmd),
#[clap(display_order = 400, visible_alias = "tx")]
Transaction(TxCmdWithOptions),
/// Manage a validator.
#[clap(subcommand, display_order = 900)]
Validator(ValidatorCmd),
Expand Down
38 changes: 36 additions & 2 deletions crates/bin/pcli/src/command/tx.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use std::{
collections::BTreeMap,
fs::File,
fs::{self, File},
io::{Read, Write},
path::PathBuf,
str::FromStr,
time::{SystemTime, UNIX_EPOCH},
};

use anyhow::{ensure, Context, Result};
use ark_ff::UniformRand;
use clap::Parser;
use decaf377::{Fq, Fr};
use ibc_proto::ibc::core::client::v1::{
query_client::QueryClient as IbcClientQueryClient, QueryClientStateRequest,
Expand Down Expand Up @@ -56,7 +58,7 @@ use penumbra_proto::{
use penumbra_shielded_pool::Ics20Withdrawal;
use penumbra_stake::rate::RateData;
use penumbra_stake::{DelegationToken, IdentityKey, Penalty, UnbondingToken, UndelegateClaimPlan};
use penumbra_transaction::gas::swap_claim_gas_cost;
use penumbra_transaction::{gas::swap_claim_gas_cost, Transaction};
use penumbra_view::{SpendableNoteRecord, ViewClient};
use penumbra_wallet::plan::{self, Planner};
use proposal::ProposalCmd;
Expand All @@ -74,6 +76,27 @@ mod replicate;
/// in the [`PositionCmd::CloseAll`]/[`PositionCmd::WithdrawAll`] commands.
const POSITION_CHUNK_SIZE: usize = 30;

#[derive(Debug, Parser)]
pub struct TxCmdWithOptions {
/// If present, a file to save the transaction to instead of broadcasting it
#[clap(long)]
pub offline: Option<PathBuf>,
#[clap(subcommand)]
pub cmd: TxCmd,
}

impl TxCmdWithOptions {
/// Determine if this command requires a network sync before it executes.
pub fn offline(&self) -> bool {
self.cmd.offline()
}

pub async fn exec(&self, app: &mut App) -> Result<()> {
app.save_transaction_here_instead = self.offline.clone();
self.cmd.exec(app).await
}
}

#[derive(Debug, clap::Subcommand)]
pub enum TxCmd {
/// Auction related commands.
Expand Down Expand Up @@ -232,6 +255,12 @@ pub enum TxCmd {
#[clap(short, long, default_value_t)]
fee_tier: FeeTier,
},
/// Broadcast a saved transaction to the network
#[clap(display_order = 1000)]
Broadcast {
/// The transaction to be broadcast
transaction: PathBuf,
},
}

/// Vote on a governance proposal.
Expand Down Expand Up @@ -286,6 +315,7 @@ impl TxCmd {
TxCmd::Position(lp_cmd) => lp_cmd.offline(),
TxCmd::Withdraw { .. } => false,
TxCmd::Auction(_) => false,
TxCmd::Broadcast { .. } => false,
}
}

Expand Down Expand Up @@ -1284,6 +1314,10 @@ impl TxCmd {
TxCmd::Auction(AuctionCmd::Dutch(auction_cmd)) => {
auction_cmd.exec(app).await?;
}
TxCmd::Broadcast { transaction } => {
let transaction: Transaction = serde_json::from_slice(&fs::read(transaction)?)?;
app.submit_transaction(transaction).await?;
}
}
Ok(())
}
Expand Down
3 changes: 3 additions & 0 deletions crates/bin/pcli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use {
view::v1::view_service_client::ViewServiceClient,
},
penumbra_view::ViewClient,
std::path::PathBuf,
};

pub mod command;
Expand All @@ -34,6 +35,8 @@ pub struct App {
pub custody: CustodyServiceClient<BoxGrpcService>,
pub governance_custody: CustodyServiceClient<BoxGrpcService>,
pub config: PcliConfig,
/// If present, save the transaction here instead of broadcasting it.
pub save_transaction_here_instead: Option<PathBuf>,
}

impl App {
Expand Down
11 changes: 10 additions & 1 deletion crates/bin/pcli/src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use penumbra_proto::{
use penumbra_stake::validator::Validator;
use penumbra_transaction::{txhash::TransactionId, Transaction, TransactionPlan};
use penumbra_view::ViewClient;
use std::future::Future;
use std::{fs, future::Future};
use tonic::transport::{Channel, ClientTlsConfig};
use tracing::instrument;

Expand Down Expand Up @@ -105,6 +105,15 @@ impl App {
&mut self,
transaction: Transaction,
) -> anyhow::Result<TransactionId> {
if let Some(file) = &self.save_transaction_here_instead {
println!(
"saving transaction to disk, path: {}",
file.to_string_lossy()
);
fs::write(file, &serde_json::to_vec(&transaction)?)?;
return Ok(transaction.id());
}

println!("broadcasting transaction and awaiting confirmation...");
let mut rsp = self.view().broadcast_transaction(transaction, true).await?;

Expand Down
1 change: 1 addition & 0 deletions crates/bin/pcli/src/opt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ impl Opt {
custody,
governance_custody,
config,
save_transaction_here_instead: None,
};
Ok((app, self.cmd))
}
Expand Down

0 comments on commit 97505dc

Please sign in to comment.