diff --git a/src/connector.rs b/src/connector.rs index fd4df0110..6db5a125a 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -8,7 +8,7 @@ use crate::deposit_event::*; use crate::engine::Engine; use crate::json::parse_json; use crate::prelude::*; -use crate::prover::validate_eth_address; +use crate::prover::{validate_eth_address, Proof}; use crate::storage::{self, EthConnectorStorageId, KeyPrefix}; #[cfg(feature = "log")] use alloc::format; @@ -181,7 +181,6 @@ impl EthConnectorContract { pub fn deposit(&self) { self.assert_not_paused(PAUSE_DEPOSIT); - use crate::prover::Proof; #[cfg(feature = "log")] sdk::log("[Deposit tokens]"); @@ -643,6 +642,11 @@ impl EthConnectorContract { sdk::storage_has_key(&self.used_event_key(key)) } + /// Checks whether the provided proof was already used + pub fn is_used_proof(&self, proof: Proof) -> bool { + self.check_used_event(&proof.get_key()) + } + /// Get Eth connector paused flags pub fn get_paused_flags(&self) -> PausedMask { self.get_paused() diff --git a/src/lib.rs b/src/lib.rs index eb4cb5364..ca8d4eeed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,8 +86,9 @@ mod contract { #[cfg(feature = "evm_bully")] use crate::parameters::{BeginBlockArgs, BeginChainArgs}; use crate::parameters::{ - ExpectUtf8, FunctionCallArgs, GetStorageAtArgs, InitCallArgs, NewCallArgs, - PauseEthConnectorCallArgs, SetContractDataCallArgs, TransferCallCallArgs, ViewCallArgs, + ExpectUtf8, FunctionCallArgs, GetStorageAtArgs, InitCallArgs, IsUsedProofCallArgs, + NewCallArgs, PauseEthConnectorCallArgs, SetContractDataCallArgs, TransferCallCallArgs, + ViewCallArgs, }; use crate::prelude::{Address, H256, U256}; use crate::sdk; @@ -401,6 +402,15 @@ mod contract { EthConnectorContract::get_instance().finish_deposit_near(); } + #[no_mangle] + pub extern "C" fn is_used_proof() { + let args = IsUsedProofCallArgs::try_from_slice(&sdk::read_input()).expect(ERR_FAILED_PARSE); + + let is_used_proof = EthConnectorContract::get_instance().is_used_proof(args.proof); + let res = is_used_proof.try_to_vec().unwrap(); + sdk::return_output(&res[..]); + } + #[no_mangle] pub extern "C" fn ft_total_supply() { EthConnectorContract::get_instance().ft_total_supply(); diff --git a/src/parameters.rs b/src/parameters.rs index 7b1831427..fc2d4c5f9 100644 --- a/src/parameters.rs +++ b/src/parameters.rs @@ -145,6 +145,14 @@ pub struct DepositCallArgs { pub relayer_eth_account: Option, } +/// Eth-connector isUsedProof arguments +#[cfg(feature = "engine")] +#[derive(BorshSerialize, BorshDeserialize)] +pub struct IsUsedProofCallArgs { + /// Proof data + pub proof: Proof, +} + /// withdraw result for eth-connector #[cfg(feature = "engine")] #[derive(BorshSerialize)] diff --git a/tests/test_connector.rs b/tests/test_connector.rs index d0e4bda26..9dcb8c255 100644 --- a/tests/test_connector.rs +++ b/tests/test_connector.rs @@ -68,6 +68,11 @@ pub struct WithdrawResult { pub eth_custodian_address: EthAddress, } +#[derive(BorshDeserialize, Debug)] +pub struct IsUsedProofResult { + pub is_used_proof: bool, +} + fn init(custodian_address: &str) -> (UserAccount, UserAccount) { let master_account = near_sdk_sim::init_simulator(None); let contract = init_contract(&master_account, CONTRACT_ACC, custodian_address); @@ -144,6 +149,35 @@ fn call_deposit_near(master_account: &UserAccount, contract: &str) -> Vec