diff --git a/e2e/tests/bindings.rs b/e2e/tests/bindings.rs index c071f07436..cd54df505f 100644 --- a/e2e/tests/bindings.rs +++ b/e2e/tests/bindings.rs @@ -19,7 +19,8 @@ mod hygiene { Deploy( name = "simple_contract_instance", contract = "SimpleContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); } @@ -36,7 +37,8 @@ async fn compile_bindings_from_contract_file() { Deploy( name = "simple_contract_instance", contract = "SimpleContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -119,12 +121,14 @@ async fn shared_types() -> Result<()> { Deploy( name = "contract_a", contract = "ContractA", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), Deploy( name = "contract_b", contract = "ContractB", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); { @@ -230,7 +234,8 @@ async fn type_paths_respected() -> Result<()> { Deploy( name = "contract_a_instance", contract = "ContractA", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); { diff --git a/e2e/tests/configurables.rs b/e2e/tests/configurables.rs index 6c65221f67..d9a002d56b 100644 --- a/e2e/tests/configurables.rs +++ b/e2e/tests/configurables.rs @@ -17,7 +17,7 @@ async fn contract_default_configurables() -> Result<()> { "sway/contracts/configurables/out/release/configurables.bin", LoadConfiguration::default(), )? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_instance = MyContract::new(contract_id, wallet.clone()); @@ -129,7 +129,7 @@ async fn contract_configurables() -> Result<()> { "sway/contracts/configurables/out/release/configurables.bin", LoadConfiguration::default().with_configurables(configurables), )? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_instance = MyContract::new(contract_id, wallet.clone()); @@ -197,7 +197,7 @@ async fn contract_manual_configurables() -> Result<()> { LoadConfiguration::default(), )? .with_configurables(configurables) - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_instance = MyContract::new(contract_id, wallet.clone()); diff --git a/e2e/tests/contracts.rs b/e2e/tests/contracts.rs index a9e3f6d14b..74b9a4f748 100644 --- a/e2e/tests/contracts.rs +++ b/e2e/tests/contracts.rs @@ -23,7 +23,8 @@ async fn test_multiple_args() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -60,17 +61,20 @@ async fn test_contract_calling_contract() -> Result<()> { Deploy( name = "lib_contract_instance", contract = "LibContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), Deploy( name = "lib_contract_instance2", contract = "LibContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), Deploy( name = "contract_caller_instance", contract = "LibContractCaller", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let lib_contract_id = lib_contract_instance.contract_id(); @@ -126,7 +130,8 @@ async fn test_reverting_transaction() -> Result<()> { Deploy( name = "contract_instance", contract = "RevertContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -155,7 +160,8 @@ async fn test_multiple_read_calls() -> Result<()> { Deploy( name = "contract_instance", contract = "MultiReadContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -191,7 +197,8 @@ async fn test_multi_call_beginner() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -222,7 +229,8 @@ async fn test_multi_call_pro() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -275,7 +283,8 @@ async fn test_contract_call_fee_estimation() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -312,7 +321,8 @@ async fn contract_call_has_same_estimated_and_used_gas() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -347,7 +357,8 @@ async fn mult_call_has_same_estimated_and_used_gas() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -383,7 +394,8 @@ async fn contract_method_call_respects_maturity() -> Result<()> { Deploy( name = "contract_instance", contract = "BlockHeightContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -418,7 +430,8 @@ async fn test_auth_msg_sender_from_sdk() -> Result<()> { Deploy( name = "contract_instance", contract = "AuthContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -444,7 +457,8 @@ async fn test_large_return_data() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -501,7 +515,8 @@ async fn can_handle_function_called_new() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -529,17 +544,18 @@ async fn test_contract_setup_macro_deploy_with_salt() -> Result<()> { Deploy( name = "lib_contract_instance", contract = "LibContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), Deploy( name = "contract_caller_instance", contract = "LibContractCaller", - wallet = "wallet" + wallet = "wallet", ), Deploy( name = "contract_caller_instance2", contract = "LibContractCaller", - wallet = "wallet" + wallet = "wallet", ), ); let lib_contract_id = lib_contract_instance.contract_id(); @@ -585,7 +601,8 @@ async fn test_wallet_getter() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -612,7 +629,8 @@ async fn test_connect_wallet() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); // ANCHOR_END: contract_setup_macro_manual_wallet @@ -664,7 +682,7 @@ async fn setup_output_variable_estimation_test() -> Result<( "sway/contracts/token_ops/out/release/token_ops.bin", LoadConfiguration::default(), )? - .deploy(&wallets[0], TxPolicies::default()) + .deploy_if_not_exists(&wallets[0], TxPolicies::default()) .await?; let mint_asset_id = contract_id.asset_id(&Bits256::zeroed()); @@ -788,7 +806,8 @@ async fn test_contract_instance_get_balances() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_id = contract_instance.contract_id(); @@ -832,7 +851,8 @@ async fn contract_call_futures_implement_send() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -864,12 +884,14 @@ async fn test_contract_set_estimation() -> Result<()> { Deploy( name = "lib_contract_instance", contract = "LibContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), Deploy( name = "contract_caller_instance", contract = "LibContractCaller", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let lib_contract_id = lib_contract_instance.contract_id(); @@ -924,17 +946,20 @@ async fn test_output_variable_contract_id_estimation_multicall() -> Result<()> { Deploy( name = "lib_contract_instance", contract = "LibContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), Deploy( name = "contract_caller_instance", contract = "LibContractCaller", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), Deploy( name = "contract_test_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1007,7 +1032,8 @@ async fn test_contract_call_with_non_default_max_input() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1057,7 +1083,8 @@ async fn test_add_custom_assets() -> Result<()> { Deploy( name = "contract_instance", contract = "MyContract", - wallet = "wallet_1" + wallet = "wallet_1", + random_salt = false, ), ); @@ -1119,7 +1146,8 @@ async fn test_payable_annotation() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1203,12 +1231,14 @@ async fn low_level_call() -> Result<()> { Deploy( name = "caller_contract_instance", contract = "MyCallerContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), Deploy( name = "target_contract_instance", contract = "MyTargetContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1410,7 +1440,8 @@ async fn can_configure_decoding_of_contract_return() -> Result<()> { Deploy( contract = "MyContract", name = "contract_instance", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ) ); @@ -1471,7 +1502,8 @@ async fn test_contract_submit_and_response() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1518,12 +1550,14 @@ async fn test_heap_type_multicall() -> Result<()> { Deploy( name = "contract_instance", contract = "VectorOutputContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), Deploy( name = "contract_instance_2", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1581,7 +1615,7 @@ async fn heap_types_correctly_offset_in_create_transactions_w_storage_slots() -> "sway/contracts/storage/out/release/storage.bin", LoadConfiguration::default(), )? - .deploy(&predicate, TxPolicies::default()) + .deploy_if_not_exists(&predicate, TxPolicies::default()) .await?; Ok(()) @@ -1604,12 +1638,14 @@ async fn test_arguments_with_gas_forwarded() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), Deploy( name = "contract_instance_2", contract = "VectorOutputContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1660,7 +1696,8 @@ async fn contract_custom_call_no_signatures_strategy() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let provider = wallet.try_provider()?; @@ -1711,7 +1748,7 @@ async fn contract_encoder_config_is_applied() -> Result<()> { "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let instance = TestContract::new(contract_id.clone(), wallet.clone()); @@ -1769,7 +1806,8 @@ async fn test_reentrant_calls() -> Result<()> { Deploy( name = "contract_caller_instance", contract = "LibContractCaller", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1810,7 +1848,8 @@ async fn msg_sender_gas_estimation_issue() { Deploy( contract = "MyContract", name = "contract_instance", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ) ); @@ -1843,7 +1882,8 @@ async fn variable_output_estimation_is_optimized() -> Result<()> { Deploy( contract = "MyContract", name = "contract_instance", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ) ); @@ -1910,7 +1950,7 @@ async fn simulations_can_be_made_without_coins() -> Result<()> { "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? - .deploy(wallet, TxPolicies::default()) + .deploy_if_not_exists(wallet, TxPolicies::default()) .await?; let provider = wallet.provider().cloned(); @@ -1941,7 +1981,7 @@ async fn simulations_can_be_made_without_coins_multicall() -> Result<()> { "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? - .deploy(wallet, TxPolicies::default()) + .deploy_if_not_exists(wallet, TxPolicies::default()) .await?; let provider = wallet.provider().cloned(); @@ -2000,7 +2040,7 @@ async fn contract_call_with_non_zero_base_asset_id_and_tip() -> Result<()> { "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? - .deploy(wallet, TxPolicies::default()) + .deploy_if_not_exists(wallet, TxPolicies::default()) .await?; let contract_instance = MyContract::new(contract_id, wallet.clone()); @@ -2043,7 +2083,8 @@ async fn max_fee_estimation_respects_tolerance() -> Result<()> { Deploy( name = "contract_instance", wallet = "deploy_wallet", - contract = "MyContract" + contract = "MyContract", + random_salt = false, ) ); let contract_instance = contract_instance.with_account(call_wallet.clone()); @@ -2178,7 +2219,7 @@ async fn blob_contract_deployment() -> Result<()> { let contract_id = contract .convert_to_loader(100_000)? - .deploy(&wallets[0], TxPolicies::default()) + .deploy_if_not_exists(&wallets[0], TxPolicies::default()) .await?; let contract_instance = MyContract::new(contract_id, wallets[0].clone()); @@ -2205,7 +2246,7 @@ async fn regular_contract_can_be_deployed() -> Result<()> { // when let contract_id = Contract::load_from(contract_binary, LoadConfiguration::default())? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; // then @@ -2237,7 +2278,7 @@ async fn unuploaded_loader_can_be_deployed_directly() -> Result<()> { let contract_id = Contract::load_from(contract_binary, LoadConfiguration::default())? .convert_to_loader(1024)? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_instance = MyContract::new(contract_id, wallet); @@ -2276,7 +2317,7 @@ async fn unuploaded_loader_can_upload_blobs_separately_then_deploy() -> Result<( contract.salt(), contract.storage_slots().to_vec(), )? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_instance = MyContract::new(contract_id, wallet); @@ -2307,7 +2348,9 @@ async fn loader_blob_already_uploaded_not_an_issue() -> Result<()> { .await?; // this will try to upload the blobs but skip upon encountering an error - let contract_id = contract.deploy(&wallet, TxPolicies::default()).await?; + let contract_id = contract + .deploy_if_not_exists(&wallet, TxPolicies::default()) + .await?; let contract_instance = MyContract::new(contract_id, wallet); let response = contract_instance.methods().something().call().await?.value; @@ -2337,13 +2380,13 @@ async fn loader_works_via_proxy() -> Result<()> { let contract_id = contract .convert_to_loader(100)? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_binary = "sway/contracts/proxy/out/release/proxy.bin"; let proxy_id = Contract::load_from(contract_binary, LoadConfiguration::default())? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let proxy = MyProxy::new(proxy_id, wallet.clone()); @@ -2388,7 +2431,7 @@ async fn loader_storage_works_via_proxy() -> Result<()> { let contract_id = contract .convert_to_loader(100)? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_binary = "sway/contracts/proxy/out/release/proxy.bin"; @@ -2398,7 +2441,7 @@ async fn loader_storage_works_via_proxy() -> Result<()> { let proxy_id = proxy_contract .with_storage_slots(combined_storage_slots) - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let proxy = MyProxy::new(proxy_id, wallet.clone()); diff --git a/e2e/tests/logs.rs b/e2e/tests/logs.rs index c5f5ba41d5..f9dc89dabd 100644 --- a/e2e/tests/logs.rs +++ b/e2e/tests/logs.rs @@ -15,7 +15,8 @@ async fn test_parse_logged_variables() -> Result<()> { Deploy( name = "contract_instance", contract = "LogContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -53,7 +54,8 @@ async fn test_parse_logs_values() -> Result<()> { Deploy( name = "contract_instance", contract = "LogContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -87,7 +89,8 @@ async fn test_parse_logs_custom_types() -> Result<()> { Deploy( name = "contract_instance", contract = "LogContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -127,7 +130,8 @@ async fn test_parse_logs_generic_types() -> Result<()> { Deploy( name = "contract_instance", contract = "LogContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -179,7 +183,8 @@ async fn test_decode_logs() -> Result<()> { Deploy( name = "contract_instance", contract = "LogContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -233,7 +238,8 @@ async fn test_decode_logs_with_no_logs() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -260,7 +266,8 @@ async fn test_multi_call_log_single_contract() -> Result<()> { Deploy( name = "contract_instance", contract = "LogContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -308,12 +315,14 @@ async fn test_multi_call_log_multiple_contracts() -> Result<()> { Deploy( name = "contract_instance", contract = "LogContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), Deploy( name = "contract_instance2", contract = "LogContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -362,12 +371,14 @@ async fn test_multi_call_contract_with_contract_logs() -> Result<()> { Deploy( name = "contract_caller_instance", contract = "ContractCaller", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), Deploy( name = "contract_caller_instance2", contract = "ContractCaller", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -375,7 +386,7 @@ async fn test_multi_call_contract_with_contract_logs() -> Result<()> { "./sway/logs/contract_logs/out/release/contract_logs.bin", LoadConfiguration::default(), )? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_instance = MyContract::new(contract_id.clone(), wallet.clone()); @@ -433,7 +444,8 @@ async fn test_require_log() -> Result<()> { Deploy( name = "contract_instance", contract = "RequireContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -490,7 +502,8 @@ async fn test_multi_call_require_log_single_contract() -> Result<()> { Deploy( name = "contract_instance", contract = "RequireContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -557,12 +570,14 @@ async fn test_multi_call_require_log_multi_contract() -> Result<()> { Deploy( name = "contract_instance", contract = "RequireContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), Deploy( name = "contract_instance2", contract = "RequireContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -701,7 +716,8 @@ async fn test_contract_with_contract_logs() -> Result<()> { Deploy( name = "contract_caller_instance", contract = "ContractCaller", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ) ); @@ -709,7 +725,7 @@ async fn test_contract_with_contract_logs() -> Result<()> { "./sway/logs/contract_logs/out/release/contract_logs.bin", LoadConfiguration::default(), )? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_instance = MyContract::new(contract_id.clone(), wallet.clone()); @@ -749,7 +765,8 @@ async fn test_script_logs_with_contract_logs() -> Result<()> { Deploy( name = "contract_instance", contract = "MyContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), LoadScript( name = "script_instance", @@ -962,7 +979,8 @@ async fn test_contract_require_from_contract() -> Result<()> { Deploy( name = "contract_caller_instance", contract = "ContractCaller", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ) ); @@ -970,7 +988,7 @@ async fn test_contract_require_from_contract() -> Result<()> { "./sway/contracts/lib_contract/out/release/lib_contract.bin", LoadConfiguration::default(), )? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_instance = MyContract::new(contract_id.clone(), wallet.clone()); @@ -1009,12 +1027,14 @@ async fn test_multi_call_contract_require_from_contract() -> Result<()> { Deploy( name = "contract_instance", contract = "ContractLogs", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), Deploy( name = "contract_caller_instance", contract = "ContractCaller", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1022,7 +1042,7 @@ async fn test_multi_call_contract_require_from_contract() -> Result<()> { "./sway/contracts/lib_contract/out/release/lib_contract.bin", LoadConfiguration::default(), )? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let lib_contract_instance = MyContract::new(contract_id.clone(), wallet.clone()); @@ -1065,7 +1085,8 @@ async fn test_script_require_from_contract() -> Result<()> { Deploy( name = "contract_instance", contract = "MyContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), LoadScript( name = "script_instance", @@ -1111,7 +1132,7 @@ async fn test_loader_script_require_from_loader_contract() -> Result<()> { let contract = Contract::load_from(contract_binary, LoadConfiguration::default())?; let contract_id = contract .convert_to_loader(100_000)? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_instance = MyContract::new(contract_id, wallet); @@ -1146,7 +1167,8 @@ async fn test_contract_asserts_log() -> Result<()> { Deploy( name = "contract_instance", contract = "LogContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1363,7 +1385,8 @@ async fn contract_token_ops_error_messages() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -1403,7 +1426,8 @@ async fn test_log_results() -> Result<()> { Deploy( contract = "MyContract", name = "contract_instance", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ) ); @@ -1441,7 +1465,8 @@ async fn can_configure_decoder_for_contract_log_decoding() -> Result<()> { Deploy( contract = "MyContract", name = "contract_instance", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ) ); @@ -1585,7 +1610,8 @@ async fn contract_heap_log() -> Result<()> { Deploy( contract = "MyContract", name = "contract_instance", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ) ); let contract_methods = contract_instance.methods(); diff --git a/e2e/tests/predicates.rs b/e2e/tests/predicates.rs index cb99b772c3..58642149b8 100644 --- a/e2e/tests/predicates.rs +++ b/e2e/tests/predicates.rs @@ -230,7 +230,7 @@ async fn pay_with_predicate() -> Result<()> { "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? - .deploy(&predicate, TxPolicies::default()) + .deploy_if_not_exists(&predicate, TxPolicies::default()) .await?; let contract_methods = MyContract::new(contract_id.clone(), predicate.clone()).methods(); @@ -299,7 +299,7 @@ async fn pay_with_predicate_vector_data() -> Result<()> { "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? - .deploy(&predicate, TxPolicies::default()) + .deploy_if_not_exists(&predicate, TxPolicies::default()) .await?; let contract_methods = MyContract::new(contract_id.clone(), predicate.clone()).methods(); @@ -361,7 +361,7 @@ async fn predicate_contract_transfer() -> Result<()> { "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? - .deploy(&predicate, TxPolicies::default()) + .deploy_if_not_exists(&predicate, TxPolicies::default()) .await?; let contract_balances = provider.get_contract_balances(&contract_id).await?; @@ -550,7 +550,7 @@ async fn contract_tx_and_call_params_with_predicate() -> Result<()> { "./sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? - .deploy(&predicate, TxPolicies::default()) + .deploy_if_not_exists(&predicate, TxPolicies::default()) .await?; println!("Contract deployed @ {contract_id}"); @@ -630,7 +630,7 @@ async fn diff_asset_predicate_payment() -> Result<()> { "./sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? - .deploy(&predicate, TxPolicies::default()) + .deploy_if_not_exists(&predicate, TxPolicies::default()) .await?; let contract_methods = MyContract::new(contract_id.clone(), predicate.clone()).methods(); diff --git a/e2e/tests/providers.rs b/e2e/tests/providers.rs index d9ca2500a6..cd7b289fd2 100644 --- a/e2e/tests/providers.rs +++ b/e2e/tests/providers.rs @@ -40,7 +40,7 @@ async fn test_provider_launch_and_connect() -> Result<()> { "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_instance_connected = MyContract::new(contract_id.clone(), wallet.clone()); @@ -88,7 +88,7 @@ async fn test_network_error() -> Result<()> { "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await; assert!(matches!(response, Err(Error::Provider(_)))); @@ -132,7 +132,8 @@ async fn test_input_message() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -179,7 +180,7 @@ async fn test_input_message_pays_fee() -> Result<()> { "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_instance = MyContract::new(contract_id, wallet.clone()); @@ -293,7 +294,8 @@ async fn contract_deployment_respects_maturity() -> Result<()> { LoadConfiguration::default(), ) .map(|loaded_contract| { - loaded_contract.deploy(wallet, TxPolicies::default().with_maturity(maturity)) + loaded_contract + .deploy_if_not_exists(wallet, TxPolicies::default().with_maturity(maturity)) }) }; @@ -325,7 +327,8 @@ async fn test_gas_forwarded_defaults_to_tx_limit() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -363,7 +366,8 @@ async fn test_amount_and_asset_forwarding() -> Result<()> { Deploy( name = "contract_instance", contract = "TokenContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_id = contract_instance.contract_id(); @@ -474,7 +478,8 @@ async fn test_gas_errors() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -526,7 +531,8 @@ async fn test_call_param_gas_errors() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -568,7 +574,8 @@ async fn test_get_gas_used() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -715,7 +722,8 @@ async fn test_sway_timestamp() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -876,7 +884,8 @@ async fn can_fetch_mint_transactions() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1027,7 +1036,8 @@ async fn tx_respects_policies() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1190,7 +1200,7 @@ async fn contract_call_with_impersonation() -> Result<()> { "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_instance = MyContract::new(contract_id, impersonator.clone()); diff --git a/e2e/tests/scripts.rs b/e2e/tests/scripts.rs index 4dbef3a279..a416b02b0e 100644 --- a/e2e/tests/scripts.rs +++ b/e2e/tests/scripts.rs @@ -527,14 +527,14 @@ async fn loader_script_calling_loader_proxy() -> Result<()> { let contract_id = contract .convert_to_loader(100)? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_binary = "sway/contracts/proxy/out/release/proxy.bin"; let proxy_id = Contract::load_from(contract_binary, LoadConfiguration::default())? .convert_to_loader(100)? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let proxy = MyProxy::new(proxy_id.clone(), wallet.clone()); diff --git a/e2e/tests/storage.rs b/e2e/tests/storage.rs index 8f2d1bf6ef..554b7123a1 100644 --- a/e2e/tests/storage.rs +++ b/e2e/tests/storage.rs @@ -23,7 +23,7 @@ async fn test_storage_initialization() -> Result<()> { "sway/contracts/storage/out/release/storage.bin", LoadConfiguration::default().with_storage_configuration(storage_configuration), )? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_instance = MyContract::new(contract_id, wallet.clone()); @@ -52,7 +52,7 @@ async fn test_init_storage_automatically() -> Result<()> { "sway/contracts/storage/out/release/storage.bin", LoadConfiguration::default(), )? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_methods = MyContract::new(contract_id, wallet.clone()).methods(); diff --git a/e2e/tests/types_contracts.rs b/e2e/tests/types_contracts.rs index 6fbc052587..e4e7dd3aba 100644 --- a/e2e/tests/types_contracts.rs +++ b/e2e/tests/types_contracts.rs @@ -22,7 +22,8 @@ async fn test_methods_typeless_argument() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -48,7 +49,8 @@ async fn call_with_empty_return() -> Result<()> { Deploy( name = "contract_instance", contract = "TestContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -78,7 +80,7 @@ async fn call_with_structs() -> Result<()> { "sway/types/contracts/complex_types_contract/out/release/complex_types_contract.bin", LoadConfiguration::default(), )? - .deploy(&wallet, TxPolicies::default()) + .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_methods = MyContract::new(contract_id, wallet).methods(); @@ -108,7 +110,8 @@ async fn abigen_different_structs_same_arg_name() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -137,7 +140,8 @@ async fn nested_structs() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -197,7 +201,8 @@ async fn calls_with_empty_struct() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -260,7 +265,8 @@ async fn test_tuples() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -334,7 +340,8 @@ async fn test_evm_address() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -401,7 +408,8 @@ async fn test_array() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -428,7 +436,8 @@ async fn test_arrays_with_custom_types() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -470,7 +479,8 @@ async fn str_in_array() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -510,7 +520,8 @@ async fn test_enum_inside_struct() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -552,7 +563,8 @@ async fn native_types_support() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -590,7 +602,8 @@ async fn enum_coding_w_variable_width_variants() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -631,7 +644,8 @@ async fn enum_coding_w_unit_enums() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -670,7 +684,8 @@ async fn enum_as_input() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -746,7 +761,8 @@ async fn type_inside_enum() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -810,7 +826,8 @@ async fn test_rust_option_can_be_decoded() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -862,7 +879,8 @@ async fn test_rust_option_can_be_encoded() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -916,7 +934,8 @@ async fn test_rust_result_can_be_decoded() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -968,7 +987,8 @@ async fn test_rust_result_can_be_encoded() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -1003,7 +1023,8 @@ async fn test_identity_can_be_decoded() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -1048,7 +1069,8 @@ async fn test_identity_can_be_encoded() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -1096,12 +1118,14 @@ async fn test_identity_with_two_contracts() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), Deploy( name = "contract_instance2", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1141,7 +1165,8 @@ async fn generics_test() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -1298,7 +1323,8 @@ async fn contract_vectors() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let methods = contract_instance.methods(); @@ -1385,7 +1411,8 @@ async fn test_b256() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1423,7 +1450,8 @@ async fn test_b512() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -1471,7 +1499,8 @@ async fn test_u128() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -1523,7 +1552,8 @@ async fn test_u256() -> Result<()> { Deploy( name = "contract_instance", contract = "TypesContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -1560,7 +1590,8 @@ async fn test_base_type_in_vec_output() -> Result<()> { Deploy( name = "contract_instance", contract = "VectorOutputContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -1599,7 +1630,8 @@ async fn test_composite_types_in_vec_output() -> Result<()> { Deploy( name = "contract_instance", contract = "VectorOutputContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -1668,7 +1700,8 @@ async fn test_bytes_output() -> Result<()> { Deploy( name = "contract_instance", contract = "BytesOutputContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1691,7 +1724,8 @@ async fn test_bytes_as_input() -> Result<()> { Deploy( name = "contract_instance", contract = "BytesInputContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -1727,7 +1761,8 @@ async fn contract_raw_slice() -> Result<()> { Deploy( name = "contract_instance", contract = "RawSliceContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1772,7 +1807,8 @@ async fn contract_string_slice() -> Result<()> { Deploy( name = "contract_instance", contract = "StringSliceContract", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); @@ -1798,7 +1834,8 @@ async fn contract_std_lib_string() -> Result<()> { Deploy( name = "contract_instance", contract = "StdLibString", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -1836,7 +1873,8 @@ async fn test_heap_type_in_enums() -> Result<()> { Deploy( name = "contract_instance", contract = "HeapTypeInEnum", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); let contract_methods = contract_instance.methods(); @@ -1948,7 +1986,8 @@ async fn nested_heap_types() -> Result<()> { Deploy( name = "contract_instance", contract = "HeapTypeInEnum", - wallet = "wallet" + wallet = "wallet", + random_salt = false, ), ); diff --git a/packages/fuels-accounts/src/provider.rs b/packages/fuels-accounts/src/provider.rs index 806ccd2cb0..862b3414fd 100644 --- a/packages/fuels-accounts/src/provider.rs +++ b/packages/fuels-accounts/src/provider.rs @@ -720,6 +720,10 @@ impl Provider { self } + + pub async fn contract_exists(&self, contract_id: &Bech32ContractId) -> Result { + Ok(self.client.contract_exists(&contract_id.into()).await?) + } } #[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] diff --git a/packages/fuels-accounts/src/provider/retryable_client.rs b/packages/fuels-accounts/src/provider/retryable_client.rs index 56acc0c862..69afc9bbf0 100644 --- a/packages/fuels-accounts/src/provider/retryable_client.rs +++ b/packages/fuels-accounts/src/provider/retryable_client.rs @@ -1,9 +1,10 @@ use std::{future::Future, io}; -use custom_queries::{IsUserAccountQuery, IsUserAccountVariables}; +use custom_queries::{ContractExistsQuery, IsUserAccountQuery, IsUserAccountVariables}; use cynic::QueryBuilder; use fuel_core_client::client::{ pagination::{PaginatedResult, PaginationRequest}, + schema::contract::ContractByIdArgs, types::{ gas_price::{EstimateGasPrice, LatestGasPrice}, primitives::{BlockId, TransactionId}, @@ -306,6 +307,22 @@ impl RetryableClient { }) .await } + + pub async fn contract_exists(&self, contract_id: &ContractId) -> RequestResult { + self.wrap(|| { + let query = ContractExistsQuery::build(ContractByIdArgs { + id: (*contract_id).into(), + }); + self.client.query(query) + }) + .await + .map(|query| { + query + .contract + .map(|contract| ContractId::from(contract.id) == *contract_id) + .unwrap_or(false) + }) + } // DELEGATION END pub async fn is_user_account(&self, address: [u8; 32]) -> Result { @@ -333,7 +350,9 @@ mod custom_queries { use fuel_core_client::client::schema::blob::BlobIdFragment; use fuel_core_client::client::schema::schema; use fuel_core_client::client::schema::{ - contract::ContractIdFragment, tx::TransactionIdFragment, BlobId, ContractId, TransactionId, + contract::{ContractByIdArgs, ContractIdFragment}, + tx::TransactionIdFragment, + BlobId, ContractId, TransactionId, }; #[derive(cynic::QueryVariables, Debug)] @@ -357,4 +376,15 @@ mod custom_queries { #[arguments(id: $transaction_id)] pub transaction: Option, } + + #[derive(cynic::QueryFragment, Clone, Debug)] + #[cynic( + schema_path = "./target/fuel-core-client-schema.sdl", + graphql_type = "Query", + variables = "ContractByIdArgs" + )] + pub struct ContractExistsQuery { + #[arguments(id: $id)] + pub contract: Option, + } } diff --git a/packages/fuels-macros/src/setup_program_test/code_gen.rs b/packages/fuels-macros/src/setup_program_test/code_gen.rs index b4c22c2b8c..a98a2911c2 100644 --- a/packages/fuels-macros/src/setup_program_test/code_gen.rs +++ b/packages/fuels-macros/src/setup_program_test/code_gen.rs @@ -124,17 +124,26 @@ fn contract_deploying_code( let contract_instance_name = ident(&command.name); let contract_struct_name = ident(&command.contract.value()); let wallet_name = ident(&command.wallet); + let random_salt = command.random_salt; let project = project_lookup .get(&command.contract.value()) .expect("Project should be in lookup"); let bin_path = project.bin_path(); + let salt = if random_salt { + quote! { + // Generate random salt for contract deployment. + // These lines must be inside the `quote!` macro, otherwise the salt remains + // identical between macro compilation, causing contract id collision. + ::fuels::test_helpers::generate_random_salt() + } + } else { + quote! { [0; 32] } + }; + quote! { - // Generate random salt for contract deployment. - // These lines must be inside the `quote!` macro, otherwise the salt remains - // identical between macro compilation, causing contract id collision. - let salt: [u8; 32] = ::fuels::test_helpers::generate_random_salt(); + let salt: [u8; 32] = #salt; let #contract_instance_name = { let load_config = ::fuels::programs::contract::LoadConfiguration::default().with_salt(salt); @@ -145,7 +154,7 @@ fn contract_deploying_code( ) .expect("Failed to load the contract"); - let contract_id = loaded_contract.deploy( + let contract_id = loaded_contract.deploy_if_not_exists( &#wallet_name, ::fuels::types::transaction::TxPolicies::default() ) diff --git a/packages/fuels-macros/src/setup_program_test/parsing/commands/deploy_contract.rs b/packages/fuels-macros/src/setup_program_test/parsing/commands/deploy_contract.rs index 748b968a98..3a42774289 100644 --- a/packages/fuels-macros/src/setup_program_test/parsing/commands/deploy_contract.rs +++ b/packages/fuels-macros/src/setup_program_test/parsing/commands/deploy_contract.rs @@ -1,6 +1,6 @@ use std::convert::TryFrom; -use syn::{Error, LitStr}; +use syn::{Error, Lit, LitStr}; use crate::parse_utils::{Command, UniqueNameValues}; @@ -9,6 +9,7 @@ pub struct DeployContractCommand { pub name: String, pub contract: LitStr, pub wallet: String, + pub random_salt: bool, } impl TryFrom for DeployContractCommand { @@ -16,16 +17,21 @@ impl TryFrom for DeployContractCommand { fn try_from(command: Command) -> Result { let name_values = UniqueNameValues::new(command.contents)?; - name_values.validate_has_no_other_names(&["name", "contract", "wallet"])?; + name_values.validate_has_no_other_names(&["name", "contract", "wallet", "random_salt"])?; let name = name_values.get_as_lit_str("name")?.value(); let contract = name_values.get_as_lit_str("contract")?.clone(); let wallet = name_values.get_as_lit_str("wallet")?.value(); + let random_salt = name_values.try_get("random_salt").map_or(true, |opt| { + let Lit::Bool(b) = opt else { return true }; + b.value() + }); Ok(Self { name, contract, wallet, + random_salt, }) } } diff --git a/packages/fuels-programs/src/contract/loader.rs b/packages/fuels-programs/src/contract/loader.rs index 71966f4762..5405f68c7d 100644 --- a/packages/fuels-programs/src/contract/loader.rs +++ b/packages/fuels-programs/src/contract/loader.rs @@ -236,6 +236,18 @@ impl Contract> { .await } + /// Deploys the loader contract after uploading the code blobs, + /// if there is no contract with this ContractId Already. + pub async fn deploy_if_not_exists( + self, + account: &impl Account, + tx_policies: TxPolicies, + ) -> Result { + self.upload_blobs(account, tx_policies) + .await? + .deploy_if_not_exists(account, tx_policies) + .await + } /// Reverts the contract from a loader contract back to a regular contract. pub fn revert_to_regular(self) -> Contract { let code = self @@ -311,4 +323,14 @@ impl Contract> { .deploy(account, tx_policies) .await } + + pub async fn deploy_if_not_exists( + self, + account: &impl Account, + tx_policies: TxPolicies, + ) -> Result { + Contract::regular(self.code(), self.salt, self.storage_slots) + .deploy_if_not_exists(account, tx_policies) + .await + } } diff --git a/packages/fuels-programs/src/contract/regular.rs b/packages/fuels-programs/src/contract/regular.rs index 466092a1cd..4865e97b8f 100644 --- a/packages/fuels-programs/src/contract/regular.rs +++ b/packages/fuels-programs/src/contract/regular.rs @@ -169,6 +169,22 @@ impl Contract { Ok(contract_id.into()) } + /// Deploys a compiled contract to a running node if a contract with + /// the corresponding [`ContractId`] doesn't exist. + pub async fn deploy_if_not_exists( + self, + account: &impl Account, + tx_policies: TxPolicies, + ) -> Result { + let contract_id = Bech32ContractId::from(self.contract_id()); + let provider = account.try_provider()?; + if provider.contract_exists(&contract_id).await? { + Ok(contract_id) + } else { + self.deploy(account, tx_policies).await + } + } + /// Converts a regular contract into a loader contract, splitting the code into blobs. pub fn convert_to_loader( self,