Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InstructionData::write_to implementation #2733

Merged
merged 11 commits into from
Dec 16, 2023
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The minor version will be incremented upon a breaking change and the patch versi
- cli: Allow force `init` and `new` ([#2698](https://github.com/coral-xyz/anchor/pull/2698)).
- cli: Add verifiable option when `deploy` ([#2705](https://github.com/coral-xyz/anchor/pull/2705)).
- cli: Add support for passing arguments to the underlying `solana program deploy` command with `anchor deploy` ([#2709](https://github.com/coral-xyz/anchor/pull/2709)).
- lang: Add `InstructionData::write_to` implementation ([#2733](https://github.com/coral-xyz/anchor/pull/2733)).

### Fixes

Expand Down
10 changes: 10 additions & 0 deletions lang/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,16 @@ pub trait InstructionData: Discriminator + AnchorSerialize {
d.append(&mut self.try_to_vec().expect("Should always serialize"));
d
}

/// Clears `data` and writes instruction data to it.
///
/// We use a `Vec<u8>`` here because of the additional flexibility of re-allocation (only if
/// necessary), and because the data field in `Instruction` expects a `Vec<u8>`.
fn write_to(&self, mut data: &mut Vec<u8>) {
data.clear();
data.extend_from_slice(&Self::DISCRIMINATOR);
self.serialize(&mut data).unwrap()
}
}

/// An event that can be emitted via a Solana log. See [`emit!`](crate::prelude::emit) for an example.
Expand Down
36 changes: 36 additions & 0 deletions lang/tests/serialization.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use anchor_lang::{AnchorDeserialize, AnchorSerialize, Discriminator, InstructionData};

#[test]
fn test_instruction_data() {
// Define some test type and implement ser/de, discriminator, and ix data
#[derive(Default, AnchorSerialize, AnchorDeserialize, PartialEq, Eq)]
struct MyType {
foo: [u8; 8],
bar: String,
}
impl Discriminator for MyType {
const DISCRIMINATOR: [u8; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
}
impl InstructionData for MyType {}

// Initialize some instance of the type
let instance = MyType {
foo: [0, 2, 4, 6, 8, 10, 12, 14],
bar: "sharding sucks".into(),
};

// Serialize using both methods
let data = instance.data();
let mut write = vec![];
instance.write_to(&mut write);

// Check that one is correct and that they are equal (implies other is correct)
let correct_disc = data[0..8] == MyType::DISCRIMINATOR;
let correct_data = MyType::deserialize(&mut &data[8..]).is_ok_and(|result| result == instance);
let correct_serialization = correct_disc & correct_data;
assert!(correct_serialization, "serialization was not correct");
assert_eq!(
&data, &write,
"the different methods produced different serialized representations"
);
}
Loading