anza-xyz / anza-xyz/pinocchio

feat request: add a trait to serialize instruction data

Abierto
#109 12 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
Rust
Estrellas
951
Forks
228
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

right now all instructions are wrapped behind structs, and instruction data are mostly inside implementation inside `invoke_signed`.

we can add a trait to export/serialize these instructions.

there're two benefits for this:
1. we can easily test against other libraries (e.g. solana-program, anchor, etc.) to see if our pinocchio instruction has the same results
2. developers may have more control over the instruction data (not common but may be useful for some hacky stuff)

a draft interface:

```rust
pub trait IxSerialize {
fn to_ix_data(&self) -> Box<[u8]>;
}

// For e.g. construction of transaction
impl IxSerialize for Transfer<'_> {
fn to_ix_data(&self) -> Box<[u8]> {
self.to_ix_data()
}
}
```

and an example impl of `token::transfer`

```rust
impl Transfer<'_> {
#[inline(always)]
pub fn invoke(&self) -> ProgramResult {
self.invoke_signed(&[])
}

pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
// account metadata
let account_metas: [AccountMeta; 3] = [
AccountMeta::writable(self.from.key()),
AccountMeta::writable(self.to.key()),
AccountMeta::readonly_signer(self.authority.key()),
];

let instruction_data = self.to_ix_data();

let instruction = Instruction {
program_id: &crate::ID,
accounts: &account_metas,
data: &instruction_data,
};

invoke_signed(&instruction, &[self.from, self.to, self.authority], signers)
}

fn to_ix_data(&self) -> Box<[u8]> {
// Instruction data layout:
// - [0]: instruction discriminator (1 byte, u8)
// - [1..9]: amount (8 bytes, u64)
let mut instruction_data = Box::new_uninit_slice(9);

// Set discriminator as u8 at offset [0]
write_bytes(&mut instruction_data, &[3]);
// Set amount as u64 at offset [1..9]
write_bytes(&mut instruction_data[1..9], &self.amount.to_le_bytes());

unsafe { instruction_data.assume_init() }
}
}

impl<'a> IxSerialize for Transfer<'a> {
fn to_ix_data(&self) -> Box<[u8]> {
self.to_ix_data()
}
}
```

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.