From 14ee085fef3702a1f0889e0f99e1ea75d767fbc1 Mon Sep 17 00:00:00 2001 From: "Tyler.S" Date: Mon, 30 Oct 2023 17:16:26 -0700 Subject: [PATCH 01/11] Check if contract is compiled using RC SDK version in deploy --- .../src/commands/contract/deploy.rs | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/cmd/soroban-cli/src/commands/contract/deploy.rs b/cmd/soroban-cli/src/commands/contract/deploy.rs index 2b3cffb17..4fabdb291 100644 --- a/cmd/soroban-cli/src/commands/contract/deploy.rs +++ b/cmd/soroban-cli/src/commands/contract/deploy.rs @@ -11,7 +11,7 @@ use soroban_env_host::{ CreateContractArgs, Error as XdrError, Hash, HashIdPreimage, HashIdPreimageContractId, HostFunction, InvokeHostFunctionOp, Memo, MuxedAccount, Operation, OperationBody, Preconditions, PublicKey, ScAddress, SequenceNumber, Transaction, TransactionExt, Uint256, - VecM, WriteXdr, + VecM, WriteXdr, ScMetaV0, ScMetaEntry, }, HostError, }; @@ -22,6 +22,8 @@ use crate::{ utils, wasm, }; +const CONTRACT_META_SDK_KEY: &str = "rssdkver"; + #[derive(Parser, Debug, Clone)] #[command(group( clap::ArgGroup::new("wasm_src") @@ -46,6 +48,8 @@ pub struct Cmd { config: config::Args, #[command(flatten)] pub fee: crate::fee::Args, + #[arg(long, short = 'i')] + pub ignore_checks: bool, } #[derive(thiserror::Error, Debug)] @@ -74,8 +78,18 @@ pub enum Error { wasm_hash: String, error: stellar_strkey::DecodeError, }, + #[error("cannot parse WASM file {wasm}: {error}")] + CannotParseWasm { + wasm: std::path::PathBuf, + error: wasm::Error + }, #[error("Must provide either --wasm or --wash-hash")] WasmNotProvided, + #[error("the deployed smart contract {wasm} was built with Soroban Rust SDK v{version}, a release candidate version not intended for use with the Stellar Public Network. To deploy anyway, use --ignore-checks")] + ContractCompiledWithReleaseCandidateSdk { + wasm: std::path::PathBuf, + version: String + }, #[error(transparent)] Rpc(#[from] rpc::Error), #[error(transparent)] @@ -92,6 +106,25 @@ impl Cmd { } pub async fn run_and_get_contract_id(&self) -> Result { + if let Some(wasm_path) = &self.wasm { + let wasm_args = wasm::Args { wasm: wasm_path.clone() }; + let wasm_spec = wasm_args.parse().map_err(|e| { + Error::CannotParseWasm { + wasm: wasm_path.clone(), + error: e + } + })?; + if let Some(rs_sdk_ver) = get_contract_meta_sdk_version(&wasm_spec) { + if rs_sdk_ver.contains("rc") && !self.ignore_checks { + return Err(Error::ContractCompiledWithReleaseCandidateSdk { + wasm: wasm_path.clone(), + version: rs_sdk_ver + }); + } else if rs_sdk_ver.contains("rc") { + tracing::warn!("the deployed smart contract {path} was built with Soroban Rust SDK v{rs_sdk_ver}, a release candidate version not intended for use with the Stellar Public Network", path = wasm_path.display()); + } + } + } let wasm_hash = if let Some(wasm) = &self.wasm { let hash = install::Cmd { wasm: wasm::Args { wasm: wasm.clone() }, @@ -155,6 +188,28 @@ impl Cmd { } } +fn get_contract_meta_sdk_version(wasm_spec: &utils::contract_spec::ContractSpec) -> Option { + let rs_sdk_version_option = if let Some(_meta) = &wasm_spec.meta_base64 { + wasm_spec.meta.iter().find(|entry| { + match entry { + ScMetaEntry::ScMetaV0(ScMetaV0 { key, .. }) => { + key.to_string_lossy().contains(CONTRACT_META_SDK_KEY) + } + } + }) + } else { + None + }; + if let Some(rs_sdk_version_entry) = &rs_sdk_version_option { + match rs_sdk_version_entry { + ScMetaEntry::ScMetaV0(ScMetaV0 { val, .. }) => { + return Some(val.to_string_lossy()); + } + } + } + return None; +} + fn build_create_contract_tx( hash: Hash, sequence: i64, From 301a298a41c5f75eb7d615108cdc5254d24e3c63 Mon Sep 17 00:00:00 2001 From: "Tyler.S" Date: Mon, 30 Oct 2023 17:25:47 -0700 Subject: [PATCH 02/11] Rust fmt --- .../src/commands/contract/deploy.rs | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/cmd/soroban-cli/src/commands/contract/deploy.rs b/cmd/soroban-cli/src/commands/contract/deploy.rs index 4fabdb291..b537f37b9 100644 --- a/cmd/soroban-cli/src/commands/contract/deploy.rs +++ b/cmd/soroban-cli/src/commands/contract/deploy.rs @@ -10,8 +10,8 @@ use soroban_env_host::{ AccountId, ContractExecutable, ContractIdPreimage, ContractIdPreimageFromAddress, CreateContractArgs, Error as XdrError, Hash, HashIdPreimage, HashIdPreimageContractId, HostFunction, InvokeHostFunctionOp, Memo, MuxedAccount, Operation, OperationBody, - Preconditions, PublicKey, ScAddress, SequenceNumber, Transaction, TransactionExt, Uint256, - VecM, WriteXdr, ScMetaV0, ScMetaEntry, + Preconditions, PublicKey, ScAddress, ScMetaEntry, ScMetaV0, SequenceNumber, Transaction, + TransactionExt, Uint256, VecM, WriteXdr, }, HostError, }; @@ -81,14 +81,14 @@ pub enum Error { #[error("cannot parse WASM file {wasm}: {error}")] CannotParseWasm { wasm: std::path::PathBuf, - error: wasm::Error + error: wasm::Error, }, #[error("Must provide either --wasm or --wash-hash")] WasmNotProvided, #[error("the deployed smart contract {wasm} was built with Soroban Rust SDK v{version}, a release candidate version not intended for use with the Stellar Public Network. To deploy anyway, use --ignore-checks")] ContractCompiledWithReleaseCandidateSdk { wasm: std::path::PathBuf, - version: String + version: String, }, #[error(transparent)] Rpc(#[from] rpc::Error), @@ -107,18 +107,18 @@ impl Cmd { pub async fn run_and_get_contract_id(&self) -> Result { if let Some(wasm_path) = &self.wasm { - let wasm_args = wasm::Args { wasm: wasm_path.clone() }; - let wasm_spec = wasm_args.parse().map_err(|e| { - Error::CannotParseWasm { - wasm: wasm_path.clone(), - error: e - } + let wasm_args = wasm::Args { + wasm: wasm_path.clone(), + }; + let wasm_spec = wasm_args.parse().map_err(|e| Error::CannotParseWasm { + wasm: wasm_path.clone(), + error: e, })?; if let Some(rs_sdk_ver) = get_contract_meta_sdk_version(&wasm_spec) { if rs_sdk_ver.contains("rc") && !self.ignore_checks { - return Err(Error::ContractCompiledWithReleaseCandidateSdk { + return Err(Error::ContractCompiledWithReleaseCandidateSdk { wasm: wasm_path.clone(), - version: rs_sdk_ver + version: rs_sdk_ver, }); } else if rs_sdk_ver.contains("rc") { tracing::warn!("the deployed smart contract {path} was built with Soroban Rust SDK v{rs_sdk_ver}, a release candidate version not intended for use with the Stellar Public Network", path = wasm_path.display()); @@ -190,11 +190,9 @@ impl Cmd { fn get_contract_meta_sdk_version(wasm_spec: &utils::contract_spec::ContractSpec) -> Option { let rs_sdk_version_option = if let Some(_meta) = &wasm_spec.meta_base64 { - wasm_spec.meta.iter().find(|entry| { - match entry { - ScMetaEntry::ScMetaV0(ScMetaV0 { key, .. }) => { - key.to_string_lossy().contains(CONTRACT_META_SDK_KEY) - } + wasm_spec.meta.iter().find(|entry| match entry { + ScMetaEntry::ScMetaV0(ScMetaV0 { key, .. }) => { + key.to_string_lossy().contains(CONTRACT_META_SDK_KEY) } }) } else { From 180c98c889d0f33ce2ff243ad188996d910328c9 Mon Sep 17 00:00:00 2001 From: "Tyler.S" Date: Mon, 30 Oct 2023 17:28:50 -0700 Subject: [PATCH 03/11] Add info for --ignore-check --- cmd/soroban-cli/src/commands/contract/deploy.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/soroban-cli/src/commands/contract/deploy.rs b/cmd/soroban-cli/src/commands/contract/deploy.rs index b537f37b9..ef02ef35b 100644 --- a/cmd/soroban-cli/src/commands/contract/deploy.rs +++ b/cmd/soroban-cli/src/commands/contract/deploy.rs @@ -49,6 +49,7 @@ pub struct Cmd { #[command(flatten)] pub fee: crate::fee::Args, #[arg(long, short = 'i')] + /// Whether to ignore safety checks when deploying contracts pub ignore_checks: bool, } @@ -205,7 +206,7 @@ fn get_contract_meta_sdk_version(wasm_spec: &utils::contract_spec::ContractSpec) } } } - return None; + None } fn build_create_contract_tx( From 6a58122fdc0f9851d3ad5beba1450c1f9d93fc3e Mon Sep 17 00:00:00 2001 From: "Tyler.S" Date: Mon, 30 Oct 2023 17:28:57 -0700 Subject: [PATCH 04/11] Regenerate docs --- docs/soroban-cli-full-docs.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/soroban-cli-full-docs.md b/docs/soroban-cli-full-docs.md index a07f46d5b..fab85f1ba 100644 --- a/docs/soroban-cli-full-docs.md +++ b/docs/soroban-cli-full-docs.md @@ -283,6 +283,7 @@ Deploy a contract * `--fee ` — fee amount for transaction, in stroops. 1 stroop = 0.0000001 xlm Default value: `100` +* `-i`, `--ignore-checks` — Whether to ignore safety checks when deploying contracts From dc80efb7735b1d47f31a71da301deb4f9a535b1b Mon Sep 17 00:00:00 2001 From: "Tyler.S" Date: Tue, 31 Oct 2023 09:55:24 -0700 Subject: [PATCH 05/11] Update CLI tests --- cmd/soroban-rpc/internal/test/cli_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cmd/soroban-rpc/internal/test/cli_test.go b/cmd/soroban-rpc/internal/test/cli_test.go index f83380ace..2b22235ec 100644 --- a/cmd/soroban-rpc/internal/test/cli_test.go +++ b/cmd/soroban-rpc/internal/test/cli_test.go @@ -77,13 +77,13 @@ func TestCLIContractInstallAndDeploy(t *testing.T) { runSuccessfulCLICmd(t, "contract install --wasm "+helloWorldContractPath) wasm := getHelloWorldContract(t) contractHash := xdr.Hash(sha256.Sum256(wasm)) - output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt %s --wasm-hash %s", hex.EncodeToString(testSalt[:]), contractHash.HexString())) + output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt %s --wasm-hash %s --ignore-checks", hex.EncodeToString(testSalt[:]), contractHash.HexString())) outputsContractIDInLastLine(t, output) } func TestCLIContractDeploy(t *testing.T) { NewCLITest(t) - output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt %s --wasm %s", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt %s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) outputsContractIDInLastLine(t, output) } @@ -103,14 +103,14 @@ func outputsContractIDInLastLine(t *testing.T, output string) { func TestCLIContractDeployAndInvoke(t *testing.T) { NewCLITest(t) - contractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + contractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) output := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- hello --world=world", contractID)) require.Contains(t, output, `["Hello","world"]`) } func TestCLIRestorePreamble(t *testing.T) { test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) require.Equal(t, "1", count) count = runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) @@ -128,7 +128,7 @@ func TestCLIRestorePreamble(t *testing.T) { func TestCLIExtend(t *testing.T) { test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) require.Equal(t, "1", count) @@ -152,7 +152,7 @@ func TestCLIExtend(t *testing.T) { } func TestCLIExtendTooLow(t *testing.T) { test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) require.Equal(t, "1", count) @@ -174,7 +174,7 @@ func TestCLIExtendTooLow(t *testing.T) { func TestCLIExtendTooHigh(t *testing.T) { test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) require.Equal(t, "1", count) @@ -193,7 +193,7 @@ func TestCLIExtendTooHigh(t *testing.T) { func TestCLIRestore(t *testing.T) { test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) require.Equal(t, "1", count) From e5090167ce3a2a614101b5a26d7636497b6d2e47 Mon Sep 17 00:00:00 2001 From: "Tyler.S" Date: Tue, 31 Oct 2023 11:24:03 -0700 Subject: [PATCH 06/11] Move rc checking logic to install cmd --- .../src/commands/contract/deploy.rs | 56 ++----------------- .../src/commands/contract/install.rs | 51 ++++++++++++++++- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/cmd/soroban-cli/src/commands/contract/deploy.rs b/cmd/soroban-cli/src/commands/contract/deploy.rs index ef02ef35b..4f2ecfc19 100644 --- a/cmd/soroban-cli/src/commands/contract/deploy.rs +++ b/cmd/soroban-cli/src/commands/contract/deploy.rs @@ -10,7 +10,7 @@ use soroban_env_host::{ AccountId, ContractExecutable, ContractIdPreimage, ContractIdPreimageFromAddress, CreateContractArgs, Error as XdrError, Hash, HashIdPreimage, HashIdPreimageContractId, HostFunction, InvokeHostFunctionOp, Memo, MuxedAccount, Operation, OperationBody, - Preconditions, PublicKey, ScAddress, ScMetaEntry, ScMetaV0, SequenceNumber, Transaction, + Preconditions, PublicKey, ScAddress, SequenceNumber, Transaction, TransactionExt, Uint256, VecM, WriteXdr, }, HostError, @@ -22,8 +22,6 @@ use crate::{ utils, wasm, }; -const CONTRACT_META_SDK_KEY: &str = "rssdkver"; - #[derive(Parser, Debug, Clone)] #[command(group( clap::ArgGroup::new("wasm_src") @@ -48,7 +46,7 @@ pub struct Cmd { config: config::Args, #[command(flatten)] pub fee: crate::fee::Args, - #[arg(long, short = 'i')] + #[arg(long, short = 'i', default_value = "false")] /// Whether to ignore safety checks when deploying contracts pub ignore_checks: bool, } @@ -79,18 +77,9 @@ pub enum Error { wasm_hash: String, error: stellar_strkey::DecodeError, }, - #[error("cannot parse WASM file {wasm}: {error}")] - CannotParseWasm { - wasm: std::path::PathBuf, - error: wasm::Error, - }, + #[error("Must provide either --wasm or --wash-hash")] WasmNotProvided, - #[error("the deployed smart contract {wasm} was built with Soroban Rust SDK v{version}, a release candidate version not intended for use with the Stellar Public Network. To deploy anyway, use --ignore-checks")] - ContractCompiledWithReleaseCandidateSdk { - wasm: std::path::PathBuf, - version: String, - }, #[error(transparent)] Rpc(#[from] rpc::Error), #[error(transparent)] @@ -107,30 +96,12 @@ impl Cmd { } pub async fn run_and_get_contract_id(&self) -> Result { - if let Some(wasm_path) = &self.wasm { - let wasm_args = wasm::Args { - wasm: wasm_path.clone(), - }; - let wasm_spec = wasm_args.parse().map_err(|e| Error::CannotParseWasm { - wasm: wasm_path.clone(), - error: e, - })?; - if let Some(rs_sdk_ver) = get_contract_meta_sdk_version(&wasm_spec) { - if rs_sdk_ver.contains("rc") && !self.ignore_checks { - return Err(Error::ContractCompiledWithReleaseCandidateSdk { - wasm: wasm_path.clone(), - version: rs_sdk_ver, - }); - } else if rs_sdk_ver.contains("rc") { - tracing::warn!("the deployed smart contract {path} was built with Soroban Rust SDK v{rs_sdk_ver}, a release candidate version not intended for use with the Stellar Public Network", path = wasm_path.display()); - } - } - } let wasm_hash = if let Some(wasm) = &self.wasm { let hash = install::Cmd { wasm: wasm::Args { wasm: wasm.clone() }, config: self.config.clone(), fee: self.fee.clone(), + ignore_checks: self.ignore_checks } .run_and_get_hash() .await?; @@ -189,25 +160,6 @@ impl Cmd { } } -fn get_contract_meta_sdk_version(wasm_spec: &utils::contract_spec::ContractSpec) -> Option { - let rs_sdk_version_option = if let Some(_meta) = &wasm_spec.meta_base64 { - wasm_spec.meta.iter().find(|entry| match entry { - ScMetaEntry::ScMetaV0(ScMetaV0 { key, .. }) => { - key.to_string_lossy().contains(CONTRACT_META_SDK_KEY) - } - }) - } else { - None - }; - if let Some(rs_sdk_version_entry) = &rs_sdk_version_option { - match rs_sdk_version_entry { - ScMetaEntry::ScMetaV0(ScMetaV0 { val, .. }) => { - return Some(val.to_string_lossy()); - } - } - } - None -} fn build_create_contract_tx( hash: Hash, diff --git a/cmd/soroban-cli/src/commands/contract/install.rs b/cmd/soroban-cli/src/commands/contract/install.rs index fc171bbbe..a5d15615b 100644 --- a/cmd/soroban-cli/src/commands/contract/install.rs +++ b/cmd/soroban-cli/src/commands/contract/install.rs @@ -5,7 +5,7 @@ use std::num::ParseIntError; use clap::{command, Parser}; use soroban_env_host::xdr::{ Error as XdrError, Hash, HostFunction, InvokeHostFunctionOp, Memo, MuxedAccount, Operation, - OperationBody, Preconditions, SequenceNumber, Transaction, TransactionExt, TransactionResult, + OperationBody, Preconditions, ScMetaEntry, ScMetaV0, SequenceNumber, Transaction, TransactionExt, TransactionResult, TransactionResultResult, Uint256, VecM, }; @@ -14,6 +14,8 @@ use crate::key; use crate::rpc::{self, Client}; use crate::{commands::config, utils, wasm}; +const CONTRACT_META_SDK_KEY: &str = "rssdkver"; + #[derive(Parser, Debug, Clone)] #[group(skip)] pub struct Cmd { @@ -23,6 +25,9 @@ pub struct Cmd { pub fee: crate::fee::Args, #[command(flatten)] pub wasm: wasm::Args, + #[arg(long, short = 'i', default_value = "false")] + /// Whether to ignore safety checks when deploying contracts + pub ignore_checks: bool, } #[derive(thiserror::Error, Debug)] @@ -45,6 +50,16 @@ pub enum Error { UnexpectedSimulateTransactionResultSize { length: usize }, #[error(transparent)] Restore(#[from] restore::Error), + #[error("cannot parse WASM file {wasm}: {error}")] + CannotParseWasm { + wasm: std::path::PathBuf, + error: wasm::Error, + }, + #[error("the deployed smart contract {wasm} was built with Soroban Rust SDK v{version}, a release candidate version not intended for use with the Stellar Public Network. To deploy anyway, use --ignore-checks")] + ContractCompiledWithReleaseCandidateSdk { + wasm: std::path::PathBuf, + version: String, + }, } impl Cmd { @@ -55,6 +70,20 @@ impl Cmd { } pub async fn run_and_get_hash(&self) -> Result { + let wasm_spec = &self.wasm.parse().map_err(|e| Error::CannotParseWasm { + wasm: self.wasm.wasm.clone(), + error: e, + })?; + if let Some(rs_sdk_ver) = get_contract_meta_sdk_version(&wasm_spec) { + if rs_sdk_ver.contains("rc") && !self.ignore_checks { + return Err(Error::ContractCompiledWithReleaseCandidateSdk { + wasm: self.wasm.wasm.clone(), + version: rs_sdk_ver, + }); + } else if rs_sdk_ver.contains("rc") { + tracing::warn!("the deployed smart contract {path} was built with Soroban Rust SDK v{rs_sdk_ver}, a release candidate version not intended for use with the Stellar Public Network", path = self.wasm.wasm.display()); + } + } self.run_against_rpc_server(&self.wasm.read()?).await } @@ -117,6 +146,26 @@ impl Cmd { } } +fn get_contract_meta_sdk_version(wasm_spec: &utils::contract_spec::ContractSpec) -> Option { + let rs_sdk_version_option = if let Some(_meta) = &wasm_spec.meta_base64 { + wasm_spec.meta.iter().find(|entry| match entry { + ScMetaEntry::ScMetaV0(ScMetaV0 { key, .. }) => { + key.to_string_lossy().contains(CONTRACT_META_SDK_KEY) + } + }) + } else { + None + }; + if let Some(rs_sdk_version_entry) = &rs_sdk_version_option { + match rs_sdk_version_entry { + ScMetaEntry::ScMetaV0(ScMetaV0 { val, .. }) => { + return Some(val.to_string_lossy()); + } + } + } + None +} + pub(crate) fn build_install_contract_code_tx( source_code: &[u8], sequence: i64, From b988fbd4361a9f38b675159882bee8c99d45e1a7 Mon Sep 17 00:00:00 2001 From: "Tyler.S" Date: Tue, 31 Oct 2023 11:24:36 -0700 Subject: [PATCH 07/11] Update tests that use install cmd --- cmd/crates/soroban-test/tests/it/integration/util.rs | 2 ++ cmd/soroban-rpc/internal/test/cli_test.go | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/crates/soroban-test/tests/it/integration/util.rs b/cmd/crates/soroban-test/tests/it/integration/util.rs index 878f8a055..4cc41474f 100644 --- a/cmd/crates/soroban-test/tests/it/integration/util.rs +++ b/cmd/crates/soroban-test/tests/it/integration/util.rs @@ -69,6 +69,7 @@ pub fn deploy_contract(sandbox: &TestEnv, wasm: &Wasm) -> String { .arg("install") .arg("--wasm") .arg(wasm.path()) + .arg("--ignore-checks") .assert() .success() .stdout(format!("{hash}\n")); @@ -80,6 +81,7 @@ pub fn deploy_contract(sandbox: &TestEnv, wasm: &Wasm) -> String { .arg(&format!("{hash}")) .arg("--salt") .arg(TEST_SALT) + .arg("--ignore-checks") .assert() .success() .stdout(format!("{TEST_CONTRACT_ID}\n")); diff --git a/cmd/soroban-rpc/internal/test/cli_test.go b/cmd/soroban-rpc/internal/test/cli_test.go index 2b22235ec..de33f0721 100644 --- a/cmd/soroban-rpc/internal/test/cli_test.go +++ b/cmd/soroban-rpc/internal/test/cli_test.go @@ -66,7 +66,7 @@ func TestCLIWrapNative(t *testing.T) { func TestCLIContractInstall(t *testing.T) { NewCLITest(t) - output := runSuccessfulCLICmd(t, "contract install --wasm "+helloWorldContractPath) + output := runSuccessfulCLICmd(t, fmt.Sprintf("contract install --wasm %s --ignore-checks", helloWorldContractPath)) wasm := getHelloWorldContract(t) contractHash := xdr.Hash(sha256.Sum256(wasm)) require.Contains(t, output, contractHash.HexString()) @@ -74,7 +74,7 @@ func TestCLIContractInstall(t *testing.T) { func TestCLIContractInstallAndDeploy(t *testing.T) { NewCLITest(t) - runSuccessfulCLICmd(t, "contract install --wasm "+helloWorldContractPath) + runSuccessfulCLICmd(t, fmt.Sprintf("contract install --wasm %s --ignore-checks", helloWorldContractPath)) wasm := getHelloWorldContract(t) contractHash := xdr.Hash(sha256.Sum256(wasm)) output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt %s --wasm-hash %s --ignore-checks", hex.EncodeToString(testSalt[:]), contractHash.HexString())) From 9dd2b4f8c48dfe41ecfcfcc38ae164aa77c9ad5b Mon Sep 17 00:00:00 2001 From: "Tyler.S" Date: Tue, 31 Oct 2023 11:26:48 -0700 Subject: [PATCH 08/11] Formatting fix --- cmd/soroban-cli/src/commands/contract/deploy.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/cmd/soroban-cli/src/commands/contract/deploy.rs b/cmd/soroban-cli/src/commands/contract/deploy.rs index 4f2ecfc19..415f3fd3b 100644 --- a/cmd/soroban-cli/src/commands/contract/deploy.rs +++ b/cmd/soroban-cli/src/commands/contract/deploy.rs @@ -77,7 +77,6 @@ pub enum Error { wasm_hash: String, error: stellar_strkey::DecodeError, }, - #[error("Must provide either --wasm or --wash-hash")] WasmNotProvided, #[error(transparent)] @@ -160,7 +159,6 @@ impl Cmd { } } - fn build_create_contract_tx( hash: Hash, sequence: i64, From 279b6f7f2ea869ae6ea14836a637bc8eface90bc Mon Sep 17 00:00:00 2001 From: "Tyler.S" Date: Tue, 31 Oct 2023 11:29:12 -0700 Subject: [PATCH 09/11] Gen docs --- docs/soroban-cli-full-docs.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/soroban-cli-full-docs.md b/docs/soroban-cli-full-docs.md index fab85f1ba..66bb14230 100644 --- a/docs/soroban-cli-full-docs.md +++ b/docs/soroban-cli-full-docs.md @@ -285,6 +285,8 @@ Deploy a contract Default value: `100` * `-i`, `--ignore-checks` — Whether to ignore safety checks when deploying contracts + Default value: `false` + ## `soroban contract fetch` @@ -350,6 +352,9 @@ Install a WASM file to the ledger without creating a contract instance Default value: `100` * `--wasm ` — Path to wasm binary +* `-i`, `--ignore-checks` — Whether to ignore safety checks when deploying contracts + + Default value: `false` From b263f9b94ae6186f88c9cf81f83576aeb96d65da Mon Sep 17 00:00:00 2001 From: "Tyler.S" Date: Tue, 31 Oct 2023 11:30:40 -0700 Subject: [PATCH 10/11] rustfmt --- cmd/soroban-cli/src/commands/contract/deploy.rs | 6 +++--- cmd/soroban-cli/src/commands/contract/install.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/soroban-cli/src/commands/contract/deploy.rs b/cmd/soroban-cli/src/commands/contract/deploy.rs index 415f3fd3b..5ef18a833 100644 --- a/cmd/soroban-cli/src/commands/contract/deploy.rs +++ b/cmd/soroban-cli/src/commands/contract/deploy.rs @@ -10,8 +10,8 @@ use soroban_env_host::{ AccountId, ContractExecutable, ContractIdPreimage, ContractIdPreimageFromAddress, CreateContractArgs, Error as XdrError, Hash, HashIdPreimage, HashIdPreimageContractId, HostFunction, InvokeHostFunctionOp, Memo, MuxedAccount, Operation, OperationBody, - Preconditions, PublicKey, ScAddress, SequenceNumber, Transaction, - TransactionExt, Uint256, VecM, WriteXdr, + Preconditions, PublicKey, ScAddress, SequenceNumber, Transaction, TransactionExt, Uint256, + VecM, WriteXdr, }, HostError, }; @@ -100,7 +100,7 @@ impl Cmd { wasm: wasm::Args { wasm: wasm.clone() }, config: self.config.clone(), fee: self.fee.clone(), - ignore_checks: self.ignore_checks + ignore_checks: self.ignore_checks, } .run_and_get_hash() .await?; diff --git a/cmd/soroban-cli/src/commands/contract/install.rs b/cmd/soroban-cli/src/commands/contract/install.rs index a5d15615b..b30df716c 100644 --- a/cmd/soroban-cli/src/commands/contract/install.rs +++ b/cmd/soroban-cli/src/commands/contract/install.rs @@ -5,8 +5,8 @@ use std::num::ParseIntError; use clap::{command, Parser}; use soroban_env_host::xdr::{ Error as XdrError, Hash, HostFunction, InvokeHostFunctionOp, Memo, MuxedAccount, Operation, - OperationBody, Preconditions, ScMetaEntry, ScMetaV0, SequenceNumber, Transaction, TransactionExt, TransactionResult, - TransactionResultResult, Uint256, VecM, + OperationBody, Preconditions, ScMetaEntry, ScMetaV0, SequenceNumber, Transaction, + TransactionExt, TransactionResult, TransactionResultResult, Uint256, VecM, }; use super::restore; From c68d03cd8f0588263e9a47b93ed8b2dc28d32f2f Mon Sep 17 00:00:00 2001 From: "Tyler.S" Date: Tue, 31 Oct 2023 11:40:58 -0700 Subject: [PATCH 11/11] Reference fix --- cmd/soroban-cli/src/commands/contract/install.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/soroban-cli/src/commands/contract/install.rs b/cmd/soroban-cli/src/commands/contract/install.rs index b30df716c..ea5719140 100644 --- a/cmd/soroban-cli/src/commands/contract/install.rs +++ b/cmd/soroban-cli/src/commands/contract/install.rs @@ -74,7 +74,7 @@ impl Cmd { wasm: self.wasm.wasm.clone(), error: e, })?; - if let Some(rs_sdk_ver) = get_contract_meta_sdk_version(&wasm_spec) { + if let Some(rs_sdk_ver) = get_contract_meta_sdk_version(wasm_spec) { if rs_sdk_ver.contains("rc") && !self.ignore_checks { return Err(Error::ContractCompiledWithReleaseCandidateSdk { wasm: self.wasm.wasm.clone(),