TransportError(ErrorResp(ErrorPayload { code: -32000, message: \"already known\", data: None }))

alloy is used to send evm transactions. In the local environment, the transaction can be successfully sent, but on the main ICP network, a message is displayed indicating a TransportError(ErrorResp(ErrorPayload {code: -32000, message: "already known", data: None})), it seems to be because of the error caused by ICP consensus, please help me

se crate::types::{CHAIN_INFO, CONFIG_INFO};
use alloy::primitives::PrimitiveSignature;
use alloy::{
    network::EthereumWallet,
    primitives::{Address, Bytes, U256},
    providers::{Provider, ProviderBuilder},
    signers::local::PrivateKeySigner,
    sol,
    transports::icp::{IcpConfig, RpcApi, RpcService},
};
use common_utils::decrypt_keystore::{decrypt_keystore, get_private_key};
use common_utils::get_time;
use common_utils::types::PRIVATE_KEY_STORAGE;
use hex::FromHex;

sol!(
    #[allow(missing_docs, clippy::too_many_arguments)]
    #[sol(rpc)]
    MarketCapManager,
    "abi/abi.json"
);

pub async fn send_withdraw(
    cycle: u64,
    amount: u128,
    inter_nonce: u64,
    sign_time: u64,
    signature: String,
    swap_amount: u128,
) -> Result<String, String> {
    let private_key = get_private_key();
    let signer = private_key
        .parse::<PrivateKeySigner>()
        .map_err(|e| format!("Private key conversion error, {}", e))?;
    let address = signer.address();

    let wallet = EthereumWallet::from(signer);
    let chain_info = CHAIN_INFO.with(|chain| chain.borrow().get().clone());

    let rpc_service = RpcService::Custom(RpcApi {
        url: chain_info.chain_url.clone(),
        headers: None,
    });
    let config = IcpConfig::new(rpc_service);
    let provider = ProviderBuilder::new()
        .with_gas_estimation()
        .wallet(wallet)
        .on_icp(config);

    let contract_address: Address = chain_info
        .contract_address
        .parse()
        .map_err(|e| format!("Invalid contract address: {}", e))?;
    let contract = MarketCapManager::new(contract_address, provider.clone());

    let signature_bytes = match Vec::from_hex(&signature) {
        Ok(bytes) => bytes,
        Err(e) => return Err(format!("Invalid signature hex: {}", e)),
    };

    let result = provider.get_transaction_count(address).await;
    let nonce = match result {
        Ok(n) => n,
        Err(e) => {
            return Err(format!("Description Failed to obtain the nonce, {}", e));
        }
    };

    //first withdraw -> swap
    match contract
        .withdrawFromMiningPool(
            U256::from(cycle),
            U256::from(amount),
            U256::from(inter_nonce),
            U256::from(sign_time),
            Bytes::from(signature_bytes.clone()),
            U256::from(swap_amount),
        )
        .nonce(nonce)
        .chain_id(chain_info.chain_id)
        .from(address)
        .gas_price(3000000000)
        .send()
        .await
    {
        Ok(builder) => {
            let node_hash = *builder.tx_hash();
            let tx_response = provider.get_transaction_by_hash(node_hash).await.unwrap();

            match tx_response {
                Some(tx) => return Ok(format!("The 1 task is successfully, {}", tx.hash)),
                None => return Err(format!(
                    "The 1 task failed, could not get transaction, {}",
                    node_hash
                )),
            }
        },
        Err(e) => {
            return Err(format!(
                "The 1 task failed, could not send transaction, {:?}",
                e
            ));
        }
    };
    Err("The 1 task exception error".to_string())
}
1 Like