Skip to content

Fix transaction decoding to support versioned transactions #94

Open
@amilz

Description

@amilz

decode_b64_transaction() currently uses legacy Transaction type for deserialization, which fails when trying to decode versioned transactions with some error like this:

Invalid transaction: Failed to deserialize transaction: invalid value: integer `2066803`, expected a value in the range [0, 65535]
// (or similar)

Versioned transactions have a different serialization format that includes version information. The legacy Transaction type cannot deserialize versioned transactions - it expects the old format without version prefixes.

Current Code

bincode::deserialize(&decoded).map_err(|e| {
KoraError::InvalidTransaction(format!("Failed to deserialize transaction: {}", e))
})

Solution

Allow for both Transaction and Versioned. Something like this...

use solana_sdk::{ 
    transaction::{Transaction, VersionedTransaction}, 
};

pub fn decode_b64_transaction(encoded: &str) -> Result<VersionedTransaction, KoraError> {
    let decoded = STANDARD.decode(encoded).map_err(|e| {
        KoraError::InvalidTransaction(format!("Failed to decode base64 transaction: {}", e))
    })?;

    // Try versioned transaction first
    if let Ok(versioned_tx) = bincode::deserialize::<VersionedTransaction>(&decoded) {
        return Ok(versioned_tx);
    }

    // Fall back to legacy transaction and convert to versioned
    let legacy_tx: Transaction = bincode::deserialize(&decoded).map_err(|e| {
        KoraError::InvalidTransaction(format!("Failed to deserialize transaction: {}", e))
    })?;

    Ok(VersionedTransaction::from(legacy_tx))
}

Impact

  • Compatibility: Support both legacy and versioned transactions
  • Future-proofing: Versioned transactions are the modern standard
  • Error reduction: Eliminates confusing deserialization errors for versioned transactions (alternatively, we should create a specific error case for versioned transactions for clearer error handling)
  • This change will require updating any code that calls decode_b64_transaction() to work with VersionedTransaction instead of Transaction.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions