From f82d9e67c2a81e600ae61a86dd1a7c905facf6c5 Mon Sep 17 00:00:00 2001 From: Cameron Carstens Date: Tue, 9 Jul 2024 19:40:56 +0800 Subject: [PATCH] Correctly handle `Input::Message` when calling `msg_sender()` (#6231) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description When the input type was of `Input::Message` and the `msg_sender()` function was called, it would revert. It now properly handle `Input::Message`. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Kaya Gökalp Co-authored-by: SwayStar123 <46050679+SwayStar123@users.noreply.github.com> --- sway-lib-std/src/auth.sw | 24 ++++++- .../auth_testing_contract/src/main.sw | 6 +- .../src/sdk-harness/test_projects/auth/mod.rs | 62 +++++++++++++++++++ 3 files changed, 87 insertions(+), 5 deletions(-) diff --git a/sway-lib-std/src/auth.sw b/sway-lib-std/src/auth.sw index cb85965da5e..4551a8ca7d7 100644 --- a/sway-lib-std/src/auth.sw +++ b/sway-lib-std/src/auth.sw @@ -6,7 +6,14 @@ use ::contract_id::ContractId; use ::identity::Identity; use ::option::Option::{self, *}; use ::result::Result::{self, *}; -use ::inputs::{Input, input_coin_owner, input_count, input_message_recipient, input_type}; +use ::inputs::{ + Input, + input_coin_owner, + input_count, + input_message_recipient, + input_message_sender, + input_type, +}; use ::revert::revert; /// The error type used when an `Identity` cannot be determined. @@ -151,7 +158,20 @@ pub fn caller_address() -> Result { } // type == InputCoin or InputMessage. - let owner_of_input = input_coin_owner(i.as_u64()); + let owner_of_input = match type_of_input { + Input::Coin => { + input_coin_owner(i.as_u64()) + }, + Input::Message => { + Some(input_message_sender(i.as_u64())) + }, + _ => { + // type != InputCoin or InputMessage, continue looping. + i += 1u16; + continue; + } + }; + if candidate.is_none() { // This is the first input seen of the correct type. candidate = owner_of_input; diff --git a/test/src/sdk-harness/test_artifacts/auth_testing_contract/src/main.sw b/test/src/sdk-harness/test_artifacts/auth_testing_contract/src/main.sw index c49a0540b15..4fd51ea5edc 100644 --- a/test/src/sdk-harness/test_artifacts/auth_testing_contract/src/main.sw +++ b/test/src/sdk-harness/test_artifacts/auth_testing_contract/src/main.sw @@ -26,7 +26,7 @@ impl AuthTesting for Contract { ret } - fn returns_msg_sender_address(_expected_id: Address) -> bool { + fn returns_msg_sender_address(expected_id: Address) -> bool { let result: Result = msg_sender(); let mut ret = false; if result.is_err() { @@ -34,8 +34,8 @@ impl AuthTesting for Contract { } let unwrapped = result.unwrap(); match unwrapped { - Identity::Address(_) => { - ret = true + Identity::Address(address) => { + ret = expected_id == address }, _ => { ret = false diff --git a/test/src/sdk-harness/test_projects/auth/mod.rs b/test/src/sdk-harness/test_projects/auth/mod.rs index 5672e77b7b4..172bce95282 100644 --- a/test/src/sdk-harness/test_projects/auth/mod.rs +++ b/test/src/sdk-harness/test_projects/auth/mod.rs @@ -9,6 +9,8 @@ use fuels::{ coin::{Coin, CoinStatus}, message::{Message, MessageStatus}, Bytes32, ContractId, + coin_type::CoinType, + input::Input, }, }; use std::str::FromStr; @@ -69,6 +71,66 @@ async fn msg_sender_from_contract() { assert!(result.value); } +#[tokio::test] +async fn input_message_msg_sender_from_contract() { + // Wallet + let mut wallet = WalletUnlocked::new_random(None); + + // Setup coins and messages + let coins = setup_single_asset_coins(wallet.address(), AssetId::BASE, 100, 1000); + let msg = setup_single_message( + &Bech32Address { + hrp: "".to_string(), + hash: Default::default(), + }, + wallet.address(), + DEFAULT_COIN_AMOUNT, + 10.into(), + vec![], + ); + + let provider = setup_test_provider(coins.clone(), vec![msg.clone()], None, None) + .await + .unwrap(); + wallet.set_provider(provider.clone()); + + // Setup contract + let id = Contract::load_from( + "test_artifacts/auth_testing_contract/out/release/auth_testing_contract.bin", + LoadConfiguration::default(), + ) + .unwrap() + .deploy(&wallet, TxPolicies::default()) + .await + .unwrap(); + let instance = AuthContract::new(id.clone(), wallet.clone()); + + // Start building transactions + let call_handler = instance.methods().returns_msg_sender_address(Address::from(*msg.sender.hash())); + let mut tb = call_handler.transaction_builder().await.unwrap(); + + // Inputs + tb.inputs_mut().push(Input::ResourceSigned { + resource: CoinType::Message(wallet + .get_messages() + .await + .unwrap() + .first() + .unwrap() + .clone()), + }); + + // Build transaction + tb.add_signer(wallet.clone()).unwrap(); + let tx = tb.build(provider.clone()).await.unwrap(); + + // Send and verify + let tx_id = provider.send_transaction(tx).await.unwrap(); + let tx_status = provider.tx_status(&tx_id).await.unwrap(); + let response = call_handler.get_response_from(tx_status).unwrap(); + assert!(response.value); +} + async fn get_contracts() -> ( AuthContract, ContractId,