Skip to content

Commit c27bd5a

Browse files
committed
Add bincode dependency and enhance Solana transaction handling
- Added `bincode` as a dependency in the Cargo.toml for the executors. - Updated the SolanaExecutorJobHandler to handle serialized transactions with existing signatures more robustly, preventing retries that would invalidate signatures when the blockhash expires.
1 parent 614fb50 commit c27bd5a

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

executors/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ edition = "2024"
66
[dependencies]
77
hex = { workspace = true }
88
alloy = { workspace = true, features = ["serde"] }
9+
bincode = { workspace = true, features = ["serde"] }
910
thirdweb-core = { version = "0.1.0", path = "../thirdweb-core" }
1011
hmac = { workspace = true }
1112
reqwest = { workspace = true }

executors/src/solana_executor/worker.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,39 @@ impl SolanaExecutorJobHandler {
597597
.nack(Some(CONFIRMATION_RETRY_DELAY), RequeuePosition::Last));
598598
}
599599
Ok(false) => {
600-
// Blockhash expired, need to resubmit
600+
// Blockhash expired
601+
602+
// For serialized transactions with existing signatures, we cannot retry with a new blockhash
603+
// because the signatures will become invalid. Check if there are any non-default signatures.
604+
if let engine_solana_core::transaction::SolanaTransactionInput::Serialized { transaction } = &job_data.transaction.input {
605+
// Deserialize the base64 transaction to check for signatures
606+
if let Ok(tx_bytes) = base64::engine::general_purpose::STANDARD.decode(transaction)
607+
&& let Ok((versioned_tx, _)) = bincode::serde::decode_from_slice::<solana_sdk::transaction::VersionedTransaction, _>(
608+
&tx_bytes,
609+
bincode::config::standard()
610+
) {
611+
// Check if any signatures are non-default (not all zeros)
612+
let has_signatures = versioned_tx.signatures.iter().any(|sig| {
613+
sig.as_ref() != [0u8; 64]
614+
});
615+
616+
if has_signatures {
617+
error!(
618+
transaction_id = %transaction_id,
619+
signature = %signature,
620+
"Blockhash expired for serialized transaction with existing signatures - cannot retry without invalidating them"
621+
);
622+
let _ = self.storage.delete_attempt(transaction_id).await;
623+
return Err(SolanaExecutorError::TransactionFailed {
624+
reason: "Blockhash expired for serialized transaction with existing signatures. Retrying with a new blockhash would invalidate them.".to_string(),
625+
}
626+
.fail());
627+
}
628+
// If no signatures, we can retry - will be signed during execution
629+
}
630+
}
631+
632+
// For instruction-based transactions or serialized without signatures, we can retry with a new blockhash
601633
warn!(
602634
transaction_id = %transaction_id,
603635
signature = %signature,

0 commit comments

Comments
 (0)