Skip to content

Commit

Permalink
feat(CLI): Contract Install with internal error restores the code (#788)
Browse files Browse the repository at this point in the history
This will prevent users from having to do the restore themselves in a second step. Since deploy reuses the install command it works for that too.
  • Loading branch information
willemneal authored Jul 26, 2023
1 parent 6750d78 commit 7f8581c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 11 deletions.
34 changes: 30 additions & 4 deletions cmd/soroban-cli/src/commands/contract/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ use std::array::TryFromSliceError;
use std::fmt::Debug;
use std::num::ParseIntError;

use crate::rpc::{self, Client};
use crate::{commands::config, utils, wasm};
use clap::{command, Parser};
use soroban_env_host::xdr::{
Error as XdrError, Hash, HostFunction, InvokeHostFunctionOp, Memo, MuxedAccount, Operation,
OperationBody, Preconditions, SequenceNumber, Transaction, TransactionExt, Uint256, VecM,
OperationBody, Preconditions, SequenceNumber, Transaction, TransactionExt, TransactionResult,
TransactionResultResult, Uint256, VecM,
};

use super::restore;
use crate::rpc::{self, Client};
use crate::{commands::config, utils, wasm};

#[derive(Parser, Debug, Clone)]
#[group(skip)]
pub struct Cmd {
Expand Down Expand Up @@ -39,6 +42,8 @@ pub enum Error {
Wasm(#[from] wasm::Error),
#[error("unexpected ({length}) simulate transaction result length")]
UnexpectedSimulateTransactionResultSize { length: usize },
#[error(transparent)]
Restore(#[from] restore::Error),
}

impl Cmd {
Expand Down Expand Up @@ -86,14 +91,35 @@ impl Cmd {
let (tx_without_preflight, hash) =
build_install_contract_code_tx(contract.clone(), sequence + 1, self.fee.fee, &key)?;

client
// Currently internal errors are not returned if the contract code is expired
if let (
TransactionResult {
result: TransactionResultResult::TxInternalError,
..
},
_,
_,
) = client
.prepare_and_send_transaction(
&tx_without_preflight,
&key,
&network.network_passphrase,
None,
)
.await?
{
// Now just need to restore it and don't have to install again
restore::Cmd {
contract_id: None,
key: vec![],
key_xdr: vec![],
wasm: Some(self.wasm.wasm.clone()),
config: self.config.clone(),
fee: self.fee.clone(),
}
.run_against_rpc_server()
.await?;
}

Ok(hash)
}
Expand Down
14 changes: 7 additions & 7 deletions cmd/soroban-cli/src/commands/contract/restore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,32 +27,32 @@ pub struct Cmd {
/// Contract ID to which owns the data entries.
/// If no keys provided the Contract's instance will be restored
#[arg(long = "id", required_unless_present = "wasm")]
contract_id: Option<String>,
pub contract_id: Option<String>,
/// Storage key (symbols only)
#[arg(
long = "key",
required_unless_present = "key_xdr",
required_unless_present = "wasm"
)]
key: Vec<String>,
pub key: Vec<String>,
/// Storage key (base64-encoded XDR)
#[arg(
long = "key-xdr",
required_unless_present = "key",
required_unless_present = "wasm"
)]
key_xdr: Vec<String>,
pub key_xdr: Vec<String>,
/// Path to Wasm file of contract code to restore
#[arg(
long,
conflicts_with = "key",
conflicts_with = "key_xdr",
conflicts_with = "contract_id"
)]
wasm: Option<PathBuf>,
pub wasm: Option<PathBuf>,

#[command(flatten)]
config: config::Args,
pub config: config::Args,
#[command(flatten)]
pub fee: crate::fee::Args,
}
Expand Down Expand Up @@ -115,7 +115,7 @@ impl Cmd {
Ok(())
}

async fn run_against_rpc_server(&self) -> Result<u32, Error> {
pub async fn run_against_rpc_server(&self) -> Result<u32, Error> {
let network = self.config.get_network()?;
tracing::trace!(?network);
let entry_keys = if let Some(wasm) = &self.wasm {
Expand Down Expand Up @@ -216,7 +216,7 @@ impl Cmd {
}
}

fn run_in_sandbox(&self) -> Result<u32, Error> {
pub fn run_in_sandbox(&self) -> Result<u32, Error> {
// TODO: Implement this. This means we need to store ledger entries somewhere, and handle
// eviction, and restoration with that evicted state store.
todo!("Restoring ledger entries is not supported in the local sandbox mode");
Expand Down

0 comments on commit 7f8581c

Please sign in to comment.