Skip to content

Commit

Permalink
Handle restorePreamble in cli prepare_and_send helper
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Bellamy authored and willemneal committed Sep 11, 2023
1 parent c5d1559 commit ab0763b
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 14 deletions.
58 changes: 44 additions & 14 deletions cmd/soroban-cli/src/rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use tokio::time::sleep;
use crate::utils::{self, contract_spec};

mod transaction;
use transaction::{assemble, sign_soroban_authorizations};
use transaction::{assemble, build_restore_txn, sign_soroban_authorizations};

const VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION");

Expand Down Expand Up @@ -201,7 +201,18 @@ pub struct SimulateHostFunctionResult {
pub xdr: String,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, Default)]
#[derive(serde::Deserialize, serde::Serialize, Debug)]
pub struct SimulateTransactionResponseRestorePreamble {
#[serde(rename = "transactionData")]
pub transaction_data: String,
#[serde(
rename = "minResourceFee",
deserialize_with = "deserialize_number_from_string"
)]
pub min_resource_fee: u32,
}

#[derive(serde::Deserialize, serde::Serialize, Debug)]
pub struct SimulateTransactionResponse {
#[serde(
rename = "minResourceFee",
Expand Down Expand Up @@ -231,7 +242,9 @@ pub struct SimulateTransactionResponse {
rename = "latestLedger",
deserialize_with = "deserialize_number_from_string"
)]
pub latest_ledger: u64,
pub latest_ledger: u32,
#[serde(rename = "restorePreamble")]
restore_preamble: Option<SimulateTransactionResponseRestorePreamble>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub error: Option<String>,
}
Expand Down Expand Up @@ -626,22 +639,24 @@ soroban config identity fund {address} --helper-url <url>"#
pub async fn prepare_transaction(
&self,
tx: &Transaction,
) -> Result<(Transaction, Vec<DiagnosticEvent>), Error> {
) -> Result<
(
Transaction,
Option<SimulateTransactionResponseRestorePreamble>,
),
Error,
> {
tracing::trace!(?tx);
let sim_response = self
.simulate_transaction(&TransactionEnvelope::Tx(TransactionV1Envelope {
tx: tx.clone(),
signatures: VecM::default(),
}))
.await?;

let events = sim_response
.events
.iter()
.map(DiagnosticEvent::from_xdr_base64)
.collect::<Result<Vec<_>, _>>()?;

Ok((assemble(tx, &sim_response)?, events))
Ok((
assemble(tx, &sim_response, log_events)?,
sim_response.restore_preamble,
))
}

pub async fn prepare_and_send_transaction(
Expand All @@ -654,7 +669,20 @@ soroban config identity fund {address} --helper-url <url>"#
log_resources: Option<LogResources>,
) -> Result<(TransactionResult, TransactionMeta, Vec<DiagnosticEvent>), Error> {
let GetLatestLedgerResponse { sequence, .. } = self.get_latest_ledger().await?;
let (unsigned_tx, events) = self.prepare_transaction(tx_without_preflight).await?;
let (mut unsigned_tx, restore_preamble) = self
.prepare_transaction(tx_without_preflight, log_events)
.await?;
if let Some(restore) = restore_preamble {
// Build and submit the restore transaction
self.send_transaction(&utils::sign_transaction(
source_key,
&build_restore_txn(&unsigned_tx, &restore)?,
network_passphrase,
)?)
.await?;
// Increment the original txn's seq_num so it doesn't conflict
unsigned_tx.seq_num = SequenceNumber(unsigned_tx.seq_num.0 + 1);
}
let (part_signed_tx, signed_auth_entries) = sign_soroban_authorizations(
&unsigned_tx,
source_key,
Expand All @@ -671,7 +699,9 @@ soroban config identity fund {address} --helper-url <url>"#
(part_signed_tx, events)
} else {
// re-simulate to calculate the new fees
self.prepare_transaction(&part_signed_tx).await?
self.prepare_transaction(&part_signed_tx, log_events)
.await?
.0
};

// Try logging stuff if requested
Expand Down
23 changes: 23 additions & 0 deletions cmd/soroban-cli/src/rpc/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,29 @@ pub fn sign_soroban_authorization_entry(
Ok(auth)
}

pub fn build_restore_txn(
parent: &Transaction,
restore: &SimulateTransactionResponseRestorePreamble,
) -> Result<Transaction, Error> {
let transaction_data = SorobanTransactionData::from_xdr_base64(restore.transaction_data)?;
Ok(Transaction {
source_account: parent.source_account.clone(),
fee: parent.fee + restore.min_resource_fee,
seq_num: parent.seq_num,
cond: Preconditions::None,
memo: Memo::None,
operations: vec![Operation {
source_account: None,
body: OperationBody::RestoreFootprint(RestoreFootprintOp {
ext: ExtensionPoint::V0,
}),
}]
.try_into()
.unwrap(),
ext: TransactionExt::V1(transaction_data),
})
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit ab0763b

Please sign in to comment.