From 65a4cc49522eee26070493e87b84bd12a1814242 Mon Sep 17 00:00:00 2001 From: Raymond Yeh Date: Sun, 28 Aug 2022 17:30:57 +0000 Subject: [PATCH] test: implment flipper, issue666, msg_sender, primitives tests Signed-off-by: Raymond Yeh --- integration/subxt-tests/Cargo.toml | 1 + integration/subxt-tests/src/cases/flipper.rs | 69 +- integration/subxt-tests/src/cases/issue666.rs | 62 +- integration/subxt-tests/src/cases/mod.rs | 1 + .../subxt-tests/src/cases/msg_sender.rs | 86 ++- .../subxt-tests/src/cases/primitives.rs | 652 +++++++++++++++++- 6 files changed, 867 insertions(+), 4 deletions(-) diff --git a/integration/subxt-tests/Cargo.toml b/integration/subxt-tests/Cargo.toml index 57d1d61e0..aa6ef6a6b 100644 --- a/integration/subxt-tests/Cargo.toml +++ b/integration/subxt-tests/Cargo.toml @@ -12,6 +12,7 @@ contract-metadata = "1.5.0" contract-transcode = "0.1.0" hex = "0.4.3" ink_metadata = "3.3.1" +num-bigint = "0.4.3" pallet-contracts-primitives = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27"} parity-scale-codec = "3.1.5" rand = "0.8.5" diff --git a/integration/subxt-tests/src/cases/flipper.rs b/integration/subxt-tests/src/cases/flipper.rs index 94259d15e..3c577ca1a 100644 --- a/integration/subxt-tests/src/cases/flipper.rs +++ b/integration/subxt-tests/src/cases/flipper.rs @@ -1,4 +1,71 @@ +use parity_scale_codec::{Decode, Encode}; +use sp_core::hexdisplay::AsBytesRef; + +use crate::{build_selector, DeployContract, Execution, ReadContract, WriteContract, API}; + #[tokio::test] async fn case() -> anyhow::Result<()> { - unimplemented!(); + let api = API::new().await?; + + let code = std::fs::read("./contracts/flipper.wasm")?; + + let selector = build_selector( + "f81e7e1a", + Some(&mut |s| { + true.encode_to(s); + }), + )?; + + let contract = DeployContract { + caller: sp_keyring::AccountKeyring::Alice, + selector, + value: 0, + code, + } + .execute(&api) + .await?; + + // get value + let selector = build_selector("6d4ce63c", None)?; + + let init_value = ReadContract { + caller: sp_keyring::AccountKeyring::Alice, + contract_address: contract.contract_address.clone(), + value: 0, + selector, + } + .execute(&api) + .await + .and_then(|v| ::decode(&mut v.return_value.as_bytes_ref()).map_err(Into::into))?; + + assert!(init_value); + + // flip flipper + let selector = build_selector("cde4efa9", None)?; + + WriteContract { + caller: sp_keyring::AccountKeyring::Alice, + contract_address: contract.contract_address.clone(), + selector, + value: 0, + } + .execute(&api) + .await?; + + // get value + let selector = build_selector("6d4ce63c", None)?; + + let value = ReadContract { + caller: sp_keyring::AccountKeyring::Alice, + contract_address: contract.contract_address.clone(), + value: 0, + selector, + } + .execute(&api) + .await + .and_then(|v| ::decode(&mut v.return_value.as_bytes_ref()).map_err(Into::into))?; + + assert!(!value); + + Ok(()) } diff --git a/integration/subxt-tests/src/cases/issue666.rs b/integration/subxt-tests/src/cases/issue666.rs index 94259d15e..2acee0702 100644 --- a/integration/subxt-tests/src/cases/issue666.rs +++ b/integration/subxt-tests/src/cases/issue666.rs @@ -1,4 +1,64 @@ +use parity_scale_codec::Encode; + +use crate::{build_selector, DeployContract, Execution, WriteContract, API}; + #[tokio::test] async fn case() -> anyhow::Result<()> { - unimplemented!(); + let api = API::new().await?; + + let flipper_code = std::fs::read("./contracts/Flip.wasm")?; + let inc_code = std::fs::read("./contracts/Inc.wasm")?; + + let selector = build_selector("861731d5", None)?; + + let flipper = DeployContract { + caller: sp_keyring::AccountKeyring::Alice, + selector, + value: 0, + code: flipper_code, + } + .execute(&api) + .await?; + + // flip on Flip + let selector = build_selector("cde4efa9", None)?; + + WriteContract { + caller: sp_keyring::AccountKeyring::Alice, + contract_address: flipper.contract_address.clone(), + selector, + value: 0, + } + .execute(&api) + .await?; + + let selector = build_selector( + "45fd0674", + Some(&mut |s| { + flipper.contract_address.encode_to(s); + }), + )?; + + let inc = DeployContract { + caller: sp_keyring::AccountKeyring::Alice, + selector, + value: 0, + code: inc_code, + } + .execute(&api) + .await?; + + // superFlip on Inc + let selector = build_selector("cc69915f", None)?; + + WriteContract { + caller: sp_keyring::AccountKeyring::Alice, + contract_address: inc.contract_address.clone(), + selector, + value: 0, + } + .execute(&api) + .await?; + + Ok(()) } diff --git a/integration/subxt-tests/src/cases/mod.rs b/integration/subxt-tests/src/cases/mod.rs index 69d8ea2c5..b585697d1 100644 --- a/integration/subxt-tests/src/cases/mod.rs +++ b/integration/subxt-tests/src/cases/mod.rs @@ -6,6 +6,7 @@ mod create_contract; mod destruct; mod events; mod external_call; +mod flipper; mod issue666; mod msg_sender; mod primitives; diff --git a/integration/subxt-tests/src/cases/msg_sender.rs b/integration/subxt-tests/src/cases/msg_sender.rs index 94259d15e..ed6d3c3af 100644 --- a/integration/subxt-tests/src/cases/msg_sender.rs +++ b/integration/subxt-tests/src/cases/msg_sender.rs @@ -1,4 +1,88 @@ +use parity_scale_codec::{Decode, Encode, Input}; +use sp_core::{crypto::AccountId32, hexdisplay::AsBytesRef}; + +use crate::{build_selector, DeployContract, Execution, ReadContract, WriteContract, API}; + #[tokio::test] async fn case() -> anyhow::Result<()> { - unimplemented!(); + let api = API::new().await?; + + // mytoken + let mytoken_code = std::fs::read("./contracts/mytoken.wasm")?; + let mytoken_event_code = std::fs::read("./contracts/mytokenEvent.wasm")?; + + let selector = build_selector("861731d5", None)?; + + let mytoken = DeployContract { + caller: sp_keyring::AccountKeyring::Alice, + selector, + value: 0, + code: mytoken_code, + } + .execute(&api) + .await?; + + // read test + let selector = build_selector( + "ceff345b", + Some(&mut |s| { + sp_keyring::AccountKeyring::Alice + .to_account_id() + .encode_to(s); + + true.encode_to(s); + }), + )?; + + let addr = ReadContract { + caller: sp_keyring::AccountKeyring::Alice, + contract_address: mytoken.contract_address.clone(), + value: 0, + selector, + } + .execute(&api) + .await + .and_then(|v| ::decode(&mut v.return_value.as_bytes_ref()).map_err(Into::into))?; + + assert_eq!(addr, sp_keyring::AccountKeyring::Alice.to_account_id()); + + // mytokenEvent + let selector = build_selector("861731d5", None)?; + + let mytoken_event = DeployContract { + caller: sp_keyring::AccountKeyring::Alice, + selector, + value: 0, + code: mytoken_event_code, + } + .execute(&api) + .await?; + + // call test + let selector = build_selector("f8a8fd6d", None)?; + + let output = WriteContract { + caller: sp_keyring::AccountKeyring::Alice, + contract_address: mytoken_event.contract_address.clone(), + selector, + value: 0, + } + .execute(&api) + .await?; + + assert_eq!(output.events.len(), 1); + + let evt = &output.events[0]; + + let mut evt_buffer = evt.data.as_slice(); + + let topic_id = evt_buffer.read_byte()?; + + assert_eq!(topic_id, 0); + + let addr = ::decode(&mut evt_buffer)?; + + assert_eq!(addr, sp_keyring::AccountKeyring::Alice.to_account_id()); + + Ok(()) } diff --git a/integration/subxt-tests/src/cases/primitives.rs b/integration/subxt-tests/src/cases/primitives.rs index 94259d15e..93e1c9088 100644 --- a/integration/subxt-tests/src/cases/primitives.rs +++ b/integration/subxt-tests/src/cases/primitives.rs @@ -1,4 +1,654 @@ +use std::{ops::BitOr, str::FromStr}; + +use hex::FromHex; +use num_bigint::{BigInt, BigUint, Sign}; +use parity_scale_codec::{Decode, Encode, Input}; +use sp_core::{crypto::AccountId32, hexdisplay::AsBytesRef, H256, U256}; +use subxt::ext::sp_runtime::{traits::One, MultiAddress}; + +use crate::{build_selector, DeployContract, Execution, ReadContract, WriteContract, API}; + +async fn query(api: &API, addr: &AccountId32, selector: &[u8]) -> anyhow::Result { + ReadContract { + caller: sp_keyring::AccountKeyring::Alice, + contract_address: addr.clone(), + value: 0, + selector: selector.to_vec(), + } + .execute(api) + .await + .and_then(|v| T::decode(&mut v.return_value.as_bytes_ref()).map_err(Into::into)) +} + #[tokio::test] async fn case() -> anyhow::Result<()> { - unimplemented!(); + let api = API::new().await?; + let code = std::fs::read("./contracts/primitives.wasm")?; + + let selector = build_selector("861731d5", None)?; + + let contract = DeployContract { + caller: sp_keyring::AccountKeyring::Alice, + selector, + value: 0, + code, + } + .execute(&api) + .await?; + + // test res + + #[derive(Encode, Decode)] + enum oper { + add, + sub, + mul, + div, + r#mod, + pow, + shl, + shr, + or, + and, + xor, + } + + let selector = build_selector( + "4df68232", + Some(&mut |s| { + oper::mul.encode_to(s); + }), + )?; + + let is_mul = query::(&api, &contract.contract_address, &selector).await?; + assert!(is_mul); + + let selector = build_selector("29eebbd6", None)?; + + let return_div = query::(&api, &contract.contract_address, &selector).await?; + if let oper::div = return_div { + } else { + panic!("not div"); + } + + let selector = build_selector( + "df3fd4a5", + Some(&mut |s| { + oper::add.encode_to(s); + 1000_i64.encode_to(s); + 4100_i64.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, 5100); + + let selector = build_selector( + "df3fd4a5", + Some(&mut |s| { + oper::sub.encode_to(s); + 1000_i64.encode_to(s); + 4100_i64.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, -3100); + + let selector = build_selector( + "df3fd4a5", + Some(&mut |s| { + oper::mul.encode_to(s); + 1000_i64.encode_to(s); + 4100_i64.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, 4100000); + + let selector = build_selector( + "df3fd4a5", + Some(&mut |s| { + oper::div.encode_to(s); + 1000_i64.encode_to(s); + 10_i64.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, 100); + + let selector = build_selector( + "df3fd4a5", + Some(&mut |s| { + oper::r#mod.encode_to(s); + 1000_i64.encode_to(s); + 99_i64.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, 10); + + let selector = build_selector( + "df3fd4a5", + Some(&mut |s| { + oper::shl.encode_to(s); + (-1000_i64).encode_to(s); + 8_i64.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, -256000); + + let selector = build_selector( + "df3fd4a5", + Some(&mut |s| { + oper::shr.encode_to(s); + (-1000_i64).encode_to(s); + 8_i64.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, -4); + + // op_u64 + let selector = build_selector( + "1582ed95", + Some(&mut |s| { + oper::add.encode_to(s); + 1000_u64.encode_to(s); + 4100_u64.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, 5100); + + let selector = build_selector( + "1582ed95", + Some(&mut |s| { + oper::sub.encode_to(s); + 1000_u64.encode_to(s); + 4100_u64.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, 18446744073709548516); + + let selector = build_selector( + "1582ed95", + Some(&mut |s| { + oper::mul.encode_to(s); + 123456789_u64.encode_to(s); + 123456789_u64.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, 15241578750190521); + + let selector = build_selector( + "1582ed95", + Some(&mut |s| { + oper::div.encode_to(s); + 123456789_u64.encode_to(s); + 100_u64.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, 1234567); + + let selector = build_selector( + "1582ed95", + Some(&mut |s| { + oper::r#mod.encode_to(s); + 123456789_u64.encode_to(s); + 100_u64.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, 89); + + let selector = build_selector( + "1582ed95", + Some(&mut |s| { + oper::pow.encode_to(s); + 3_u64.encode_to(s); + 7_u64.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, 2187); + + let selector = build_selector( + "1582ed95", + Some(&mut |s| { + oper::shl.encode_to(s); + 1000_u64.encode_to(s); + 8_u64.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, 256000); + + let selector = build_selector( + "1582ed95", + Some(&mut |s| { + oper::shr.encode_to(s); + 1000_u64.encode_to(s); + 8_u64.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, 3); + + // op_i256 + let selector = build_selector( + "d6435f25", + Some(&mut |s| { + oper::add.encode_to(s); + U256::from(1000_u128).encode_to(s); + U256::from(4100_u128).encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!(res, U256::from(5100_u128)); + + let selector = build_selector( + "d6435f25", + Some(&mut |s| { + oper::sub.encode_to(s); + U256::from(1000_u128).encode_to(s); + U256::from(4100_u128).encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + // use two's compliment to get negative value in + assert_eq!(res, !U256::from(3100_u128) + U256::one()); + + let selector = build_selector( + "d6435f25", + Some(&mut |s| { + oper::mul.encode_to(s); + U256::from(1000_u128).encode_to(s); + U256::from(4100_u128).encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!(res, U256::from_dec_str("4100000")?); + + let selector = build_selector( + "d6435f25", + Some(&mut |s| { + oper::div.encode_to(s); + U256::from(1000_u128).encode_to(s); + U256::from(10_u128).encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!(res, U256::from_dec_str("100")?); + + let selector = build_selector( + "d6435f25", + Some(&mut |s| { + oper::r#mod.encode_to(s); + U256::from(1000_u128).encode_to(s); + U256::from(99_u128).encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!(res, U256::from_dec_str("10")?); + + let selector = build_selector( + "d6435f25", + Some(&mut |s| { + oper::shl.encode_to(s); + (!U256::from_dec_str("10000000000000").unwrap() + U256::one()).encode_to(s); + U256::from(8_u128).encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!(res, !U256::from_dec_str("2560000000000000")? + U256::one()); + + let selector = build_selector( + "d6435f25", + Some(&mut |s| { + oper::shr.encode_to(s); + (!U256::from_dec_str("10000000000000").unwrap() + U256::one()).encode_to(s); + U256::from(8_u128).encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + assert_eq!(res, !U256::from(39062500000_i64) + U256::one()); + + // op_u256 + let selector = build_selector( + "b446eacd", + Some(&mut |s| { + oper::add.encode_to(s); + U256::from(1000_u128).encode_to(s); + U256::from(4100_u128).encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!(res, U256::from(5100_u128)); + + let selector = build_selector( + "b446eacd", + Some(&mut |s| { + oper::sub.encode_to(s); + U256::from(1000_u128).encode_to(s); + U256::from(4100_u128).encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!(res, !U256::from(3100_u128) + U256::one()); + + let selector = build_selector( + "b446eacd", + Some(&mut |s| { + oper::mul.encode_to(s); + U256::from(123456789_u128).encode_to(s); + U256::from(123456789_u128).encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!(res, U256::from(15241578750190521_u128)); + + let selector = build_selector( + "b446eacd", + Some(&mut |s| { + oper::div.encode_to(s); + U256::from(123456789_u128).encode_to(s); + U256::from(100_u128).encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!(res, U256::from(1234567_u128)); + + let selector = build_selector( + "b446eacd", + Some(&mut |s| { + oper::r#mod.encode_to(s); + U256::from(123456789_u128).encode_to(s); + U256::from(100_u128).encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!(res, U256::from(89_u64)); + + let selector = build_selector( + "b446eacd", + Some(&mut |s| { + oper::pow.encode_to(s); + U256::from(123456789_u128).encode_to(s); + U256::from(9_u128).encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!( + res.to_string(), + "6662462759719942007440037531362779472290810125440036903063319585255179509" + ); + + let selector = build_selector( + "b446eacd", + Some(&mut |s| { + oper::shl.encode_to(s); + U256::from(10000000000000_u128).encode_to(s); + U256::from(8_u128).encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!(res, U256::from(2560000000000000_u128)); + + let selector = build_selector( + "b446eacd", + Some(&mut |s| { + oper::shr.encode_to(s); + U256::from(10000000000000_u128).encode_to(s); + U256::from(8_u128).encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!(res, U256::from(39062500000_u128)); + + // test bytesN + let selector = build_selector("6233b7a0", None)?; + + let res = query::<[u8; 6]>(&api, &contract.contract_address, &selector).await?; + + assert_eq!(hex::encode(res), "414243444546"); + + // test bytesS + let selector = build_selector( + "42067d4a", + Some(&mut |s| { + oper::shl.encode_to(s); + <[u8; 5]>::from_hex("deadcafe59").unwrap().encode_to(s); + 8_u64.encode_to(s); + }), + )?; + + let res = query::<[u8; 5]>(&api, &contract.contract_address, &selector).await?; + + assert_eq!(hex::encode(res), "adcafe5900"); + + let selector = build_selector( + "42067d4a", + Some(&mut |s| { + oper::shr.encode_to(s); + <[u8; 5]>::from_hex("deadcafe59").unwrap().encode_to(s); + 8_u64.encode_to(s); + }), + )?; + + let res = query::<[u8; 5]>(&api, &contract.contract_address, &selector).await?; + + assert_eq!(hex::encode(res), "00deadcafe"); + + // opU85 + let selector = build_selector( + "2cd64c02", + Some(&mut |s| { + oper::or.encode_to(s); + <[u8; 5]>::from_hex("deadcafe59").unwrap().encode_to(s); + <[u8; 5]>::from_hex("0000000006").unwrap().encode_to(s); + }), + )?; + + let res = query::<[u8; 5]>(&api, &contract.contract_address, &selector).await?; + + assert_eq!(hex::encode(res), "deadcafe5f"); + + let selector = build_selector( + "2cd64c02", + Some(&mut |s| { + oper::and.encode_to(s); + <[u8; 5]>::from_hex("deadcafe59").unwrap().encode_to(s); + <[u8; 5]>::from_hex("00000000ff").unwrap().encode_to(s); + }), + )?; + + let res = query::<[u8; 5]>(&api, &contract.contract_address, &selector).await?; + + assert_eq!(hex::encode(res), "0000000059"); + + let selector = build_selector( + "2cd64c02", + Some(&mut |s| { + oper::xor.encode_to(s); + <[u8; 5]>::from_hex("deadcafe59").unwrap().encode_to(s); + <[u8; 5]>::from_hex("00000000ff").unwrap().encode_to(s); + }), + )?; + + let res = query::<[u8; 5]>(&api, &contract.contract_address, &selector).await?; + + assert_eq!(hex::encode(res), "deadcafea6"); + + // test bytes14 + let selector = build_selector( + "b04add4f", + Some(&mut |s| { + oper::shl.encode_to(s); + <[u8; 14]>::from_hex("deadcafe123456789abcdefbeef7") + .unwrap() + .encode_to(s); + 9_u64.encode_to(s); + }), + )?; + + let res = query::<[u8; 14]>(&api, &contract.contract_address, &selector).await?; + + assert_eq!(hex::encode(res), "5b95fc2468acf13579bdf7ddee00"); + + let selector = build_selector( + "b04add4f", + Some(&mut |s| { + oper::shr.encode_to(s); + <[u8; 14]>::from_hex("deadcafe123456789abcdefbeef7") + .unwrap() + .encode_to(s); + 9_u64.encode_to(s); + }), + )?; + + let res = query::<[u8; 14]>(&api, &contract.contract_address, &selector).await?; + + assert_eq!(hex::encode(res), "006f56e57f091a2b3c4d5e6f7df7"); + + let selector = build_selector( + "e2816d52", + Some(&mut |s| { + oper::or.encode_to(s); + <[u8; 14]>::from_hex("deadcafe123456789abcdefbeef7") + .unwrap() + .encode_to(s); + <[u8; 14]>::from_hex("0000060000000000000000000000") + .unwrap() + .encode_to(s); + }), + )?; + + let res = query::<[u8; 14]>(&api, &contract.contract_address, &selector).await?; + + assert_eq!(hex::encode(res), "deadcefe123456789abcdefbeef7"); + + let selector = build_selector( + "e2816d52", + Some(&mut |s| { + oper::and.encode_to(s); + <[u8; 14]>::from_hex("deadcafe123456789abcdefbeef7") + .unwrap() + .encode_to(s); + <[u8; 14]>::from_hex("000000000000000000ff00000000") + .unwrap() + .encode_to(s); + }), + )?; + + let res = query::<[u8; 14]>(&api, &contract.contract_address, &selector).await?; + + assert_eq!(hex::encode(res), "000000000000000000bc00000000"); + + let selector = build_selector( + "e2816d52", + Some(&mut |s| { + oper::xor.encode_to(s); + <[u8; 14]>::from_hex("deadcafe123456789abcdefbeef7") + .unwrap() + .encode_to(s); + <[u8; 14]>::from_hex("ff00000000000000000000000000") + .unwrap() + .encode_to(s); + }), + )?; + + let res = query::<[u8; 14]>(&api, &contract.contract_address, &selector).await?; + + assert_eq!(hex::encode(res), "21adcafe123456789abcdefbeef7"); + + // test addressPassthrough + + let default_acc = + AccountId32::from_str("5GBWmgdFAMqm8ZgAHGobqDqX6tjLxJhv53ygjNtaaAn3sjeZ").unwrap(); + + let selector = build_selector( + "ed36bc79", + Some(&mut |s| { + default_acc.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!(res, default_acc); + + let alice = sp_keyring::AccountKeyring::Alice.to_account_id(); + + let dave = sp_keyring::AccountKeyring::Dave.to_account_id(); + + let selector = build_selector( + "ed36bc79", + Some(&mut |s| { + alice.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!(res, alice); + + let selector = build_selector( + "ed36bc79", + Some(&mut |s| { + dave.encode_to(s); + }), + )?; + + let res = query::(&api, &contract.contract_address, &selector).await?; + + assert_eq!(res, dave); + + Ok(()) }