Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly handle Input::Message when calling msg_sender() #6231

Merged
merged 7 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions sway-lib-std/src/auth.sw
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -151,7 +158,20 @@ pub fn caller_address() -> Result<Address, AuthError> {
}

// 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ 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<Identity, AuthError> = msg_sender();
let mut ret = false;
if result.is_err() {
ret = false;
}
let unwrapped = result.unwrap();
match unwrapped {
Identity::Address(_) => {
ret = true
Identity::Address(address) => {
ret = expected_id == address
},
_ => {
ret = false
Expand Down
62 changes: 62 additions & 0 deletions test/src/sdk-harness/test_projects/auth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use fuels::{
coin::{Coin, CoinStatus},
message::{Message, MessageStatus},
Bytes32, ContractId,
coin_type::CoinType,
input::Input,
},
};
use std::str::FromStr;
Expand Down Expand Up @@ -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<WalletUnlocked>,
ContractId,
Expand Down
Loading