Skip to content

Commit

Permalink
feat: TxnResult for returning result or base64 xdr
Browse files Browse the repository at this point in the history
  • Loading branch information
willemneal authored and gitbutler-client committed Apr 2, 2024
1 parent 479d7b5 commit 894b0a0
Show file tree
Hide file tree
Showing 14 changed files with 202 additions and 82 deletions.
33 changes: 18 additions & 15 deletions cmd/crates/soroban-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,21 +235,24 @@ impl TestEnv {
},
hd_path: None,
};
cmd.run_against_rpc_server(
Some(&global::Args {
locator: config::locator::Args {
global: false,
config_dir,
},
filter_logs: Vec::default(),
quiet: false,
verbose: false,
very_verbose: false,
list: false,
}),
Some(&config),
)
.await
Ok(cmd
.run_against_rpc_server(
Some(&global::Args {
locator: config::locator::Args {
global: false,
config_dir,
},
filter_logs: Vec::default(),
quiet: false,
verbose: false,
very_verbose: false,
list: false,
}),
Some(&config),
)
.await?
.res()
.unwrap())
}

/// Reference to current directory of the `TestEnv`.
Expand Down
12 changes: 8 additions & 4 deletions cmd/soroban-cli/src/commands/contract/deploy/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::convert::Infallible;
use std::{array::TryFromSliceError, fmt::Debug, num::ParseIntError};

use crate::{
commands::{config, global, NetworkRunnable},
commands::{config, global, txn_result::TxnResult, NetworkRunnable},
rpc::{Client, Error as SorobanRpcError},
utils::{contract_id_hash_from_asset, parsing::parse_asset},
};
Expand Down Expand Up @@ -73,7 +73,7 @@ impl NetworkRunnable for Cmd {
&self,
_: Option<&global::Args>,
config: Option<&config::Args>,
) -> Result<String, Error> {
) -> Result<TxnResult<String>, Error> {
let config = config.unwrap_or(&self.config);
// Parse asset
let asset = parse_asset(&self.asset)?;
Expand Down Expand Up @@ -101,14 +101,18 @@ impl NetworkRunnable for Cmd {
network_passphrase,
&key,
)?;
self.fee.exit_if_build_only(&tx)?;
if self.fee.build_only {
return Ok(TxnResult::from_xdr(&tx)?);
}
let txn = client.create_assembled_transaction(&tx).await?;
let txn = self.fee.apply_to_assembled_txn(txn)?;
client
.send_assembled_transaction(txn, &key, &[], network_passphrase, None, None)
.await?;

Ok(stellar_strkey::Contract(contract_id.0).to_string())
Ok(TxnResult::Xdr(
stellar_strkey::Contract(contract_id.0).to_string(),
))
}
}

