Saneesh kumar
Saneesh kumar

Reputation: 110

BorshDeserialize gives try_from_slice error

I was exploring the "BorshDeserialize" option in Rust. and noticed the following issues when using trait bounds. Any help is appreciated

Sample code

use borsh::{BorshDeserialize, BorshSerialize};
use solana_program::pubkey::Pubkey;
use std::mem;

#[derive(BorshSerialize, BorshDeserialize, PartialEq, Debug)]
struct SampleData<'a> {
    accounts: (&'a Pubkey, &'a Pubkey),
    data: String,
    timestamp: u64,
    owner: &'a Pubkey,
}

fn main() {
    println!(
        "Size of SampleData is {} bytes",
        mem::size_of::<SampleData>()
    );
    let _pub_key = Pubkey::default();
    let _a = SampleData {
        accounts: (&_pub_key, &_pub_key),
        data: "ABCDE".to_string(),
        timestamp: 1643116047,
        owner: &_pub_key,
    };
    let _encoded_a = _a.try_to_vec().unwrap();
    println!("{:?}", _encoded_a);
    let _decoded_a = SampleData::try_from_slice(&_encoded_a).unwrap();
    println!("decoded_a: {:?}", _decoded_a);
}

Error message

error[E0599]: the function or associated item try_from_slice exists for struct SampleData<'_>, but its trait bounds were not satisfied
--> src/main.rs:27:34 | 6 | struct SampleData<'a> { | --------------------- | | | function or associated item try_from_slice not found for this | doesn't satisfy SampleData<'_>: BorshDeserialize ... 27 | let _decoded_a = SampleData::try_from_slice(&_encoded_a).unwrap(); |
^^^^^^^^^^^^^^ function or associated item cannot be called on SampleData<'_> due to unsatisfied trait bounds | note: the following trait bounds were not satisfied because of the requirements of the implementation of BorshDeserialize for _: (&Pubkey, &Pubkey): BorshDeserialize &Pubkey: BorshDeserialize --> src/main.rs:5:26 | 5 | #[derive(BorshSerialize, BorshDeserialize, PartialEq, Debug)] | ^^^^^^^^^^^^^^^^ 6 | struct SampleData<'a> { |
^^^^^^^^^^^^^^ = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item try_from_slice, perhaps you need to implement it: candidate #1: BorshDeserialize = note: this error originates in the derive macro BorshDeserialize (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try rustc --explain E0599. error: could not compile seralize due to previous error

Upvotes: 1

Views: 1678

Answers (1)

Jon C
Jon C

Reputation: 8412

The problem is that SampleData contains references, which isn't supported in normal Borsh deserialization. Borsh creates a new instance of your type based on a slice, but it won't be able to create references.

If you want to stick with Borsh, you should change the type to:

#[derive(BorshSerialize, BorshDeserialize, PartialEq, Debug)]
struct SampleData {
    accounts: (Pubkey, Pubkey),
    data: String,
    timestamp: u64,
    owner: Pubkey,
}

Upvotes: 2

Related Questions