Skip to content

Commit

Permalink
feat: add check to ignore already executed messages
Browse files Browse the repository at this point in the history
Signed-off-by: Guilherme Felipe da Silva <[email protected]>
  • Loading branch information
frenzox committed Jan 7, 2025
1 parent 38cd956 commit 9fa9b33
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion crates/solana-gateway-task-processor/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ use axelar_solana_encoding::borsh::BorshDeserialize as _;
use axelar_solana_encoding::types::execute_data::{ExecuteData, MerkleisedPayload};
use axelar_solana_encoding::types::messages::{CrossChainId, Message};
use axelar_solana_gateway::error::GatewayError;
use axelar_solana_gateway::state::incoming_message::command_id;
use axelar_solana_gateway::state::incoming_message::{command_id, IncomingMessage, MessageStatus};
use axelar_solana_gateway::BytemuckedPda as _;
use effective_tx_sender::ComputeBudgetError;
use eyre::{Context as _, OptionExt as _};
use futures::stream::{FusedStream as _, FuturesOrdered, FuturesUnordered};
Expand Down Expand Up @@ -342,6 +343,11 @@ async fn execute_task(
let (gateway_incoming_message_pda, ..) =
axelar_solana_gateway::get_incoming_message_pda(&command_id);

if incoming_message_already_executed(solana_rpc_client, &gateway_incoming_message_pda).await? {
tracing::warn!("incoming message already executed");
return Ok(());
}

// Upload the message payload to a Gateway-owned PDA account and get its address back.
let gateway_message_payload_pda = message_payload::upload(
solana_rpc_client,
Expand Down Expand Up @@ -398,6 +404,20 @@ async fn execute_task(
Ok(())
}

/// Checks if the incoming message has already been executed.
async fn incoming_message_already_executed(
solana_rpc_client: &RpcClient,
incoming_message_pda: &Pubkey,
) -> eyre::Result<bool> {
let raw_incoming_message = solana_rpc_client
.get_account_data(incoming_message_pda)
.await?;
let incoming_message = IncomingMessage::read(&raw_incoming_message)
.ok_or_eyre("failed to read incoming message")?;

Ok(incoming_message.status == MessageStatus::Executed)
}

/// Validates that the relayer's signing account is not included in the transaction payload.
///
/// This is a critical security check to prevent potential account draining attacks. Since the
Expand Down

0 comments on commit 9fa9b33

Please sign in to comment.