Expand Down
19 changes: 14 additions & 5 deletions cmd/soroban-cli/src/commands/contract/deploy/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ use soroban_env_host::{

use crate::commands::{
contract::{self, id::wasm::get_contract_id},
global, NetworkRunnable,
global,
txn_result::{self, TxnResult},
NetworkRunnable,
};
use crate::{
commands::{config, contract::install, HEADING_RPC},
Expand Down Expand Up @@ -91,6 +93,8 @@ pub enum Error {
Infallible(#[from] std::convert::Infallible),
#[error(transparent)]
WasmId(#[from] contract::id::wasm::Error),
#[error(transparent)]
TxnResult(#[from] txn_result::Error),
}

impl Cmd {
Expand All @@ -110,7 +114,7 @@ impl NetworkRunnable for Cmd {
&self,
global_args: Option<&global::Args>,
config: Option<&config::Args>,
) -> Result<String, Error> {
) -> Result<TxnResult<String>, Error> {
let config = config.unwrap_or(&self.config);
let wasm_hash = if let Some(wasm) = &self.wasm {
let mut fee = self.fee.clone();
Expand All @@ -123,7 +127,7 @@ impl NetworkRunnable for Cmd {
}
.run_against_rpc_server(global_args, Some(config))
.await?;
hex::encode(hash)
hex::encode(hash.try_res()?)
} else {
self.wasm_hash
.as_ref()
Expand Down Expand Up @@ -166,13 +170,18 @@ impl NetworkRunnable for Cmd {
salt,
&key,
)?;
self.fee.exit_if_build_only(&txn)?;
if self.fee.build_only {
return Ok(TxnResult::from_xdr(&txn)?);
}

let txn = client.create_assembled_transaction(&txn).await?;
let txn = self.fee.apply_to_assembled_txn(txn)?;
client
.send_assembled_transaction(txn, &key, &[], &network.network_passphrase, None, None)
.await?;
Ok(stellar_strkey::Contract(contract_id.0).to_string())
Ok(TxnResult::Res(
stellar_strkey::Contract(contract_id.0).to_string(),
))
}
}

Expand Down
18 changes: 12 additions & 6 deletions cmd/soroban-cli/src/commands/contract/extend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use soroban_env_host::xdr::{
};

use crate::{
commands::{config, global, NetworkRunnable},
commands::{config, global, txn_result::TxnResult, NetworkRunnable},
key,
rpc::{self, Client},
wasm, Pwd,
Expand Down Expand Up @@ -80,7 +80,11 @@ pub enum Error {
impl Cmd {
#[allow(clippy::too_many_lines)]
pub async fn run(&self) -> Result<(), Error> {
let ttl_ledger = self.run_against_rpc_server(None, None).await?;
let res = self.run_against_rpc_server(None, None).await?;
let TxnResult::Res(ttl_ledger) = &res else {
println!("{}", res.xdr().unwrap());
return Ok(());
};
if self.ttl_ledger_only {
println!("{ttl_ledger}");
} else {
Expand Down Expand Up @@ -110,7 +114,7 @@ impl NetworkRunnable for Cmd {
&self,
_args: Option<&global::Args>,
config: Option<&config::Args>,
) -> Result<u32, Self::Error> {
) -> Result<TxnResult<u32>, Self::Error> {
let config = config.unwrap_or(&self.config);
let network = config.get_network()?;
tracing::trace!(?network);
Expand Down Expand Up @@ -154,7 +158,9 @@ impl NetworkRunnable for Cmd {
resource_fee: 0,
}),
};
self.fee.exit_if_build_only(&tx)?;
if self.fee.build_only {
return Ok(TxnResult::from_xdr(&tx)?);
}
let res = client
.prepare_and_send_transaction(&tx, &key, &[], &network.network_passphrase, None, None)
.await?;
Expand Down Expand Up @@ -184,7 +190,7 @@ impl NetworkRunnable for Cmd {
let entry = client.get_full_ledger_entries(&keys).await?;
let extension = entry.entries[0].live_until_ledger_seq;
if entry.latest_ledger + i64::from(extend_to) < i64::from(extension) {
return Ok(extension);
return Ok(TxnResult::Res(extension));
}
}

Expand All @@ -199,7 +205,7 @@ impl NetworkRunnable for Cmd {
}),
..
}),
) => Ok(*live_until_ledger_seq),
) => Ok(TxnResult::Res(*live_until_ledger_seq)),
_ => Err(Error::LedgerEntryNotFound),
}
}
Expand Down
14 changes: 11 additions & 3 deletions cmd/soroban-cli/src/commands/contract/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use stellar_strkey::DecodeError;

use super::super::config::{self, locator};
use crate::commands::network::{self, Network};
use crate::commands::txn_result::TxnResult;
use crate::commands::{global, NetworkRunnable};
use crate::{
rpc::{self, Client},
Expand Down Expand Up @@ -116,7 +117,14 @@ impl Cmd {
}

pub async fn get_bytes(&self) -> Result<Vec<u8>, Error> {
self.run_against_rpc_server(None, None).await
// This is safe because fetch doesn't create a transaction
unsafe {
Ok(self
.run_against_rpc_server(None, None)
.await?
.res()
.unwrap_unchecked())
}
}

pub fn network(&self) -> Result<Network, Error> {
Expand All @@ -137,7 +145,7 @@ impl NetworkRunnable for Cmd {
&self,
_args: Option<&global::Args>,
config: Option<&config::Args>,
) -> Result<Vec<u8>, Error> {
) -> Result<TxnResult<Vec<u8>>, Error> {
let network = config.map_or_else(|| self.network(), |c| Ok(c.get_network()?))?;
tracing::trace!(?network);
let contract_id = self.contract_id()?;
Expand All @@ -146,7 +154,7 @@ impl NetworkRunnable for Cmd {
.verify_network_passphrase(Some(&network.network_passphrase))
.await?;
// async closures are not yet stable
Ok(client.get_remote_wasm(&contract_id).await?)
Ok(TxnResult::Res(client.get_remote_wasm(&contract_id).await?))
}
}
pub fn get_contract_wasm_from_storage(
Expand Down
16 changes: 11 additions & 5 deletions cmd/soroban-cli/src/commands/contract/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use soroban_env_host::xdr::{
};

use super::restore;
use crate::commands::txn_result::TxnResult;
use crate::commands::{global, NetworkRunnable};
use crate::key;
use crate::rpc::{self, Client};
Expand Down Expand Up @@ -66,7 +67,10 @@ pub enum Error {

impl Cmd {
pub async fn run(&self) -> Result<(), Error> {
let res_str = hex::encode(self.run_against_rpc_server(None, None).await?);
let res_str = match self.run_against_rpc_server(None, None).await? {
TxnResult::Xdr(xdr) => xdr,
TxnResult::Res(hash) => hex::encode(hash),
};
println!("{res_str}");
Ok(())
}
Expand All @@ -80,7 +84,7 @@ impl NetworkRunnable for Cmd {
&self,
args: Option<&global::Args>,
config: Option<&config::Args>,
) -> Result<Hash, Error> {
) -> Result<TxnResult<Hash>, Error> {
let config = config.unwrap_or(&self.config);
let contract = self.wasm.read()?;
let network = config.get_network()?;
Expand Down Expand Up @@ -119,12 +123,14 @@ impl NetworkRunnable for Cmd {
let (tx_without_preflight, hash) =
build_install_contract_code_tx(&contract, sequence + 1, self.fee.fee, &key)?;

self.fee.exit_if_build_only(&tx_without_preflight)?;
if self.fee.build_only {
return Ok(TxnResult::from_xdr(&tx_without_preflight)?);
}
let code_key =
xdr::LedgerKey::ContractCode(xdr::LedgerKeyContractCode { hash: hash.clone() });
let contract_data = client.get_ledger_entries(&[code_key]).await?;
if !contract_data.entries.unwrap_or_default().is_empty() {
return Ok(hash);
return Ok(TxnResult::Res(hash));
}
let txn = client
.create_assembled_transaction(&tx_without_preflight)
Expand Down Expand Up @@ -160,7 +166,7 @@ impl NetworkRunnable for Cmd {
.await?;
}

Ok(hash)
Ok(TxnResult::Res(hash))
}
}

Expand Down
17 changes: 12 additions & 5 deletions cmd/soroban-cli/src/commands/contract/invoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use super::super::{
config::{self, locator},
events,
};
use crate::commands::txn_result::TxnResult;
use crate::commands::NetworkRunnable;
use crate::{commands::global, rpc, Pwd};
use soroban_spec_tools::{contract, Spec};
Expand Down Expand Up @@ -263,7 +264,7 @@ impl Cmd {
Ok(())
}

pub async fn invoke(&self, global_args: &global::Args) -> Result<String, Error> {
pub async fn invoke(&self, global_args: &global::Args) -> Result<TxnResult<String>, Error> {
self.run_against_rpc_server(Some(global_args), None).await
}

Expand Down Expand Up @@ -300,7 +301,7 @@ impl NetworkRunnable for Cmd {
&self,
global_args: Option<&global::Args>,
config: Option<&config::Args>,
) -> Result<String, Error> {
) -> Result<TxnResult<String>, Error> {
let config = config.unwrap_or(&self.config);
let network = config.get_network()?;
tracing::trace!(?network);
Expand Down Expand Up @@ -334,7 +335,9 @@ impl NetworkRunnable for Cmd {
self.fee.fee,
&key,
)?;
self.fee.exit_if_build_only(&tx)?;
if self.fee.build_only {
return Ok(TxnResult::from_xdr(&tx)?);
}
let txn = client.create_assembled_transaction(&tx).await?;
let txn = self.fee.apply_to_assembled_txn(txn)?;
let (return_value, events) = if self.is_view() {
Expand Down Expand Up @@ -380,7 +383,11 @@ fn log_resources(resources: &SorobanResources) {
crate::log::cost(resources);
}

pub fn output_to_string(spec: &Spec, res: &ScVal, function: &str) -> Result<String, Error> {
pub fn output_to_string(
spec: &Spec,
res: &ScVal,
function: &str,
) -> Result<TxnResult<String>, Error> {
let mut res_str = String::new();
if let Some(output) = spec.find_function(function)?.outputs.first() {
res_str = spec
Expand All @@ -391,7 +398,7 @@ pub fn output_to_string(spec: &Spec, res: &ScVal, function: &str) -> Result<Stri
})?
.to_string();
}
Ok(res_str)
Ok(TxnResult::Res(res_str))
}

fn build_invoke_contract_tx(
Expand Down
14 changes: 10 additions & 4 deletions cmd/soroban-cli/src/commands/contract/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use soroban_env_host::{
use soroban_sdk::xdr::Limits;

use crate::{
commands::{config, global, NetworkRunnable},
commands::{config, global, txn_result::TxnResult, NetworkRunnable},
key,
rpc::{self, Client, FullLedgerEntries, FullLedgerEntry},
};
Expand Down Expand Up @@ -91,7 +91,13 @@ pub enum Error {

impl Cmd {
pub async fn run(&self) -> Result<(), Error> {
let entries = self.run_against_rpc_server(None, None).await?;
let entries = match self.run_against_rpc_server(None, None).await? {
TxnResult::Res(res) => res,
TxnResult::Xdr(xdr) => {
println!("{xdr}");
return Ok(());
}
};
self.output_entries(&entries)
}

Expand Down Expand Up @@ -178,12 +184,12 @@ impl NetworkRunnable for Cmd {
&self,
_: Option<&global::Args>,
config: Option<&config::Args>,
) -> Result<FullLedgerEntries, Error> {
) -> Result<TxnResult<FullLedgerEntries>, Error> {
let config = config.unwrap_or(&self.config);
let network = config.get_network()?;
tracing::trace!(?network);
let client = Client::new(&network.rpc_url)?;
let keys = self.key.parse_keys()?;
Ok(client.get_full_ledger_entries(&keys).await?)
Ok(TxnResult::Res(client.get_full_ledger_entries(&keys).await?))
}
}
Loading

0 comments on commit 894b0a0

Please sign in to comment.