solana icon indicating copy to clipboard operation
solana copied to clipboard

Deserialising a JSON-serialized VersionedTransaction fails

Open kevinheavey opened this issue 1 year ago • 1 comments

VersionedTransaction derives Serialize and Deserialize but if you serialize a VersionedTransaction with serde_json you get an invalid type error. It doesn't like the VersionedMessage prefix byte.

Dependencies for this example:

serde_json = "1.0.108"
solana-sdk = "1.17.13"
use solana_sdk::{
    hash::Hash as Blockhash,
    message::{v0::Message as MessageV0, VersionedMessage},
    signer::{keypair::Keypair, Signer},
    transaction::VersionedTransaction,
};

fn main() {
    let signer = Keypair::new();
    let msg = MessageV0::try_compile(&signer.pubkey(), &[], &[], Blockhash::default()).unwrap();
    let tx = VersionedTransaction::try_new(VersionedMessage::V0(msg), &[&signer]).unwrap();
    let json = serde_json::to_string(&tx).unwrap();
    println!("{json}");
    // panics
    let _: VersionedTransaction = serde_json::from_str(&json).unwrap();
}

Output:

{"signatures":[[1],[81,11,111,219,227,8,246,195,126,135,61,240,153,123,123,163,172,30,44,47,177,169,228,91,161,126,153,204,7,146,58,70,31,95,169,2,208,23,168,187,232,205,75,197,140,136,193,128,242,172,125,208,192,40,202,248,93,160,213,225,110,127,4,2]],"message":[128,{"header":{"numRequiredSignatures":1,"numReadonlySignedAccounts":0,"numReadonlyUnsignedAccounts":0},"accountKeys":[[1],[77,67,46,87,158,68,52,31,4,228,136,122,235,120,232,191,217,67,250,135,229,183,52,187,28,187,32,143,187,181,22,3]],"recentBlockhash":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"instructions":[[0]],"addressTableLookups":[[0]]}]}
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("invalid type: integer `128`, expected message prefix byte", line: 1, column: 267)', src/main.rs:15:63
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

kevinheavey avatar Dec 30 '23 20:12 kevinheavey

Thanks for reporting! Looks like the serde_json deserializer always calls visit_u64 and PrefixVisitor doesn't implement that method. I'll fix it

jstarry avatar Jan 17 '24 13:01 jstarry

Released in v1.17.18

jstarry avatar Jan 30 '24 02:01 jstarry