--- a/crates/evm-coder/src/abi/impls.rs +++ b/crates/evm-coder/src/abi/impls.rs @@ -181,11 +181,6 @@ } } -macro_rules! count { - () => (0usize); - ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*)); -} - macro_rules! impl_tuples { ($($ident:ident)+) => { impl<$($ident: AbiType,)+> AbiType for ($($ident,)+) --- a/pallets/common/src/eth.rs +++ b/pallets/common/src/eth.rs @@ -122,6 +122,13 @@ } } +/// Ethereum representation of Optional value with CrossAddress. +#[derive(Debug, Default, AbiCoder)] +pub struct OptionCrossAddress { + pub status: bool, + pub value: CrossAddress, +} + /// Cross account struct #[derive(Debug, Default, AbiCoder)] pub struct CrossAddress { --- a/pallets/evm-contract-helpers/src/eth.rs +++ b/pallets/evm-contract-helpers/src/eth.rs @@ -25,6 +25,7 @@ types::*, ToLog, }; +use pallet_common::eth; use pallet_evm::{ ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure, PrecompileHandle, account::CrossAccountId, @@ -174,12 +175,17 @@ /// /// @param contractAddress The contract for which a sponsor is requested. /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw. - fn sponsor(&self, contract_address: address) -> Result { - Ok( - pallet_common::eth::CrossAddress::from_sub_cross_account::( - &Pallet::::get_sponsor(contract_address).ok_or("Contract has no sponsor")?, - ), - ) + fn sponsor(&self, contract_address: address) -> Result { + Ok(match Pallet::::get_sponsor(contract_address) { + Some(ref value) => eth::OptionCrossAddress { + status: true, + value: eth::CrossAddress::from_sub_cross_account::(value), + }, + None => eth::OptionCrossAddress { + status: false, + value: Default::default(), + }, + }) } /// Check tat contract has confirmed sponsor. --- a/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol +++ b/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol @@ -96,11 +96,11 @@ /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw. /// @dev EVM selector for this function is: 0x766c4f37, /// or in textual repr: sponsor(address) - function sponsor(address contractAddress) public view returns (CrossAddress memory) { + function sponsor(address contractAddress) public view returns (OptionCrossAddress memory) { require(false, stub_error); contractAddress; dummy; - return CrossAddress(0x0000000000000000000000000000000000000000, 0); + return OptionCrossAddress(false, CrossAddress(0x0000000000000000000000000000000000000000, 0)); } /// Check tat contract has confirmed sponsor. @@ -270,3 +270,9 @@ address eth; uint256 sub; } + +/// @dev Ethereum representation of Optional value with CrossAddress. +struct OptionCrossAddress { + bool status; + CrossAddress value; +} --- a/pallets/unique/src/lib.rs +++ b/pallets/unique/src/lib.rs @@ -74,7 +74,7 @@ extern crate alloc; use frame_support::{ - decl_module, decl_storage, decl_error, decl_event, + decl_module, decl_storage, decl_error, dispatch::DispatchResult, ensure, fail, weights::{Weight}, --- a/tests/src/eth/abi/contractHelpers.json +++ b/tests/src/eth/abi/contractHelpers.json @@ -223,10 +223,18 @@ "outputs": [ { "components": [ - { "internalType": "address", "name": "eth", "type": "address" }, - { "internalType": "uint256", "name": "sub", "type": "uint256" } + { "internalType": "bool", "name": "status", "type": "bool" }, + { + "components": [ + { "internalType": "address", "name": "eth", "type": "address" }, + { "internalType": "uint256", "name": "sub", "type": "uint256" } + ], + "internalType": "struct CrossAddress", + "name": "value", + "type": "tuple" + } ], - "internalType": "struct CrossAddress", + "internalType": "struct OptionCrossAddress", "name": "", "type": "tuple" } --- a/tests/src/eth/api/ContractHelpers.sol +++ b/tests/src/eth/api/ContractHelpers.sol @@ -69,7 +69,7 @@ /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw. /// @dev EVM selector for this function is: 0x766c4f37, /// or in textual repr: sponsor(address) - function sponsor(address contractAddress) external view returns (CrossAddress memory); + function sponsor(address contractAddress) external view returns (OptionCrossAddress memory); /// Check tat contract has confirmed sponsor. /// @@ -171,6 +171,12 @@ function toggleAllowlist(address contractAddress, bool enabled) external; } +/// @dev Ethereum representation of Optional value with CrossAddress. +struct OptionCrossAddress { + bool status; + CrossAddress value; +} + /// @dev Cross account struct struct CrossAddress { address eth; --- a/tests/src/eth/contractSponsoring.test.ts +++ b/tests/src/eth/contractSponsoring.test.ts @@ -42,7 +42,9 @@ expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true; // 1.1 Can get sponsor using methods.sponsor: - const actualSponsor = await helpers.methods.sponsor(flipper.options.address).call(); + const actualSponsorOpt = await helpers.methods.sponsor(flipper.options.address).call(); + expect(actualSponsorOpt.status).to.be.true; + const actualSponsor = actualSponsorOpt.value; expect(actualSponsor.eth).to.eq(flipper.options.address); expect(actualSponsor.sub).to.eq('0'); @@ -151,7 +153,9 @@ expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true; // 1.1 Can get sponsor using methods.sponsor: - const actualSponsor = await helpers.methods.sponsor(flipper.options.address).call(); + const actualSponsorOpt = await helpers.methods.sponsor(flipper.options.address).call(); + expect(actualSponsorOpt.status).to.be.true; + const actualSponsor = actualSponsorOpt.value; expect(actualSponsor.eth).to.eq(sponsor); expect(actualSponsor.sub).to.eq('0');