mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-05 23:03:06 +00:00
refactor encoding
This commit is contained in:
parent
82907f5d8f
commit
e8e565fe8c
147
nssa/src/public_transaction/encoding.rs
Normal file
147
nssa/src/public_transaction/encoding.rs
Normal file
@ -0,0 +1,147 @@
|
||||
use std::io::{Cursor, Read};
|
||||
|
||||
use nssa_core::program::ProgramId;
|
||||
|
||||
use crate::{
|
||||
public_transaction::{Message, WitnessSet}, Address, PublicKey, PublicTransaction, Signature
|
||||
};
|
||||
|
||||
const MESSAGE_ENCODING_PREFIX_LEN: usize = 19;
|
||||
const MESSAGE_ENCODING_PREFIX: &[u8; MESSAGE_ENCODING_PREFIX_LEN] = b"NSSA/v0.1/TxMessage";
|
||||
|
||||
impl Message {
|
||||
/// Serializes a `Message` into bytes in the following layout:
|
||||
/// TAG || <program_id> (bytes LE) * 8 || addresses_len (4 bytes LE) || addresses (32 bytes * N) || nonces_len (4 bytes LE) || nonces (16 bytes * M) || instruction_data_len || instruction_data (4 bytes * K)
|
||||
/// Integers and words are encoded in little-endian byte order, and fields appear in the above order.
|
||||
pub(crate) fn message_to_bytes(&self) -> Vec<u8> {
|
||||
let mut bytes = MESSAGE_ENCODING_PREFIX.to_vec();
|
||||
// program_id: [u32; 8]
|
||||
for word in &self.program_id {
|
||||
bytes.extend_from_slice(&word.to_le_bytes());
|
||||
}
|
||||
// addresses: Vec<[u8;32]>
|
||||
// serialize length as u32 little endian, then all addresses concatenated
|
||||
let addresses_len = self.addresses.len() as u32;
|
||||
bytes.extend(&addresses_len.to_le_bytes());
|
||||
for addr in &self.addresses {
|
||||
bytes.extend_from_slice(addr.value());
|
||||
}
|
||||
// nonces: Vec<u128>
|
||||
let nonces_len = self.nonces.len() as u32;
|
||||
bytes.extend(&nonces_len.to_le_bytes());
|
||||
for nonce in &self.nonces {
|
||||
bytes.extend(&nonce.to_le_bytes());
|
||||
}
|
||||
// instruction_data: Vec<u32>
|
||||
// serialize length as u32 little endian, then all addresses concatenated
|
||||
let instr_len = self.instruction_data.len() as u32;
|
||||
bytes.extend(&instr_len.to_le_bytes());
|
||||
for word in &self.instruction_data {
|
||||
bytes.extend(&word.to_le_bytes());
|
||||
}
|
||||
|
||||
bytes
|
||||
}
|
||||
|
||||
pub(crate) fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Self {
|
||||
let prefix = {
|
||||
let mut this = [0u8; MESSAGE_ENCODING_PREFIX_LEN];
|
||||
cursor.read_exact(&mut this).unwrap();
|
||||
this
|
||||
};
|
||||
assert_eq!(&prefix, MESSAGE_ENCODING_PREFIX);
|
||||
let program_id: ProgramId = {
|
||||
let mut this = [0u32; 8];
|
||||
for i in 0..8 {
|
||||
this[i] = u32_from_cursor(cursor);
|
||||
}
|
||||
this
|
||||
};
|
||||
let addresses_len = u32_from_cursor(cursor);
|
||||
let mut addresses = Vec::with_capacity(addresses_len as usize);
|
||||
for _ in 0..addresses_len {
|
||||
let mut value = [0u8; 32];
|
||||
cursor.read_exact(&mut value).unwrap();
|
||||
addresses.push(Address::new(value))
|
||||
}
|
||||
let nonces_len = u32_from_cursor(cursor);
|
||||
let mut nonces = Vec::with_capacity(nonces_len as usize);
|
||||
for _ in 0..nonces_len {
|
||||
let mut buf = [0u8; 16];
|
||||
cursor.read_exact(&mut buf).unwrap();
|
||||
nonces.push(u128::from_le_bytes(buf))
|
||||
}
|
||||
let instruction_data_len = u32_from_cursor(cursor);
|
||||
let mut instruction_data = Vec::with_capacity(instruction_data_len as usize);
|
||||
for _ in 0..instruction_data_len {
|
||||
let word = u32_from_cursor(cursor);
|
||||
instruction_data.push(word)
|
||||
}
|
||||
Self {
|
||||
program_id,
|
||||
addresses,
|
||||
nonces,
|
||||
instruction_data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl WitnessSet {
|
||||
pub(crate) fn to_bytes(&self) -> Vec<u8> {
|
||||
let mut bytes = Vec::new();
|
||||
let size = self.signatures_and_public_keys.len() as u32;
|
||||
bytes.extend_from_slice(&size.to_le_bytes());
|
||||
for (signature, public_key) in &self.signatures_and_public_keys {
|
||||
bytes.extend_from_slice(&signature.value);
|
||||
bytes.extend_from_slice(&public_key.0);
|
||||
}
|
||||
bytes
|
||||
}
|
||||
|
||||
// TODO: remove unwraps and return Result
|
||||
pub(crate) fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Self {
|
||||
let num_signatures: u32 = {
|
||||
let mut buf = [0u8; 4];
|
||||
cursor.read_exact(&mut buf).unwrap();
|
||||
u32::from_le_bytes(buf)
|
||||
};
|
||||
let mut signatures_and_public_keys = Vec::with_capacity(num_signatures as usize);
|
||||
for i in 0..num_signatures {
|
||||
let signature = Signature::from_cursor(cursor);
|
||||
let public_key = PublicKey::from_cursor(cursor);
|
||||
signatures_and_public_keys.push((signature, public_key))
|
||||
}
|
||||
Self {
|
||||
signatures_and_public_keys,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PublicTransaction {
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
let mut bytes = self.message.message_to_bytes();
|
||||
bytes.extend_from_slice(&self.witness_set.to_bytes());
|
||||
bytes
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> Self {
|
||||
let mut cursor = Cursor::new(bytes);
|
||||
Self::from_cursor(&mut cursor)
|
||||
}
|
||||
|
||||
pub fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Self {
|
||||
let message = Message::from_cursor(cursor);
|
||||
let witness_set = WitnessSet::from_cursor(cursor);
|
||||
Self {
|
||||
message,
|
||||
witness_set,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn u32_from_cursor(cursor: &mut Cursor<&[u8]>) -> u32 {
|
||||
let mut word_buf = [0u8; 4];
|
||||
cursor.read_exact(&mut word_buf).unwrap();
|
||||
u32::from_le_bytes(word_buf)
|
||||
}
|
||||
@ -7,8 +7,6 @@ use nssa_core::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{Address, error::NssaError, program::Program};
|
||||
const MESSAGE_ENCODING_PREFIX_LEN: usize = 19;
|
||||
const MESSAGE_ENCODING_PREFIX: &[u8; MESSAGE_ENCODING_PREFIX_LEN] = b"NSSA/v0.1/TxMessage";
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Message {
|
||||
@ -33,85 +31,5 @@ impl Message {
|
||||
instruction_data,
|
||||
})
|
||||
}
|
||||
|
||||
/// Serializes a `Message` into bytes in the following layout:
|
||||
/// TAG || <program_id> (bytes LE) * 8 || addresses_len (4 bytes LE) || addresses (32 bytes * N) || nonces_len (4 bytes LE) || nonces (16 bytes * M) || instruction_data_len || instruction_data (4 bytes * K)
|
||||
/// Integers and words are encoded in little-endian byte order, and fields appear in the above order.
|
||||
pub(crate) fn message_to_bytes(&self) -> Vec<u8> {
|
||||
let mut bytes = MESSAGE_ENCODING_PREFIX.to_vec();
|
||||
// program_id: [u32; 8]
|
||||
for word in &self.program_id {
|
||||
bytes.extend_from_slice(&word.to_le_bytes());
|
||||
}
|
||||
// addresses: Vec<[u8;32]>
|
||||
// serialize length as u32 little endian, then all addresses concatenated
|
||||
let addresses_len = self.addresses.len() as u32;
|
||||
bytes.extend(&addresses_len.to_le_bytes());
|
||||
for addr in &self.addresses {
|
||||
bytes.extend_from_slice(addr.value());
|
||||
}
|
||||
// nonces: Vec<u128>
|
||||
let nonces_len = self.nonces.len() as u32;
|
||||
bytes.extend(&nonces_len.to_le_bytes());
|
||||
for nonce in &self.nonces {
|
||||
bytes.extend(&nonce.to_le_bytes());
|
||||
}
|
||||
// instruction_data: Vec<u32>
|
||||
// serialize length as u32 little endian, then all addresses concatenated
|
||||
let instr_len = self.instruction_data.len() as u32;
|
||||
bytes.extend(&instr_len.to_le_bytes());
|
||||
for word in &self.instruction_data {
|
||||
bytes.extend(&word.to_le_bytes());
|
||||
}
|
||||
|
||||
bytes
|
||||
}
|
||||
|
||||
pub(crate) fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Self {
|
||||
let prefix = {
|
||||
let mut this = [0u8; MESSAGE_ENCODING_PREFIX_LEN];
|
||||
cursor.read_exact(&mut this).unwrap();
|
||||
this
|
||||
};
|
||||
assert_eq!(&prefix, MESSAGE_ENCODING_PREFIX);
|
||||
let program_id: ProgramId = {
|
||||
let mut this = [0u32; 8];
|
||||
for i in 0..8 {
|
||||
this[i] = u32_from_cursor(cursor);
|
||||
}
|
||||
this
|
||||
};
|
||||
let addresses_len = u32_from_cursor(cursor);
|
||||
let mut addresses = Vec::with_capacity(addresses_len as usize);
|
||||
for _ in 0..addresses_len {
|
||||
let mut value = [0u8; 32];
|
||||
cursor.read_exact(&mut value).unwrap();
|
||||
addresses.push(Address::new(value))
|
||||
}
|
||||
let nonces_len = u32_from_cursor(cursor);
|
||||
let mut nonces = Vec::with_capacity(nonces_len as usize);
|
||||
for _ in 0..nonces_len {
|
||||
let mut buf = [0u8; 16];
|
||||
cursor.read_exact(&mut buf).unwrap();
|
||||
nonces.push(u128::from_le_bytes(buf))
|
||||
}
|
||||
let instruction_data_len = u32_from_cursor(cursor);
|
||||
let mut instruction_data = Vec::with_capacity(instruction_data_len as usize);
|
||||
for _ in 0..instruction_data_len {
|
||||
let word = u32_from_cursor(cursor);
|
||||
instruction_data.push(word)
|
||||
}
|
||||
Self {
|
||||
program_id,
|
||||
addresses,
|
||||
nonces,
|
||||
instruction_data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn u32_from_cursor(cursor: &mut Cursor<&[u8]>) -> u32 {
|
||||
let mut word_buf = [0u8; 4];
|
||||
cursor.read_exact(&mut word_buf).unwrap();
|
||||
u32::from_le_bytes(word_buf)
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ use sha2::{Digest, digest::FixedOutput};
|
||||
|
||||
use crate::{V01State, address::Address, error::NssaError};
|
||||
|
||||
mod encoding;
|
||||
mod message;
|
||||
mod witness_set;
|
||||
|
||||
@ -47,20 +48,6 @@ impl PublicTransaction {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
let mut bytes = self.message.message_to_bytes();
|
||||
bytes.extend_from_slice(&self.witness_set.to_bytes());
|
||||
bytes
|
||||
}
|
||||
|
||||
pub fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Self {
|
||||
let message = Message::from_cursor(cursor);
|
||||
let witness_set = WitnessSet::from_cursor(cursor);
|
||||
Self {
|
||||
message,
|
||||
witness_set,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hash(&self) -> [u8; 32] {
|
||||
let bytes = self.to_bytes();
|
||||
@ -145,7 +132,7 @@ mod tests {
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
fn test_to_bytes() {
|
||||
let key1 = PrivateKey::try_new([1; 32]).unwrap();
|
||||
let key2 = PrivateKey::try_new([2; 32]).unwrap();
|
||||
let addr1 = Address::from_public_key(&PublicKey::new(&key1));
|
||||
|
||||
@ -35,32 +35,4 @@ impl WitnessSet {
|
||||
self.signatures_and_public_keys.iter()
|
||||
}
|
||||
|
||||
pub(crate) fn to_bytes(&self) -> Vec<u8> {
|
||||
let mut bytes = Vec::new();
|
||||
let size = self.signatures_and_public_keys.len() as u32;
|
||||
bytes.extend_from_slice(&size.to_le_bytes());
|
||||
for (signature, public_key) in &self.signatures_and_public_keys {
|
||||
bytes.extend_from_slice(&signature.value);
|
||||
bytes.extend_from_slice(&public_key.0);
|
||||
}
|
||||
bytes
|
||||
}
|
||||
|
||||
// TODO: remove unwraps and return Result
|
||||
pub(crate) fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Self {
|
||||
let num_signatures: u32 = {
|
||||
let mut buf = [0u8; 4];
|
||||
cursor.read_exact(&mut buf).unwrap();
|
||||
u32::from_le_bytes(buf)
|
||||
};
|
||||
let mut signatures_and_public_keys = Vec::with_capacity(num_signatures as usize);
|
||||
for i in 0..num_signatures {
|
||||
let signature = Signature::from_cursor(cursor);
|
||||
let public_key = PublicKey::from_cursor(cursor);
|
||||
signatures_and_public_keys.push((signature, public_key))
|
||||
}
|
||||
Self {
|
||||
signatures_and_public_keys,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
22
nssa/src/signature/encoding.rs
Normal file
22
nssa/src/signature/encoding.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use std::io::{Cursor, Read};
|
||||
|
||||
use crate::{PublicKey, Signature};
|
||||
|
||||
|
||||
impl PublicKey {
|
||||
// TODO: remove unwraps and return Result
|
||||
pub(crate) fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Self {
|
||||
let mut value = [0u8; 32];
|
||||
cursor.read_exact(&mut value).unwrap();
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl Signature {
|
||||
// TODO: remove unwraps and return Result
|
||||
pub(crate) fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Self {
|
||||
let mut value = [0u8; 64];
|
||||
cursor.read_exact(&mut value).unwrap();
|
||||
Self { value }
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
mod private_key;
|
||||
mod public_key;
|
||||
mod signature;
|
||||
mod encoding;
|
||||
|
||||
pub use private_key::PrivateKey;
|
||||
pub use public_key::PublicKey;
|
||||
|
||||
@ -21,11 +21,3 @@ impl PublicKey {
|
||||
}
|
||||
}
|
||||
|
||||
impl PublicKey {
|
||||
// TODO: remove unwraps and return Result
|
||||
pub(crate) fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Self {
|
||||
let mut value = [0u8; 32];
|
||||
cursor.read_exact(&mut value).unwrap();
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,11 +27,3 @@ impl Signature {
|
||||
}
|
||||
}
|
||||
|
||||
impl Signature {
|
||||
// TODO: remove unwraps and return Result
|
||||
pub(crate) fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Self {
|
||||
let mut value = [0u8; 64];
|
||||
cursor.read_exact(&mut value).unwrap();
|
||||
Self { value }
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,10 +72,7 @@ impl JsonHandler {
|
||||
|
||||
async fn process_send_tx(&self, request: Request) -> Result<Value, RpcErr> {
|
||||
let send_tx_req = SendTxRequest::parse(Some(request.params))?;
|
||||
let tx = {
|
||||
let mut cursor: Cursor<&[u8]> = Cursor::new(&send_tx_req.transaction);
|
||||
nssa::PublicTransaction::from_cursor(&mut cursor)
|
||||
};
|
||||
let tx = nssa::PublicTransaction::from_bytes(&send_tx_req.transaction);
|
||||
|
||||
{
|
||||
let mut state = self.sequencer_state.lock().await;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user