From 40335d0f7fb33d95b877283405baee5f26f71ba1 Mon Sep 17 00:00:00 2001 From: Berzan Date: Tue, 9 Apr 2024 19:40:11 +0000 Subject: [PATCH] simplify: overall logic --- .devcontainer/devcontainer.json | 4 +- balances-db/src/balances_db.rs | 8 +- burns-db/src/burns_db.rs | 8 +- data-structures/src/address.rs | 95 ++--- data-structures/src/balance.rs | 45 +-- data-structures/src/burn.rs | 45 +-- data-structures/src/byte_conversion.rs | 48 +++ data-structures/src/deposit.rs | 47 +-- data-structures/src/field.rs | 93 ++--- data-structures/src/field_conversion.rs | 34 ++ data-structures/src/lib.rs | 14 +- data-structures/src/liquidity.rs | 49 +-- data-structures/src/pool.rs | 50 +-- data-structures/src/scalar.rs | 29 ++ data-structures/src/signature.rs | 86 ++-- data-structures/src/state_roots.rs | 31 ++ data-structures/src/to_bytes.rs | 21 - data-structures/src/to_fields.rs | 37 -- data-structures/src/transaction.rs | 174 ++++---- data-structures/src/tx_status.rs | 20 +- data-structures/src/u256.rs | 40 +- dynamic-queue/Cargo.toml | 1 + dynamic-queue/src/dynamic_queue.rs | 141 ++++--- generator/Cargo.toml | 15 + generator/src/lib.rs | 1 + generator/src/method.rs | 371 ++++++++++++++++++ liquidities-db/src/liqudities_db.rs | 8 +- mempool/src/mempool.rs | 2 +- merkle-tree/src/double_witness.rs | 18 +- merkle-tree/src/merkle_tree.rs | 24 +- merkle-tree/src/sibling.rs | 12 +- merkle-tree/src/single_witness.rs | 56 +-- pools-db/src/pools_db.rs | 8 +- poseidon-hash/Cargo.toml | 3 + poseidon-hash/src/lib.rs | 64 +++ processes/src/authenticator/process.rs | 4 +- processes/src/lib.rs | 2 + processes/src/withdrawals/process.rs | 3 +- proof-generator/tests/proof-generator.test.ts | 5 + proofpool/src/proofpool.rs | 2 +- rpc-server/src/rpc_method.rs | 70 ++-- rpc-server/src/rpc_response.rs | 2 +- rpc-server/src/start_rpc_server.rs | 3 +- withdrawals-db/src/withdrawals_db.rs | 16 +- 44 files changed, 1146 insertions(+), 663 deletions(-) create mode 100644 data-structures/src/byte_conversion.rs create mode 100644 data-structures/src/field_conversion.rs create mode 100644 data-structures/src/scalar.rs create mode 100644 data-structures/src/state_roots.rs delete mode 100644 data-structures/src/to_bytes.rs delete mode 100644 data-structures/src/to_fields.rs create mode 100644 generator/Cargo.toml create mode 100644 generator/src/lib.rs create mode 100644 generator/src/method.rs diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e90bd37..0e37f92 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,7 +8,9 @@ "rust-lang.rust-analyzer", "tamasfe.even-better-toml", "dbaeumer.vscode-eslint", - "esbenp.prettier-vscode" + "esbenp.prettier-vscode", + "svelte.svelte-vscode", + "bradlc.vscode-tailwindcss" ], "settings": { "terminal.integrated.defaultProfile.linux": "fish", diff --git a/balances-db/src/balances_db.rs b/balances-db/src/balances_db.rs index 81e2052..ec9e697 100644 --- a/balances-db/src/balances_db.rs +++ b/balances-db/src/balances_db.rs @@ -2,7 +2,7 @@ use crate::{ BalancesDbError, DoubleBalanceWitness, SingleBalanceWitness, BALANCES_TREE_HEIGHT, BALANCES_TREE_SIBLING_COUNT, BALANCE_SIZE_IN_BYTES, }; -use nacho_data_structures::{Address, Balance, FromBytes, ToBytes, ToFields, U256}; +use nacho_data_structures::{Address, Balance, ByteConversion, FieldConversion, U256}; use nacho_dynamic_list::DynamicList; use nacho_merkle_tree::MerkleTree; use nacho_poseidon_hash::{create_poseidon_hasher, poseidon_hash, PoseidonHasher}; @@ -27,7 +27,7 @@ impl BalancesDb { let hasher = create_poseidon_hasher(); list.for_each(&mut indexes, |buf, index, indexes| { - let balance = Balance::from_bytes(buf); + let balance = Balance::from_bytes(&buf); match indexes.get_mut(&balance.owner) { Some(indexes) => { @@ -108,7 +108,7 @@ impl BalancesDb { let buf = self.list.get(index).await?; - let balance = Balance::from_bytes(buf); + let balance = Balance::from_bytes(&buf); Ok(balance) } @@ -124,7 +124,7 @@ impl BalancesDb { for &(index, _) in indexes { let buf = self.list.get(index).await?; - let balance = Balance::from_bytes(buf); + let balance = Balance::from_bytes(&buf); balances.push(balance) } diff --git a/burns-db/src/burns_db.rs b/burns-db/src/burns_db.rs index c03be3c..71a1d49 100644 --- a/burns-db/src/burns_db.rs +++ b/burns-db/src/burns_db.rs @@ -2,7 +2,7 @@ use crate::{ BurnsDbError, SingleBurnWitness, BURNS_TREE_HEIGHT, BURNS_TREE_SIBLING_COUNT, BURN_SIZE_IN_BYTES, }; -use nacho_data_structures::{Address, Burn, FromBytes, ToBytes, ToFields, U256}; +use nacho_data_structures::{Address, Burn, ByteConversion, FieldConversion, U256}; use nacho_dynamic_list::DynamicList; use nacho_merkle_tree::MerkleTree; use nacho_poseidon_hash::{create_poseidon_hasher, poseidon_hash, PoseidonHasher}; @@ -27,7 +27,7 @@ impl BurnsDb { let hasher = create_poseidon_hasher(); list.for_each(&mut indexes, |buf, index, indexes| { - let burn = Burn::from_bytes(buf); + let burn = Burn::from_bytes(&buf); match indexes.get_mut(&burn.burner) { Some(indexes) => { @@ -109,7 +109,7 @@ impl BurnsDb { let buf = self.list.get(index).await?; - let burn = Burn::from_bytes(buf); + let burn = Burn::from_bytes(&buf); Ok(burn) } @@ -125,7 +125,7 @@ impl BurnsDb { for &(index, _) in indexes { let buf = self.list.get(index).await?; - let burn = Burn::from_bytes(buf); + let burn = Burn::from_bytes(&buf); burns.push(burn) } diff --git a/data-structures/src/address.rs b/data-structures/src/address.rs index 5cef61f..3828b40 100644 --- a/data-structures/src/address.rs +++ b/data-structures/src/address.rs @@ -1,63 +1,65 @@ +use crate::{ByteConversion, Field, FieldConversion}; use mina_signer::CompressedPubKey; -use crate::{Field, FromBytes, ToBytes, ToFields}; - /// Byte representation of base 58 encoded public keys. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Address([u8; 55]); -impl Address { - // Example: B62qoTFrus93Ryi1VzbFakzErBBmcikHEq27vhMkU4FfjGfCovv41fb - // Regexp: /^B62q[1-9A-HJ-NP-Za-km-z]{51}$/ - pub fn is_valid(addr: &str) -> Result<(), ()> { - if addr.len() != 55 { - return Err(()); - } +impl FieldConversion<2> for Address { + fn to_fields(&self) -> [Field; 2] { + let pubkey = CompressedPubKey::from_address(std::str::from_utf8(&self.0).unwrap()).unwrap(); - if addr[0..4].as_bytes() != [66, 54, 50, 113] { - return Err(()); - } + let [field_0] = pubkey.x.to_fields(); + let [field_1] = pubkey.is_odd.to_fields(); - for c in addr.bytes() { - match c { - b'1'..=b'9' - | b'A'..=b'H' - | b'J'..=b'N' - | b'P'..=b'Z' - | b'a'..=b'k' - | b'm'..=b'z' => (), - _ => return Err(()), - } - } - - Ok(()) + [field_0, field_1] } } -impl FromBytes for Address { - type Bytes = [u8; 55]; - - fn from_bytes(bytes: Self::Bytes) -> Self { - Address(bytes) +impl ByteConversion<55> for Address { + fn to_bytes(&self) -> [u8; 55] { + self.0 } -} -impl ToBytes for Address { - type Bytes = [u8; 55]; - - fn to_bytes(&self) -> Self::Bytes { - self.0 + fn from_bytes(bytes: &[u8; 55]) -> Self { + Address(bytes.to_owned()) } } -impl ToFields for Address { - type Fields = [Field; 2]; +/// Checks the given address to be valid. +/// +/// Returns `true` if it is a valid address, otherwise returns `false`. +/// +/// Example valid address: `B62qoTFrus93Ryi1VzbFakzErBBmcikHEq27vhMkU4FfjGfCovv41fb` +/// +/// Regular expression: `/^B62q[1-9A-HJ-NP-Za-km-z]{51}$/` +/// +/// # Examples +/// +/// Check an address: +/// +/// ```rs +/// let is_valid = check_address("B62qoTFrus93Ryi1VzbFakzErBBmcikHEq27vhMkU4FfjGfCovv41fb"); +/// assert_eq!(is_valid, true); +/// ``` +/// +pub fn check_address(addr: &str) -> bool { + if addr.len() != 55 { + return false; + } - fn to_fields(&self) -> Self::Fields { - let pubkey = CompressedPubKey::from_address(std::str::from_utf8(&self.0).unwrap()).unwrap(); + if addr[0..4].as_bytes() != [66, 54, 50, 113] { + return false; + } - [pubkey.x, pubkey.is_odd.into()] + for c in addr.bytes() { + match c { + b'1'..=b'9' | b'A'..=b'H' | b'J'..=b'N' | b'P'..=b'Z' | b'a'..=b'k' | b'm'..=b'z' => (), + _ => return false, + } } + + true } #[cfg(test)] @@ -65,23 +67,22 @@ mod tests { use super::*; #[test] - fn checks_if_address_is_valid() { // /^B62q[1-9A-HJ-NP-Za-km-z]{51}$/ let addr = "B62qoTFrus93Ryi1VzbFakzErBBmcikHEq27vhMkU4FfjGfCovv41fb"; - assert_eq!(Address::is_valid(addr), Ok(())); + assert_eq!(check_address(addr), true); let addr = "B63qoTFrus93Ryi1VzbFakzErBBmcikHEq27vhMkU4FfjGfCovv41fb"; - assert_eq!(Address::is_valid(addr), Err(())); + assert_eq!(check_address(addr), false); let addr = "B63qoTFrus93Ryi1VzbFakzErBBmcikHEq2ivhMkU4FfjGfCovv41fb"; - assert_eq!(Address::is_valid(addr), Err(())); + assert_eq!(check_address(addr), false); let addr = "B63qoTFrus93Ryi1VzbFakzErBBmcikHEq2fjGfCovv41fb"; - assert_eq!(Address::is_valid(addr), Err(())); + assert_eq!(check_address(addr), false); let addr = "B63qoTFrus93Ryi1VzbFakzErBBmcikHEq2ivhMkU4FfvhMkU4FfjGfCovv41fb"; - assert_eq!(Address::is_valid(addr), Err(())); + assert_eq!(check_address(addr), false); } } diff --git a/data-structures/src/balance.rs b/data-structures/src/balance.rs index efff1be..53d4073 100644 --- a/data-structures/src/balance.rs +++ b/data-structures/src/balance.rs @@ -1,4 +1,4 @@ -use crate::{Address, Field, FromBytes, ToBytes, ToFields, U256}; +use crate::{Address, ByteConversion, Field, FieldConversion, U256}; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Balance { @@ -7,37 +7,18 @@ pub struct Balance { pub token_amount: u64, } -impl ToFields for Balance { - type Fields = [Field; 4]; +impl FieldConversion<4> for Balance { + fn to_fields(&self) -> [Field; 4] { + let [field_0, field_1] = self.owner.to_fields(); + let [field_2] = self.token_id.to_fields(); + let [field_3] = self.token_amount.to_fields(); - fn to_fields(&self) -> Self::Fields { - let owner = self.owner.to_fields(); - - [ - owner[0], - owner[1], - (&self.token_id).into(), - self.token_amount.into(), - ] - } -} - -impl FromBytes for Balance { - type Bytes = [u8; 95]; - - fn from_bytes(bytes: Self::Bytes) -> Self { - Self { - owner: Address::from_bytes(bytes[0..55].try_into().unwrap()), - token_id: U256::from_bytes(bytes[55..87].try_into().unwrap()), - token_amount: u64::from_bytes(bytes[87..95].try_into().unwrap()), - } + [field_0, field_1, field_2, field_3] } } -impl ToBytes for Balance { - type Bytes = [u8; 95]; - - fn to_bytes(&self) -> Self::Bytes { +impl ByteConversion<95> for Balance { + fn to_bytes(&self) -> [u8; 95] { let mut bytes = [0u8; 95]; bytes[0..55].copy_from_slice(&self.owner.to_bytes()); @@ -46,4 +27,12 @@ impl ToBytes for Balance { bytes } + + fn from_bytes(bytes: &[u8; 95]) -> Self { + Self { + owner: Address::from_bytes(bytes[0..55].try_into().unwrap()), + token_id: U256::from_bytes(bytes[55..87].try_into().unwrap()), + token_amount: u64::from_bytes(bytes[87..95].try_into().unwrap()), + } + } } diff --git a/data-structures/src/burn.rs b/data-structures/src/burn.rs index 7f2a4f9..d733320 100644 --- a/data-structures/src/burn.rs +++ b/data-structures/src/burn.rs @@ -1,4 +1,4 @@ -use crate::{Address, Field, FromBytes, ToBytes, ToFields, U256}; +use crate::{Address, ByteConversion, Field, FieldConversion, U256}; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Burn { @@ -7,37 +7,18 @@ pub struct Burn { pub token_amount: u64, } -impl ToFields for Burn { - type Fields = [Field; 4]; +impl FieldConversion<4> for Burn { + fn to_fields(&self) -> [Field; 4] { + let [field_0, field_1] = self.burner.to_fields(); + let [field_2] = self.token_id.to_fields(); + let [field_3] = self.token_amount.to_fields(); - fn to_fields(&self) -> Self::Fields { - let burner = self.burner.to_fields(); - - [ - burner[0], - burner[1], - (&self.token_id).into(), - self.token_amount.into(), - ] - } -} - -impl FromBytes for Burn { - type Bytes = [u8; 95]; - - fn from_bytes(bytes: Self::Bytes) -> Self { - Self { - burner: Address::from_bytes(bytes[0..55].try_into().unwrap()), - token_id: U256::from_bytes(bytes[55..87].try_into().unwrap()), - token_amount: u64::from_bytes(bytes[87..95].try_into().unwrap()), - } + [field_0, field_1, field_2, field_3] } } -impl ToBytes for Burn { - type Bytes = [u8; 95]; - - fn to_bytes(&self) -> Self::Bytes { +impl ByteConversion<95> for Burn { + fn to_bytes(&self) -> [u8; 95] { let mut bytes = [0u8; 95]; bytes[0..55].copy_from_slice(&self.burner.to_bytes()); @@ -46,4 +27,12 @@ impl ToBytes for Burn { bytes } + + fn from_bytes(bytes: &[u8; 95]) -> Self { + Self { + burner: Address::from_bytes(bytes[0..55].try_into().unwrap()), + token_id: U256::from_bytes(bytes[55..87].try_into().unwrap()), + token_amount: u64::from_bytes(bytes[87..95].try_into().unwrap()), + } + } } diff --git a/data-structures/src/byte_conversion.rs b/data-structures/src/byte_conversion.rs new file mode 100644 index 0000000..a00e7e5 --- /dev/null +++ b/data-structures/src/byte_conversion.rs @@ -0,0 +1,48 @@ +/// The trait that is used to convert statically sized data structures back and forth into bytes. +/// +/// The constant generic parameter `L` represents the length of the byte representation of the data structures. +pub trait ByteConversion { + /// Converts the data structure to bytes. + /// + /// # Examples + /// + /// Convert to bytes: + /// + /// ```rs + /// let bytes = data.to_bytes(); + /// ``` + /// + fn to_bytes(&self) -> [u8; L]; + + /// Creates a data structure from the given bytes. + /// + /// # Examples + /// + /// Create a data structure: + /// + /// ```rs + /// let data = ByteConversion.from_bytes(bytes); + /// ``` + /// + fn from_bytes(bytes: &[u8; L]) -> Self; +} + +impl ByteConversion<8> for u64 { + fn to_bytes(&self) -> [u8; 8] { + self.to_le_bytes() + } + + fn from_bytes(bytes: &[u8; 8]) -> Self { + u64::from_le_bytes(bytes.to_owned()) + } +} + +impl ByteConversion<1> for bool { + fn to_bytes(&self) -> [u8; 1] { + (self.to_owned() as u8).to_le_bytes() + } + + fn from_bytes(bytes: &[u8; 1]) -> Self { + bytes[0] != 0 + } +} diff --git a/data-structures/src/deposit.rs b/data-structures/src/deposit.rs index 78a5b5e..ed96c50 100644 --- a/data-structures/src/deposit.rs +++ b/data-structures/src/deposit.rs @@ -1,43 +1,24 @@ -use crate::{Address, Field, FromBytes, ToBytes, ToFields, U256}; +use crate::{Address, ByteConversion, Field, FieldConversion, U256}; -#[derive(Clone)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Deposit { depositor: Address, token_id: U256, token_amount: u64, } -impl ToFields for Deposit { - type Fields = [Field; 4]; +impl FieldConversion<4> for Deposit { + fn to_fields(&self) -> [Field; 4] { + let [field_0, field_1] = self.depositor.to_fields(); + let [field_2] = self.token_id.to_fields(); + let [field_3] = self.token_amount.to_fields(); - fn to_fields(&self) -> Self::Fields { - let depositor = self.depositor.to_fields(); - - [ - depositor[0], - depositor[1], - (&self.token_id).into(), - self.token_amount.into(), - ] - } -} - -impl FromBytes for Deposit { - type Bytes = [u8; 95]; - - fn from_bytes(bytes: Self::Bytes) -> Self { - Self { - depositor: Address::from_bytes(bytes[0..55].try_into().unwrap()), - token_id: U256::from_bytes(bytes[55..87].try_into().unwrap()), - token_amount: u64::from_bytes(bytes[87..95].try_into().unwrap()), - } + [field_0, field_1, field_2, field_3] } } -impl ToBytes for Deposit { - type Bytes = [u8; 95]; - - fn to_bytes(&self) -> Self::Bytes { +impl ByteConversion<95> for Deposit { + fn to_bytes(&self) -> [u8; 95] { let mut bytes = [0u8; 95]; bytes[0..55].copy_from_slice(&self.depositor.to_bytes()); @@ -46,4 +27,12 @@ impl ToBytes for Deposit { bytes } + + fn from_bytes(bytes: &[u8; 95]) -> Self { + Self { + depositor: Address::from_bytes(bytes[0..55].try_into().unwrap()), + token_id: U256::from_bytes(bytes[55..87].try_into().unwrap()), + token_amount: u64::from_bytes(bytes[87..95].try_into().unwrap()), + } + } } diff --git a/data-structures/src/field.rs b/data-structures/src/field.rs index 9ded0a5..b67adea 100644 --- a/data-structures/src/field.rs +++ b/data-structures/src/field.rs @@ -1,8 +1,8 @@ -use crate::ToFields; -use ark_ff::BigInteger256; +use crate::{ByteConversion, FieldConversion}; +use ark_ff::{BigInteger256, PrimeField}; use mina_curves::pasta::Fp; -/// An object that represents a field element. +/// An alias that represents a field element. /// /// You can think of a field element as a the basic unit of data in zero knowledge proof programming. /// @@ -33,83 +33,44 @@ use mina_curves::pasta::Fp; /// Creat a field from bytes: /// /// ```rs -/// let big_integer = BigInteger256([ -/// u64::from_le_bytes(bytes[0..8].try_into().unwrap()), -/// u64::from_le_bytes(bytes[8..16].try_into().unwrap()), -/// u64::from_le_bytes(bytes[16..24].try_into().unwrap()), -/// u64::from_le_bytes(bytes[24..32].try_into().unwrap()), -/// ]) -/// -/// let field: Field = big_integer.into(); +/// let field: Field = Field::from_bytes(&bytes); /// ``` /// -/// Convert a field into bytes: +/// Convert a field to bytes: /// /// ```rs -/// let big_integer = field.into_repr(); -/// let bytes = [0_u8; 32]; -/// bytes[0..8].copy_from_slice(&big_integer.0[0].to_le_bytes()); -/// bytes[8..16].copy_from_slice(&big_integer.0[1].to_le_bytes()); -/// bytes[16..24].copy_from_slice(&big_integer.0[2].to_le_bytes()); -/// bytes[24..32].copy_from_slice(&big_integer.0[3].to_le_bytes()); +/// let bytes = field.to_bytes(); /// ``` /// pub type Field = Fp; -impl ToFields for Field { - type Fields = [Field; 1]; - +impl FieldConversion<1> for Field { fn to_fields(&self) -> [Field; 1] { - [*self] - } -} - -/// Converts a field element to its byte representation. -/// -/// # Examples -/// -/// ```rs -/// let bytes = field_to_bytes(&field); -/// ``` -/// -pub fn field_to_bytes(field: &Field) -> [u8; 32] { - let data = &field.0 .0; - - let mut bytes = [0_u8; 32]; - - for i in 0..4 { - bytes[i * 8..i * 8 + 8].copy_from_slice(&data[i].to_le_bytes()); + [self.to_owned()] } - - bytes } -/// Constructs a field element from bytes. -/// -/// # Examples -/// -/// ```rs -/// let field = field_from_bytes(&bytes); -/// ``` -/// -pub fn field_from_bytes(bytes: &[u8; 32]) -> Field { - Field::new(BigInteger256::new([ - u64::from_le_bytes(bytes[0..8].try_into().unwrap()), - u64::from_le_bytes(bytes[8..16].try_into().unwrap()), - u64::from_le_bytes(bytes[16..24].try_into().unwrap()), - u64::from_le_bytes(bytes[24..32].try_into().unwrap()), - ])) -} +impl ByteConversion<32> for Field { + fn to_bytes(&self) -> [u8; 32] { + let mut buf = [0u8; 32]; -#[test] -fn test_field_bytes_conversion() { - let original_field: Field = "4657651324657865143213749874615453498767487414568798746541" - .parse() - .unwrap(); + let u64s = self.into_repr().0; - let bytes = field_to_bytes(&original_field); + buf[0..8].copy_from_slice(&u64s[0].to_bytes()); + buf[8..16].copy_from_slice(&u64s[1].to_bytes()); + buf[16..24].copy_from_slice(&u64s[2].to_bytes()); + buf[24..32].copy_from_slice(&u64s[3].to_bytes()); - let restored_field = field_from_bytes(&bytes); + buf + } - assert_eq!(original_field, restored_field); + fn from_bytes(bytes: &[u8; 32]) -> Self { + BigInteger256::new([ + u64::from_le_bytes(bytes[0..8].try_into().unwrap()), + u64::from_le_bytes(bytes[8..16].try_into().unwrap()), + u64::from_le_bytes(bytes[16..24].try_into().unwrap()), + u64::from_le_bytes(bytes[24..32].try_into().unwrap()), + ]) + .into() + } } diff --git a/data-structures/src/field_conversion.rs b/data-structures/src/field_conversion.rs new file mode 100644 index 0000000..a1a1298 --- /dev/null +++ b/data-structures/src/field_conversion.rs @@ -0,0 +1,34 @@ +use crate::Field; + +/// The trait that is used to convert statically sized data structures to field elements. +/// +/// The constant generic parameter `L` represents the length of the field representation of the data structures. +pub trait FieldConversion { + /// Converts the data structure to field elements. + /// + /// # Examples + /// + /// Convert to fields: + /// + /// ```rs + /// let fields = data.to_fields(); + /// ``` + /// + fn to_fields(&self) -> [Field; L]; +} + +impl FieldConversion<1> for u64 { + fn to_fields(&self) -> [Field; 1] { + let field_0 = self.to_owned().into(); + + [field_0] + } +} + +impl FieldConversion<1> for bool { + fn to_fields(&self) -> [Field; 1] { + let field_0 = self.to_owned().into(); + + [field_0] + } +} diff --git a/data-structures/src/lib.rs b/data-structures/src/lib.rs index 512ed4d..6fcc5a3 100644 --- a/data-structures/src/lib.rs +++ b/data-structures/src/lib.rs @@ -1,14 +1,16 @@ mod address; mod balance; mod burn; +mod byte_conversion; mod deposit; mod field; +mod field_conversion; mod from_bytes; mod liquidity; mod pool; +mod scalar; mod signature; -mod to_bytes; -mod to_fields; +mod state_roots; mod transaction; mod tx_status; mod u256; @@ -16,13 +18,15 @@ mod u256; pub use address::Address; pub use balance::Balance; pub use burn::Burn; -pub use field::{field_from_bytes, field_to_bytes, Field}; +pub use byte_conversion::ByteConversion; +pub use field::Field; +pub use field_conversion::FieldConversion; pub use from_bytes::FromBytes; pub use liquidity::Liquidity; pub use pool::Pool; +pub(crate) use scalar::{field_to_scalar, scalar_to_field, Scalar}; pub use signature::Signature; -pub use to_bytes::ToBytes; -pub use to_fields::ToFields; +pub use state_roots::StateRoots; pub use transaction::Transaction; pub use tx_status::TxStatus; pub use u256::U256; diff --git a/data-structures/src/liquidity.rs b/data-structures/src/liquidity.rs index 533e048..d6a00d6 100644 --- a/data-structures/src/liquidity.rs +++ b/data-structures/src/liquidity.rs @@ -1,4 +1,4 @@ -use crate::{Address, Field, FromBytes, ToBytes, ToFields, U256}; +use crate::{Address, ByteConversion, Field, FieldConversion, U256}; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Liquidity { @@ -8,39 +8,19 @@ pub struct Liquidity { pub points: U256, } -impl ToFields for Liquidity { - type Fields = [Field; 5]; +impl FieldConversion<5> for Liquidity { + fn to_fields(&self) -> [Field; 5] { + let [field_0, field_1] = self.provider.to_fields(); + let [field_2] = self.base_token_id.to_fields(); + let [field_3] = self.quote_token_id.to_fields(); + let [field_4] = self.points.to_fields(); - fn to_fields(&self) -> Self::Fields { - let provider = self.provider.to_fields(); - - [ - provider[0], - provider[1], - (&self.base_token_id).into(), - (&self.quote_token_id).into(), - (&self.points).into(), - ] - } -} - -impl FromBytes for Liquidity { - type Bytes = [u8; 151]; - - fn from_bytes(bytes: Self::Bytes) -> Self { - Self { - provider: Address::from_bytes(bytes[0..55].try_into().unwrap()), - base_token_id: U256::from_bytes(bytes[55..87].try_into().unwrap()), - quote_token_id: U256::from_bytes(bytes[87..119].try_into().unwrap()), - points: U256::from_bytes(bytes[119..151].try_into().unwrap()), - } + [field_0, field_1, field_2, field_3, field_4] } } -impl ToBytes for Liquidity { - type Bytes = [u8; 151]; - - fn to_bytes(&self) -> Self::Bytes { +impl ByteConversion<151> for Liquidity { + fn to_bytes(&self) -> [u8; 151] { let mut bytes = [0u8; 151]; bytes[0..55].copy_from_slice(&self.provider.to_bytes()); @@ -50,4 +30,13 @@ impl ToBytes for Liquidity { bytes } + + fn from_bytes(bytes: &[u8; 151]) -> Self { + Self { + provider: Address::from_bytes(bytes[0..55].try_into().unwrap()), + base_token_id: U256::from_bytes(bytes[55..87].try_into().unwrap()), + quote_token_id: U256::from_bytes(bytes[87..119].try_into().unwrap()), + points: U256::from_bytes(bytes[119..151].try_into().unwrap()), + } + } } diff --git a/data-structures/src/pool.rs b/data-structures/src/pool.rs index 6d4fb06..8511c6c 100644 --- a/data-structures/src/pool.rs +++ b/data-structures/src/pool.rs @@ -1,4 +1,4 @@ -use crate::{Field, FromBytes, ToBytes, ToFields, U256}; +use crate::{ByteConversion, Field, FieldConversion, U256}; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Pool { @@ -9,38 +9,20 @@ pub struct Pool { pub total_liqudity_points: U256, } -impl ToFields for Pool { - type Fields = [Field; 5]; +impl FieldConversion<5> for Pool { + fn to_fields(&self) -> [Field; 5] { + let [field_0] = self.base_token_id.to_fields(); + let [field_1] = self.quote_token_id.to_fields(); + let [field_2] = self.base_token_amount.to_fields(); + let [field_3] = self.quote_token_amount.to_fields(); + let [field_4] = self.total_liqudity_points.to_fields(); - fn to_fields(&self) -> Self::Fields { - [ - (&self.base_token_id).into(), - (&self.quote_token_id).into(), - self.base_token_amount.into(), - self.quote_token_amount.into(), - (&self.total_liqudity_points).into(), - ] + [field_0, field_1, field_2, field_3, field_4] } } -impl FromBytes for Pool { - type Bytes = [u8; 112]; - - fn from_bytes(bytes: Self::Bytes) -> Self { - Self { - base_token_id: U256::from_bytes(bytes[0..32].try_into().unwrap()), - quote_token_id: U256::from_bytes(bytes[32..64].try_into().unwrap()), - base_token_amount: u64::from_bytes(bytes[64..72].try_into().unwrap()), - quote_token_amount: u64::from_bytes(bytes[72..80].try_into().unwrap()), - total_liqudity_points: U256::from_bytes(bytes[80..112].try_into().unwrap()), - } - } -} - -impl ToBytes for Pool { - type Bytes = [u8; 112]; - - fn to_bytes(&self) -> Self::Bytes { +impl ByteConversion<112> for Pool { + fn to_bytes(&self) -> [u8; 112] { let mut bytes = [0u8; 112]; bytes[0..32].copy_from_slice(&self.base_token_id.to_bytes()); @@ -51,4 +33,14 @@ impl ToBytes for Pool { bytes } + + fn from_bytes(bytes: &[u8; 112]) -> Self { + Self { + base_token_id: U256::from_bytes(bytes[0..32].try_into().unwrap()), + quote_token_id: U256::from_bytes(bytes[32..64].try_into().unwrap()), + base_token_amount: u64::from_bytes(bytes[64..72].try_into().unwrap()), + quote_token_amount: u64::from_bytes(bytes[72..80].try_into().unwrap()), + total_liqudity_points: U256::from_bytes(bytes[80..112].try_into().unwrap()), + } + } } diff --git a/data-structures/src/scalar.rs b/data-structures/src/scalar.rs new file mode 100644 index 0000000..8fa7da2 --- /dev/null +++ b/data-structures/src/scalar.rs @@ -0,0 +1,29 @@ +use ark_ff::PrimeField; +use mina_signer::ScalarField; + +use crate::Field; + +/// An alias that represents a scalar field element. +pub(crate) type Scalar = ScalarField; + +/// Converts the given field element into a scalar. +/// +/// # Examples +/// +/// ```rs +/// let scalar = field_to_scalar(42.into()); +/// ``` +pub(crate) fn field_to_scalar(field: Field) -> Scalar { + field.into_repr().into() +} + +/// Converts the given scalar into a field element. +/// +/// # Examples +/// +/// ```rs +/// let field = scalar_to_field(42.into()); +/// ``` +pub(crate) fn scalar_to_field(scalar: Scalar) -> Field { + scalar.into_repr().into() +} diff --git a/data-structures/src/signature.rs b/data-structures/src/signature.rs index c5e9728..7207af2 100644 --- a/data-structures/src/signature.rs +++ b/data-structures/src/signature.rs @@ -1,74 +1,36 @@ -use crate::{FromBytes, ToBytes}; +use crate::{ + ByteConversion, Field, Scalar, {field_to_scalar, scalar_to_field}, +}; +use mina_signer::Signature as MinaSignature; -/// Byte representation of base 58 encoded signatures. +/// A signature that is created by signing a message. #[derive(Clone, Debug)] -pub struct Signature([u8; 96]); - -impl Signature { - // Example: 7mXM6pRXQCpjaqFuJ2omcZgvHwc6LybAqQwV92RfTecqcnSuPCspXehtawpCJjrBJMnRW2jxLd7zzqqckTUp9vzjrvCH2ghW - // Regexp: /^7mX[1-9A-HJ-NP-Za-km-z]{93}$/ - pub fn is_valid(sign: &str) -> Result<(), ()> { - if sign.len() != 96 { - return Err(()); - } - - if sign[0..3].as_bytes() != [55, 109, 88] { - return Err(()); - } - - for c in sign.bytes() { - match c { - b'1'..=b'9' - | b'A'..=b'H' - | b'J'..=b'N' - | b'P'..=b'Z' - | b'a'..=b'k' - | b'm'..=b'z' => (), - _ => return Err(()), - } - } - - Ok(()) - } +pub struct Signature { + pub inner: MinaSignature, } -impl FromBytes for Signature { - type Bytes = [u8; 96]; +impl ByteConversion<64> for Signature { + fn to_bytes(&self) -> [u8; 64] { + let mut bytes = [0u8; 64]; - fn from_bytes(bytes: Self::Bytes) -> Self { - Signature(bytes) - } -} + bytes[0..32].copy_from_slice(&self.inner.rx.to_bytes()); + bytes[32..64].copy_from_slice(&scalar_to_field(self.inner.s).to_bytes()); -impl ToBytes for Signature { - type Bytes = [u8; 96]; + bytes + } - fn to_bytes(&self) -> Self::Bytes { - self.0 + fn from_bytes(bytes: &[u8; 64]) -> Self { + Signature::new( + Field::from_bytes(bytes[0..32].try_into().unwrap()), + field_to_scalar(Field::from_bytes(bytes[32..64].try_into().unwrap())), + ) } } -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn checks_if_signature_is_valid() { - // /^7mX[1-9A-HJ-NP-Za-km-z]{93}$/ - - let sign = "7mXM6pRXQCpjaqFuJ2omcZgvHwc6LybAqQwV92RfTecqcnSuPCspXehtawpCJjrBJMnRW2jxLd7zzqqckTUp9vzjrvCH2ghW"; - assert_eq!(Signature::is_valid(sign), Ok(())); - - let sign = "7mcM6pRXQCpjaqFuJ2omcZgvHwc6LybAqQwV92RfTecqcnSuPCspXehtawpCJjrBJMnRW2jxLd7zzqqckTUp9vzjrvCH2ghW"; - assert_eq!(Signature::is_valid(sign), Err(())); - - let sign = "7mXM6pRXQCpjaqFuJ2omcZgvHwc6LybAqQwV92IfTecqciSuPCspXihtawpCJjrBJMnRW2jxLd7zzqqckTUp9vzjrvCH2ghW"; - assert_eq!(Signature::is_valid(sign), Err(())); - - let sign = "7mXM6pRXQCpjaqFuJ2omcZgvHwc6LybAqQwV92IfTepCJjrBJMnRW2jxBJMnRW2jxLd7zzqqckTUp9vzjrvCH2ghW"; - assert_eq!(Signature::is_valid(sign), Err(())); - - let sign = "7mXM6pRXQCpjaqFuJ2omcZgvHwc6LybAqQwV92IfTecqciSuPCspXihtawpCJjrBJMnRW2jxBJMnRW2jxLd7zzqqckTUp9vzjrvCH2ghW"; - assert_eq!(Signature::is_valid(sign), Err(())); +impl Signature { + pub fn new(r: Field, s: Scalar) -> Signature { + Signature { + inner: MinaSignature::new(r, s), + } } } diff --git a/data-structures/src/state_roots.rs b/data-structures/src/state_roots.rs new file mode 100644 index 0000000..34cc471 --- /dev/null +++ b/data-structures/src/state_roots.rs @@ -0,0 +1,31 @@ +use crate::{ByteConversion, U256}; + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct StateRoots { + balances: U256, + liquidities: U256, + pools: U256, + burns: U256, +} + +impl ByteConversion<128> for StateRoots { + fn to_bytes(&self) -> [u8; 128] { + let mut buf = [0u8; 128]; + + buf[0..32].copy_from_slice(&self.balances.to_bytes()); + buf[32..64].copy_from_slice(&self.liquidities.to_bytes()); + buf[64..96].copy_from_slice(&self.pools.to_bytes()); + buf[96..128].copy_from_slice(&self.burns.to_bytes()); + + buf + } + + fn from_bytes(bytes: &[u8; 128]) -> Self { + Self { + balances: U256::from_bytes(bytes[0..32].try_into().unwrap()), + liquidities: U256::from_bytes(bytes[32..64].try_into().unwrap()), + pools: U256::from_bytes(bytes[64..96].try_into().unwrap()), + burns: U256::from_bytes(bytes[96..128].try_into().unwrap()), + } + } +} diff --git a/data-structures/src/to_bytes.rs b/data-structures/src/to_bytes.rs deleted file mode 100644 index d92e577..0000000 --- a/data-structures/src/to_bytes.rs +++ /dev/null @@ -1,21 +0,0 @@ -pub trait ToBytes { - type Bytes; - - fn to_bytes(&self) -> Self::Bytes; -} - -impl ToBytes for u64 { - type Bytes = [u8; 8]; - - fn to_bytes(&self) -> Self::Bytes { - self.to_le_bytes() - } -} - -impl ToBytes for u128 { - type Bytes = [u8; 16]; - - fn to_bytes(&self) -> Self::Bytes { - self.to_le_bytes() - } -} diff --git a/data-structures/src/to_fields.rs b/data-structures/src/to_fields.rs deleted file mode 100644 index c557b51..0000000 --- a/data-structures/src/to_fields.rs +++ /dev/null @@ -1,37 +0,0 @@ -/// The trait that is implemented for the data structures that can be converted to `Field` elements. -/// -/// # Examples -/// -/// Define a type to implement `ToFields`: -/// -/// ```rs -/// pub struct User { -/// pub age: Field, -/// pub points: Field. -/// } -///``` -/// -/// Implement `ToFields`: -/// -/// ```rs -/// impl ToFields<2> for User { -/// fn to_fields(&self) -> [Field; 2] { -/// [self.age, self.points] -/// } -/// } -/// ``` -/// -pub trait ToFields { - type Fields; - /// Converts the data into `Field` elements. - /// - /// # Examples - /// - /// Convert a data into fields: - /// - /// ```rs - /// let fields = data.to_fields(); - /// ``` - /// - fn to_fields(&self) -> Self::Fields; -} diff --git a/data-structures/src/transaction.rs b/data-structures/src/transaction.rs index d17d984..1d5f2ab 100644 --- a/data-structures/src/transaction.rs +++ b/data-structures/src/transaction.rs @@ -1,4 +1,4 @@ -use crate::{Address, FromBytes, Signature, ToBytes, U256}; +use crate::{Address, ByteConversion, Signature, U256}; /// The enum that represents transaction types. #[derive(Clone, Debug)] @@ -52,65 +52,11 @@ pub enum Transaction { }, } -impl From<[u8; 264]> for Transaction { - fn from(value: [u8; 264]) -> Self { - match value[0] { - 0 => Self::BurnTokens { - address: Address::from_bytes(value[1..56].try_into().unwrap()), - signature: Signature::from_bytes(value[56..152].try_into().unwrap()), - token_id: U256::from_bytes(value[152..184].try_into().unwrap()), - token_amount: u64::from_le_bytes(value[184..192].try_into().unwrap()), - }, - 1 => Self::CreatePool { - address: Address::from_bytes(value[1..56].try_into().unwrap()), - signature: Signature::from_bytes(value[56..152].try_into().unwrap()), - base_token_id: U256::from_bytes(value[152..184].try_into().unwrap()), - quote_token_id: U256::from_bytes(value[184..216].try_into().unwrap()), - base_token_amount: u64::from_le_bytes(value[216..224].try_into().unwrap()), - quote_token_amount: u64::from_le_bytes(value[224..232].try_into().unwrap()), - }, - 2 => Self::ProvideLiquidity { - address: Address::from_bytes(value[1..56].try_into().unwrap()), - signature: Signature::from_bytes(value[56..152].try_into().unwrap()), - base_token_id: U256::from_bytes(value[152..184].try_into().unwrap()), - quote_token_id: U256::from_bytes(value[184..216].try_into().unwrap()), - base_token_amount: u64::from_le_bytes(value[216..224].try_into().unwrap()), - quote_token_amount_limit: u64::from_le_bytes(value[224..232].try_into().unwrap()), - }, - 3 => Self::RemoveLiquidity { - address: Address::from_bytes(value[1..56].try_into().unwrap()), - signature: Signature::from_bytes(value[56..152].try_into().unwrap()), - base_token_id: U256::from_bytes(value[152..184].try_into().unwrap()), - quote_token_id: U256::from_bytes(value[184..216].try_into().unwrap()), - base_token_amount_limit: u64::from_le_bytes(value[216..224].try_into().unwrap()), - quote_token_amount_limit: u64::from_le_bytes(value[224..232].try_into().unwrap()), - points: U256::from_bytes(value[232..264].try_into().unwrap()), - }, - 4 => Self::BuyTokens { - address: Address::from_bytes(value[1..56].try_into().unwrap()), - signature: Signature::from_bytes(value[56..152].try_into().unwrap()), - base_token_id: U256::from_bytes(value[152..184].try_into().unwrap()), - quote_token_id: U256::from_bytes(value[184..216].try_into().unwrap()), - base_token_amount: u64::from_le_bytes(value[216..224].try_into().unwrap()), - quote_token_amount_limit: u64::from_le_bytes(value[224..232].try_into().unwrap()), - }, - _ => Self::SellTokens { - address: Address::from_bytes(value[1..56].try_into().unwrap()), - signature: Signature::from_bytes(value[56..152].try_into().unwrap()), - base_token_id: U256::from_bytes(value[152..184].try_into().unwrap()), - quote_token_id: U256::from_bytes(value[184..216].try_into().unwrap()), - base_token_amount_limit: u64::from_le_bytes(value[216..224].try_into().unwrap()), - quote_token_amount: u64::from_le_bytes(value[224..232].try_into().unwrap()), - }, - } - } -} - -impl From<&Transaction> for [u8; 264] { - fn from(value: &Transaction) -> Self { - let mut buf = [0u8; 264]; +impl ByteConversion<232> for Transaction { + fn to_bytes(&self) -> [u8; 232] { + let mut buf = [0u8; 232]; - match value { + match self { Transaction::BurnTokens { address, signature, @@ -119,9 +65,9 @@ impl From<&Transaction> for [u8; 264] { } => { buf[0] = 0; buf[1..56].copy_from_slice(&address.to_bytes()); - buf[56..152].copy_from_slice(&signature.to_bytes()); - buf[152..184].copy_from_slice(&token_id.to_bytes()); - buf[184..192].copy_from_slice(&token_amount.to_bytes()); + buf[56..120].copy_from_slice(&signature.to_bytes()); + buf[120..152].copy_from_slice(&token_id.to_bytes()); + buf[152..160].copy_from_slice(&token_amount.to_bytes()); } Transaction::CreatePool { address, @@ -133,11 +79,11 @@ impl From<&Transaction> for [u8; 264] { } => { buf[0] = 1; buf[1..56].copy_from_slice(&address.to_bytes()); - buf[56..152].copy_from_slice(&signature.to_bytes()); - buf[152..184].copy_from_slice(&base_token_id.to_bytes()); - buf[184..216].copy_from_slice("e_token_id.to_bytes()); - buf[216..224].copy_from_slice(&base_token_amount.to_bytes()); - buf[224..232].copy_from_slice("e_token_amount.to_bytes()); + buf[56..120].copy_from_slice(&signature.to_bytes()); + buf[120..152].copy_from_slice(&base_token_id.to_bytes()); + buf[152..184].copy_from_slice("e_token_id.to_bytes()); + buf[184..192].copy_from_slice(&base_token_amount.to_bytes()); + buf[192..200].copy_from_slice("e_token_amount.to_bytes()); } Transaction::ProvideLiquidity { address, @@ -149,11 +95,11 @@ impl From<&Transaction> for [u8; 264] { } => { buf[0] = 2; buf[1..56].copy_from_slice(&address.to_bytes()); - buf[56..152].copy_from_slice(&signature.to_bytes()); - buf[152..184].copy_from_slice(&base_token_id.to_bytes()); - buf[184..216].copy_from_slice("e_token_id.to_bytes()); - buf[216..224].copy_from_slice(&base_token_amount.to_bytes()); - buf[224..232].copy_from_slice("e_token_amount_limit.to_bytes()); + buf[56..120].copy_from_slice(&signature.to_bytes()); + buf[120..152].copy_from_slice(&base_token_id.to_bytes()); + buf[152..184].copy_from_slice("e_token_id.to_bytes()); + buf[184..192].copy_from_slice(&base_token_amount.to_bytes()); + buf[192..200].copy_from_slice("e_token_amount_limit.to_bytes()); } Transaction::RemoveLiquidity { address, @@ -166,12 +112,12 @@ impl From<&Transaction> for [u8; 264] { } => { buf[0] = 3; buf[1..56].copy_from_slice(&address.to_bytes()); - buf[56..152].copy_from_slice(&signature.to_bytes()); - buf[152..184].copy_from_slice(&base_token_id.to_bytes()); - buf[184..216].copy_from_slice("e_token_id.to_bytes()); - buf[216..224].copy_from_slice(&base_token_amount_limit.to_bytes()); - buf[224..232].copy_from_slice("e_token_amount_limit.to_bytes()); - buf[232..264].copy_from_slice(&liquidity_point_amount.to_bytes()); + buf[56..120].copy_from_slice(&signature.to_bytes()); + buf[120..152].copy_from_slice(&base_token_id.to_bytes()); + buf[152..184].copy_from_slice("e_token_id.to_bytes()); + buf[184..192].copy_from_slice(&base_token_amount_limit.to_bytes()); + buf[192..200].copy_from_slice("e_token_amount_limit.to_bytes()); + buf[200..232].copy_from_slice(&liquidity_point_amount.to_bytes()); } Transaction::BuyTokens { address, @@ -183,11 +129,11 @@ impl From<&Transaction> for [u8; 264] { } => { buf[0] = 4; buf[1..56].copy_from_slice(&address.to_bytes()); - buf[56..152].copy_from_slice(&signature.to_bytes()); - buf[152..184].copy_from_slice(&base_token_id.to_bytes()); - buf[184..216].copy_from_slice("e_token_id.to_bytes()); - buf[216..224].copy_from_slice(&base_token_amount.to_bytes()); - buf[224..232].copy_from_slice("e_token_amount_limit.to_bytes()); + buf[56..120].copy_from_slice(&signature.to_bytes()); + buf[120..152].copy_from_slice(&base_token_id.to_bytes()); + buf[152..184].copy_from_slice("e_token_id.to_bytes()); + buf[184..192].copy_from_slice(&base_token_amount.to_bytes()); + buf[192..200].copy_from_slice("e_token_amount_limit.to_bytes()); } Transaction::SellTokens { address, @@ -199,14 +145,66 @@ impl From<&Transaction> for [u8; 264] { } => { buf[0] = 5; buf[1..56].copy_from_slice(&address.to_bytes()); - buf[56..152].copy_from_slice(&signature.to_bytes()); - buf[152..184].copy_from_slice(&base_token_id.to_bytes()); - buf[184..216].copy_from_slice("e_token_id.to_bytes()); - buf[216..224].copy_from_slice(&base_token_amount_limit.to_bytes()); - buf[224..232].copy_from_slice("e_token_amount.to_bytes()); + buf[56..120].copy_from_slice(&signature.to_bytes()); + buf[120..152].copy_from_slice(&base_token_id.to_bytes()); + buf[152..184].copy_from_slice("e_token_id.to_bytes()); + buf[184..192].copy_from_slice(&base_token_amount_limit.to_bytes()); + buf[192..200].copy_from_slice("e_token_amount.to_bytes()); } } buf } + + fn from_bytes(bytes: &[u8; 232]) -> Self { + match bytes[0] { + 0 => Self::BurnTokens { + address: Address::from_bytes(bytes[1..56].try_into().unwrap()), + signature: Signature::from_bytes(bytes[56..120].try_into().unwrap()), + token_id: U256::from_bytes(bytes[120..152].try_into().unwrap()), + token_amount: u64::from_le_bytes(bytes[152..160].try_into().unwrap()), + }, + 1 => Self::CreatePool { + address: Address::from_bytes(bytes[1..56].try_into().unwrap()), + signature: Signature::from_bytes(bytes[56..120].try_into().unwrap()), + base_token_id: U256::from_bytes(bytes[120..152].try_into().unwrap()), + quote_token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), + base_token_amount: u64::from_le_bytes(bytes[184..192].try_into().unwrap()), + quote_token_amount: u64::from_le_bytes(bytes[192..200].try_into().unwrap()), + }, + 2 => Self::ProvideLiquidity { + address: Address::from_bytes(bytes[1..56].try_into().unwrap()), + signature: Signature::from_bytes(bytes[56..120].try_into().unwrap()), + base_token_id: U256::from_bytes(bytes[120..152].try_into().unwrap()), + quote_token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), + base_token_amount: u64::from_le_bytes(bytes[184..192].try_into().unwrap()), + quote_token_amount_limit: u64::from_le_bytes(bytes[192..200].try_into().unwrap()), + }, + 3 => Self::RemoveLiquidity { + address: Address::from_bytes(bytes[1..56].try_into().unwrap()), + signature: Signature::from_bytes(bytes[56..120].try_into().unwrap()), + base_token_id: U256::from_bytes(bytes[120..152].try_into().unwrap()), + quote_token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), + base_token_amount_limit: u64::from_le_bytes(bytes[184..192].try_into().unwrap()), + quote_token_amount_limit: u64::from_le_bytes(bytes[192..200].try_into().unwrap()), + points: U256::from_bytes(bytes[200..232].try_into().unwrap()), + }, + 4 => Self::BuyTokens { + address: Address::from_bytes(bytes[1..56].try_into().unwrap()), + signature: Signature::from_bytes(bytes[56..120].try_into().unwrap()), + base_token_id: U256::from_bytes(bytes[120..152].try_into().unwrap()), + quote_token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), + base_token_amount: u64::from_le_bytes(bytes[184..192].try_into().unwrap()), + quote_token_amount_limit: u64::from_le_bytes(bytes[192..200].try_into().unwrap()), + }, + _ => Self::SellTokens { + address: Address::from_bytes(bytes[1..56].try_into().unwrap()), + signature: Signature::from_bytes(bytes[56..120].try_into().unwrap()), + base_token_id: U256::from_bytes(bytes[120..152].try_into().unwrap()), + quote_token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), + base_token_amount_limit: u64::from_le_bytes(bytes[184..192].try_into().unwrap()), + quote_token_amount: u64::from_le_bytes(bytes[192..200].try_into().unwrap()), + }, + } + } } diff --git a/data-structures/src/tx_status.rs b/data-structures/src/tx_status.rs index 2b2ff5a..362db0a 100644 --- a/data-structures/src/tx_status.rs +++ b/data-structures/src/tx_status.rs @@ -1,5 +1,7 @@ +use crate::ByteConversion; + /// The enum that represents a transaction's status. -#[derive(PartialEq, Eq, Debug)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum TxStatus { /// The status which means the transaction is pending. Pending, @@ -12,3 +14,19 @@ pub enum TxStatus { /// The status which means the zk proof that includes the transaction is settled to the L1 contract. Settled, } + +impl ByteConversion<1> for TxStatus { + fn to_bytes(&self) -> [u8; 1] { + [self.to_owned() as u8] + } + + fn from_bytes(bytes: &[u8; 1]) -> Self { + match bytes[0] { + 0 => Self::Pending, + 1 => Self::Rejected, + 2 => Self::Executed, + 3 => Self::Proved, + _ => Self::Settled, + } + } +} diff --git a/data-structures/src/u256.rs b/data-structures/src/u256.rs index b63a608..be0b6bf 100644 --- a/data-structures/src/u256.rs +++ b/data-structures/src/u256.rs @@ -3,41 +3,33 @@ use std::ops::{Add, Div, Mul, Sub}; use ark_ff::{BigInteger256, PrimeField}; -use crate::{Field, FromBytes, ToBytes}; +use crate::{ByteConversion, Field, FieldConversion}; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct U256(pub [u8; 32]); -impl FromBytes for U256 { - type Bytes = [u8; 32]; +impl FieldConversion<1> for U256 { + fn to_fields(&self) -> [Field; 1] { + let u64s: [u64; 4] = [ + u64::from_le_bytes(self.0[0..8].try_into().unwrap()), + u64::from_le_bytes(self.0[8..16].try_into().unwrap()), + u64::from_le_bytes(self.0[16..24].try_into().unwrap()), + u64::from_le_bytes(self.0[24..32].try_into().unwrap()), + ]; - fn from_bytes(bytes: Self::Bytes) -> Self { - U256(bytes) + let bigint = BigInteger256(u64s); + + [bigint.into()] } } -impl ToBytes for U256 { - type Bytes = [u8; 32]; - - fn to_bytes(&self) -> Self::Bytes { +impl ByteConversion<32> for U256 { + fn to_bytes(&self) -> [u8; 32] { self.0 } -} - -impl From<&U256> for Field { - fn from(value: &U256) -> Self { - let u64s: [u64; 4] = [ - u64::from_le_bytes(value.0[0..8].try_into().unwrap()), - u64::from_le_bytes(value.0[8..16].try_into().unwrap()), - u64::from_le_bytes(value.0[16..24].try_into().unwrap()), - u64::from_le_bytes(value.0[24..32].try_into().unwrap()), - ]; - - let bigint = BigInteger256(u64s); - - let field: Field = bigint.into(); - field + fn from_bytes(bytes: &[u8; 32]) -> Self { + U256(bytes.to_owned()) } } diff --git a/dynamic-queue/Cargo.toml b/dynamic-queue/Cargo.toml index 3393221..a7aed46 100644 --- a/dynamic-queue/Cargo.toml +++ b/dynamic-queue/Cargo.toml @@ -9,3 +9,4 @@ edition = "2021" # Crates.io dependencies. thiserror.workspace = true tokio.workspace = true +nacho-data-structures.workspace = true diff --git a/dynamic-queue/src/dynamic_queue.rs b/dynamic-queue/src/dynamic_queue.rs index 484a0de..a38c266 100644 --- a/dynamic-queue/src/dynamic_queue.rs +++ b/dynamic-queue/src/dynamic_queue.rs @@ -1,4 +1,5 @@ use crate::error::DynamicQueueError; +use nacho_data_structures::ByteConversion; use std::{io::SeekFrom, marker::PhantomData, path::Path}; use tokio::{ fs::{create_dir_all, File, OpenOptions}, @@ -7,70 +8,102 @@ use tokio::{ type Result = std::result::Result; -/// An on-disk FIFO (first in, first out) queue optimized for constant memory usage, high performance, and low disk usage. +/// An on-disk FIFO (first in, first out) queue optimized for constant memory usage, high performance and low disk usage. /// /// Items are stored in a file and it has a garbage collector to remove popped items from disk. /// -/// The constant generic parameter `C` represents the size of each item in bytes. +/// The constant generic parameter `L` represents the size of each item in bytes. /// /// The generic parameter `T` represents the type of the data structure that is going to be stored. /// -/// It requires the type `T` to implement `Into<[u8; C]>` and the type `&T` to implement `From<[u8; C]>`traits. +/// It requires the type `T` to implement `ByteConversion`trait. /// -pub struct DynamicQueue +/// # Examples +/// +/// Define a type: +/// +/// ```rs +/// struct User { +/// points: u16, +/// } +/// ``` +/// +/// Implement `ByteConversion` trait: +/// +/// ```rs +/// impl ByteConversion<2> for User { +/// fn to_bytes(&self) -> [u8; 2] { +/// self.points.to_le_bytes() +/// } +/// +/// fn from_bytes(bytes: &[u8; 2]) -> Self { +/// User { +/// points: u16::from_le_bytes(bytes.to_owned()), +/// } +/// } +/// } +/// ``` +/// +/// Create a queue: +/// ```rs +/// let queue = Queue::<2, User>::new("tmp/nacho/tests/dynamic_queue_for_users").await?; +/// ``` +/// +/// Push an item: +/// +/// ```rs +/// queue.push(&user).await?; +/// ``` +/// +/// Pop an item: +/// +/// ```rs +/// let item: Option = queue.pop().await?; +/// ``` +/// +pub struct DynamicQueue where - for<'a> &'a T: Into<[u8; C]>, - T: From<[u8; C]>, + T: ByteConversion, { file: File, phantom: PhantomData, } -impl DynamicQueue +impl DynamicQueue where - for<'a> &'a T: Into<[u8; C]>, - T: From<[u8; C]>, + T: ByteConversion, { /// Creates a new `Queue` at the given path. /// /// # Examples /// - /// Create and implement a type that meets the requirements: + /// Define a type: /// /// ```rs /// struct User { /// points: u16, /// } + /// ``` /// - /// impl From<[u8; 2]> for User { - /// fn from(value: [u8; 2]) -> Self { - /// Self { points: u16::from_le_bytes(value) } + /// Implement `ByteConversion` trait: + /// + /// ```rs + /// impl ByteConversion<2> for User { + /// fn to_bytes(&self) -> [u8; 2] { + /// self.points.to_le_bytes() /// } - /// } /// - /// impl From<&User> for [u8; 2] { - /// fn from(value: &User) -> [u8; 2] { - /// value.points.to_le_bytes() + /// fn from_bytes(bytes: &[u8; 2]) -> Self { + /// User { + /// points: u16::from_le_bytes(bytes.to_owned()), + /// } /// } /// } /// ``` /// /// Create a queue: /// ```rs - /// let queue = Queue::<4, T>::new("tmp/nacho/tests/queue").await?; - /// ``` - /// - /// Push an item: - /// - /// ```rs - /// let item = User { points: 42 }; - /// queue.push(&item).await?; - /// ``` - /// - /// Pop an item: - /// - /// ```rs - /// let item: Option = queue.pop().await?; + /// let queue = Queue::<2, User>::new("tmp/nacho/tests/dynamic_queue_for_users").await?; /// ``` /// pub async fn new(path: impl AsRef) -> Result { @@ -116,7 +149,7 @@ where /// ``` /// pub async fn push(&mut self, item: &T) -> Result<()> { - let item: [u8; C] = item.into(); + let item = item.to_bytes(); let file_len = self.get_file_len().await?; @@ -159,14 +192,14 @@ where let new_pointer = match item { Some(_) => { - let new_pointer = pointer + C as u64; + let new_pointer = pointer + L as u64; self.set_pointer(new_pointer).await?; new_pointer } None => pointer, }; - if new_pointer == 8 + 128 * C as u64 { + if new_pointer == 8 + 128 * L as u64 { self.run_garbage_collector(file_len, new_pointer).await?; } @@ -277,7 +310,7 @@ where async fn run_garbage_collector(&mut self, file_len: u64, pointer: u64) -> Result<()> { let content_size = file_len - pointer; let new_file_len = content_size + 8; - let items_count = content_size / C as u64; + let items_count = content_size / L as u64; let (chunk_count, chunks_len, remaining_count) = match items_count { ..=127 => (0, 0, items_count), @@ -286,9 +319,9 @@ where }; for i in 0..chunks_len { - let mut buf = vec![0_u8; C * chunk_count]; + let mut buf = vec![0_u8; L * chunk_count]; - let padding = C as u64 * i * chunk_count as u64; + let padding = L as u64 * i * chunk_count as u64; self.file.seek(SeekFrom::Start(pointer + padding)).await?; self.file.read_exact(&mut buf).await?; @@ -298,9 +331,9 @@ where } if remaining_count != 0 { - let mut buf = vec![0_u8; C * remaining_count as usize]; + let mut buf = vec![0_u8; L * remaining_count as usize]; - let padding = C as u64 * chunks_len * chunk_count as u64; + let padding = L as u64 * chunks_len * chunk_count as u64; self.file.seek(SeekFrom::Start(pointer + padding)).await?; self.file.read_exact(&mut buf).await?; @@ -333,15 +366,15 @@ where /// #[inline] async fn read_oldest_item(&mut self, file_len: u64, pointer: u64) -> Result> { - let mut buf = [0_u8; C]; + let mut buf = [0_u8; L]; - if file_len < pointer + C as u64 { + if file_len < pointer + L as u64 { Ok(None) } else { self.file.seek(SeekFrom::Start(pointer)).await?; self.file.read_exact(&mut buf).await?; - let item: T = buf.into(); + let item: T = T::from_bytes(&buf); Ok(Some(item)) } @@ -358,23 +391,21 @@ mod tests { num: u32, } - impl From<[u8; 4]> for T { - fn from(value: [u8; 4]) -> Self { - Self { - num: u32::from_le_bytes(value), - } + impl ByteConversion<4> for T { + fn to_bytes(&self) -> [u8; 4] { + self.num.to_le_bytes() } - } - impl From<&T> for [u8; 4] { - fn from(value: &T) -> Self { - value.num.to_le_bytes() + fn from_bytes(bytes: &[u8; 4]) -> Self { + Self { + num: u32::from_le_bytes(bytes.to_owned()), + } } } #[tokio::test] - pub async fn creates_queue() -> std::result::Result<(), Box> { - let dir = "/tmp/nacho/tests/queue/creates_queue"; + pub async fn creates_dynamic_queue() -> std::result::Result<(), Box> { + let dir = "/tmp/nacho/tests/dynamic_queue/creates_queue"; let _ = DynamicQueue::<4, T>::new(dir).await?; @@ -398,7 +429,7 @@ mod tests { #[tokio::test] pub async fn pushes_and_pops_items() -> std::result::Result<(), Box> { - let dir = "/tmp/nacho/tests/queue/pushes_and_pops_items"; + let dir = "/tmp/nacho/tests/dynamic_queue/pushes_and_pops_items"; let mut queue = DynamicQueue::<4, T>::new(dir).await?; @@ -465,7 +496,7 @@ mod tests { #[tokio::test] pub async fn collects_garbage() -> std::result::Result<(), Box> { - let dir = "/tmp/nacho/tests/queue/collects_garbage"; + let dir = "/tmp/nacho/tests/dynamic_queue/collects_garbage"; let mut queue = DynamicQueue::<4, T>::new(dir).await?; diff --git a/generator/Cargo.toml b/generator/Cargo.toml new file mode 100644 index 0000000..91ad575 --- /dev/null +++ b/generator/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "nacho-generator" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +tokio.workspace = true +thiserror.workspace = true +nacho-data-structures.workspace = true +nacho-balances-db.workspace = true +nacho-liquidities-db.workspace = true +nacho-pools-db.workspace = true +nacho-burns-db.workspace = true diff --git a/generator/src/lib.rs b/generator/src/lib.rs new file mode 100644 index 0000000..58e278f --- /dev/null +++ b/generator/src/lib.rs @@ -0,0 +1 @@ +mod method; diff --git a/generator/src/method.rs b/generator/src/method.rs new file mode 100644 index 0000000..bb02e3b --- /dev/null +++ b/generator/src/method.rs @@ -0,0 +1,371 @@ +use nacho_balances_db::{DoubleBalanceWitness, SingleBalanceWitness}; +use nacho_burns_db::SingleBurnWitness; +use nacho_data_structures::{Address, Signature, StateRoots, U256}; +use nacho_liquidities_db::SingleLiquidityWitness; +use nacho_pools_db::SinglePoolWitness; + +/// The enum that represents method types. +#[derive(Clone, Debug)] +pub enum Method { + CreateGenesis { + state_roots: StateRoots, + }, + DepositTokens { + state_roots: StateRoots, + earlier_proof_index: u64, + single_balance_witness: SingleBalanceWitness, + current_deposits_merkle_list_hash: U256, + expected_deposits_merkle_list_hash: U256, + user_address: Address, + token_id: U256, + user_deposit_token_amount: u64, + user_balance_token_amount: u64, + is_users_first_deposit: bool, + }, + BurnTokens { + state_roots: StateRoots, + earlier_proof_index: u64, + single_balance_witness: SingleBalanceWitness, + single_burn_witness: SingleBurnWitness, + user_address: Address, + token_id: U256, + user_burn_token_amount: u64, + user_balance_token_amount: u64, + amount_to_burn: u64, + user_signature: Signature, + }, + CreatePool { + state_roots: StateRoots, + earlier_proof_index: u64, + single_pool_witness: SinglePoolWitness, + single_liquidity_witness: SingleLiquidityWitness, + double_balance_witness: DoubleBalanceWitness, + base_token_id: U256, + quote_token_id: U256, + user_address: Address, + user_liquidity_base_token_amount: u64, + user_liquidity_quote_token_amount: u64, + user_balance_base_token_amount: u64, + user_balance_quote_token_amount: u64, + user_signature: Signature, + }, + ProvideLiquidity { + state_roots: StateRoots, + earlier_proof_index: u64, + single_pool_witness: SinglePoolWitness, + single_liquidity_witness: SingleLiquidityWitness, + double_balance_witness: DoubleBalanceWitness, + base_token_id: U256, + quote_token_id: U256, + user_address: Address, + user_liquidity_points: U256, + user_balance_base_token_amount: u64, + user_balance_quote_token_amount: u64, + pool_base_token_amount: u64, + pool_quote_token_amount: u64, + pool_total_liquidity_points: U256, + user_base_token_amount_to_provide: u64, + user_quote_token_amount_limit_to_provide: u64, + is_first_providing: bool, + user_signature: Signature, + }, + RemoveLiquidity { + state_roots: StateRoots, + earlier_proof_index: u64, + single_pool_witness: SinglePoolWitness, + single_liquidity_witness: SingleLiquidityWitness, + double_balance_witness: DoubleBalanceWitness, + base_token_id: U256, + quote_token_id: U256, + user_address: Address, + user_liquidity_points: U256, + user_balance_base_token_amount: u64, + user_balance_quote_token_amount: u64, + pool_base_token_amount: u64, + pool_quote_token_amount: u64, + pool_total_liquidity_points: U256, + user_liquidity_points_to_remove: U256, + user_base_token_amount_limit_to_remove: u64, + user_quote_token_amount_limit_to_remove: u64, + user_signature: Signature, + }, + BuyTokens { + state_roots: StateRoots, + earlier_proof_index: u64, + single_pool_witness: SinglePoolWitness, + double_balance_witness: DoubleBalanceWitness, + user_address: Address, + base_token_id: U256, + quote_token_id: U256, + user_balance_base_token_amount: u64, + user_balance_quote_token_amount: u64, + pool_base_token_amount: u64, + pool_quote_token_amount: u64, + pool_total_liquidity_points: U256, + user_base_token_amount_to_swap: u64, + user_quote_token_amount_limit_to_swap: u64, + user_signature: Signature, + }, + SellTokens { + state_roots: StateRoots, + earlier_proof_index: u64, + single_pool_witness: SinglePoolWitness, + double_balance_witness: DoubleBalanceWitness, + user_address: Address, + base_token_id: U256, + quote_token_id: U256, + user_balance_base_token_amount: u64, + user_balance_quote_token_amount: u64, + pool_base_token_amount: u64, + pool_quote_token_amount: u64, + pool_total_liquidity_points: U256, + user_base_token_amount_limit_to_swap: u64, + user_quote_token_amount_to_swap: u64, + user_signature: Signature, + }, +} + +// impl ToBytes for Method { +// type Bytes = [u8; 3328]; + +// fn to_bytes(&self) -> Self::Bytes { +// let mut buf = [0; 3328]; + +// match self { +// Method::CreateGenesis { state_roots } => { +// buf[0] = 0; +// buf[1..129].copy_from_slice(&state_roots.to_bytes()); +// } +// Method::DepositTokens { +// state_roots, +// earlier_proof_index, +// single_balance_witness, +// current_deposits_merkle_list_hash, +// expected_deposits_merkle_list_hash, +// user_address, +// token_id, +// user_deposit_token_amount, +// user_balance_token_amount, +// is_users_first_deposit, +// } => { +// buf[0] = 1; +// buf[1..129].copy_from_slice(&state_roots.to_bytes()); +// buf[129..137].copy_from_slice(&earlier_proof_index.to_bytes()); +// buf[137..863].copy_from_slice(&single_balance_witness.to_bytes()); +// buf[863..895].copy_from_slice(¤t_deposits_merkle_list_hash.to_bytes()); +// buf[895..927].copy_from_slice(&expected_deposits_merkle_list_hash.to_bytes()); +// buf[927..982].copy_from_slice(&user_address.to_bytes()); +// buf[982..1014].copy_from_slice(&token_id.to_bytes()); +// buf[1014..1022].copy_from_slice(&user_deposit_token_amount.to_bytes()); +// buf[1022..1030].copy_from_slice(&user_balance_token_amount.to_bytes()); +// buf[1030] = *is_users_first_deposit as u8; +// } +// Method::BurnTokens { +// state_roots, +// earlier_proof_index, +// single_balance_witness, +// single_burn_witness, +// user_address, +// token_id, +// user_burn_token_amount, +// user_balance_token_amount, +// amount_to_burn, +// user_signature, +// } => { +// buf[0] = 2; +// buf[1..129].copy_from_slice(&state_roots.to_bytes()); +// buf[129..137].copy_from_slice(&earlier_proof_index.to_bytes()); +// buf[137..863].copy_from_slice(&single_balance_witness.to_bytes()); +// buf[863..1490].copy_from_slice(&single_burn_witness.to_bytes()); +// buf[1490..1545].copy_from_slice(&user_address.to_bytes()); +// buf[1545..1577].copy_from_slice(&token_id.to_bytes()); +// buf[1577..1585].copy_from_slice(&user_burn_token_amount.to_bytes()); +// buf[1585..1593].copy_from_slice(&user_balance_token_amount.to_bytes()); +// buf[1593..1601].copy_from_slice(&amount_to_burn.to_bytes()); +// buf[1601..1697].copy_from_slice(&user_signature.to_bytes()); +// } +// Method::CreatePool { +// state_roots, +// earlier_proof_index, +// single_pool_witness, +// single_liquidity_witness, +// double_balance_witness, +// base_token_id, +// quote_token_id, +// user_address, +// user_liquidity_base_token_amount, +// user_liquidity_quote_token_amount, +// user_balance_base_token_amount, +// user_balance_quote_token_amount, +// user_signature, +// } => { +// buf[0] = 3; +// buf[1..129].copy_from_slice(&state_roots.to_bytes()); +// buf[129..137].copy_from_slice(&earlier_proof_index.to_bytes()); +// buf[137..797].copy_from_slice(&single_pool_witness.to_bytes()); +// buf[797..1490].copy_from_slice(&single_liquidity_witness.to_bytes()); +// buf[1490..2964].copy_from_slice(&double_balance_witness.to_bytes()); +// buf[2964..2996].copy_from_slice(&base_token_id.to_bytes()); +// buf[2996..3028].copy_from_slice("e_token_id.to_bytes()); +// buf[3028..3083].copy_from_slice(&user_address.to_bytes()); +// buf[3083..3091].copy_from_slice(&user_liquidity_base_token_amount.to_bytes()); +// buf[3091..3099].copy_from_slice(&user_liquidity_quote_token_amount.to_bytes()); +// buf[3099..3107].copy_from_slice(&user_balance_base_token_amount.to_bytes()); +// buf[3107..3115].copy_from_slice(&user_balance_quote_token_amount.to_bytes()); +// buf[3115..3211].copy_from_slice(&user_signature.to_bytes()); +// } +// Method::ProvideLiquidity { +// state_roots, +// earlier_proof_index, +// single_pool_witness, +// single_liquidity_witness, +// double_balance_witness, +// base_token_id, +// quote_token_id, +// user_address, +// user_liquidity_points, +// user_balance_base_token_amount, +// user_balance_quote_token_amount, +// pool_base_token_amount, +// pool_quote_token_amount, +// pool_total_liquidity_points, +// user_base_token_amount_to_provide, +// user_quote_token_amount_limit_to_provide, +// is_first_providing, +// user_signature, +// } => { +// buf[0] = 4; +// buf[1..129].copy_from_slice(&state_roots.to_bytes()); +// buf[129..137].copy_from_slice(&earlier_proof_index.to_bytes()); +// buf[137..797].copy_from_slice(&single_pool_witness.to_bytes()); +// buf[797..1490].copy_from_slice(&single_liquidity_witness.to_bytes()); +// buf[1490..2964].copy_from_slice(&double_balance_witness.to_bytes()); +// buf[2964..2996].copy_from_slice(&base_token_id.to_bytes()); +// buf[2996..3028].copy_from_slice("e_token_id.to_bytes()); +// buf[3028..3083].copy_from_slice(&user_address.to_bytes()); +// buf[3083..3115].copy_from_slice(&user_liquidity_points.to_bytes()); +// buf[3115..3123].copy_from_slice(&user_balance_base_token_amount.to_bytes()); +// buf[3123..3131].copy_from_slice(&user_balance_quote_token_amount.to_bytes()); +// buf[3131..3139].copy_from_slice(&pool_base_token_amount.to_bytes()); +// buf[3139..3147].copy_from_slice(&pool_quote_token_amount.to_bytes()); +// buf[3147..3179].copy_from_slice(&pool_total_liquidity_points.to_bytes()); +// buf[3179..3187].copy_from_slice(&user_base_token_amount_to_provide.to_bytes()); +// buf[3187..3195] +// .copy_from_slice(&user_quote_token_amount_limit_to_provide.to_bytes()); +// buf[3195] = *is_first_providing as u8; +// buf[3196..3292].copy_from_slice(&user_signature.to_bytes()); +// } +// Method::RemoveLiquidity { +// state_roots, +// earlier_proof_index, +// single_pool_witness, +// single_liquidity_witness, +// double_balance_witness, +// base_token_id, +// quote_token_id, +// user_address, +// user_liquidity_points, +// user_balance_base_token_amount, +// user_balance_quote_token_amount, +// pool_base_token_amount, +// pool_quote_token_amount, +// pool_total_liquidity_points, +// user_liquidity_points_to_remove, +// user_base_token_amount_limit_to_remove, +// user_quote_token_amount_limit_to_remove, +// user_signature, +// } => { +// buf[0] = 5; +// buf[1..129].copy_from_slice(&state_roots.to_bytes()); +// buf[129..137].copy_from_slice(&earlier_proof_index.to_bytes()); +// buf[137..797].copy_from_slice(&single_pool_witness.to_bytes()); +// buf[797..1490].copy_from_slice(&single_liquidity_witness.to_bytes()); +// buf[1490..2964].copy_from_slice(&double_balance_witness.to_bytes()); +// buf[2964..2996].copy_from_slice(&base_token_id.to_bytes()); +// buf[2996..3028].copy_from_slice("e_token_id.to_bytes()); +// buf[3028..3083].copy_from_slice(&user_address.to_bytes()); +// buf[3083..3115].copy_from_slice(&user_liquidity_points.to_bytes()); +// buf[3115..3123].copy_from_slice(&user_balance_base_token_amount.to_bytes()); +// buf[3123..3131].copy_from_slice(&user_balance_quote_token_amount.to_bytes()); +// buf[3131..3139].copy_from_slice(&pool_base_token_amount.to_bytes()); +// buf[3139..3147].copy_from_slice(&pool_quote_token_amount.to_bytes()); +// buf[3147..3179].copy_from_slice(&pool_total_liquidity_points.to_bytes()); +// buf[3179..3211].copy_from_slice(&user_liquidity_points_to_remove.to_bytes()); +// buf[3211..3219].copy_from_slice(&user_base_token_amount_limit_to_remove.to_bytes()); +// buf[3219..3227] +// .copy_from_slice(&user_quote_token_amount_limit_to_remove.to_bytes()); +// buf[3227..3323].copy_from_slice(&user_signature.to_bytes()); +// } +// Method::BuyTokens { +// state_roots, +// earlier_proof_index, +// single_pool_witness, +// double_balance_witness, +// user_address, +// base_token_id, +// quote_token_id, +// user_balance_base_token_amount, +// user_balance_quote_token_amount, +// pool_base_token_amount, +// pool_quote_token_amount, +// pool_total_liquidity_points, +// user_base_token_amount_to_swap, +// user_quote_token_amount_limit_to_swap, +// user_signature, +// } => { +// buf[0] = 6; +// buf[888..129].copy_from_slice(&state_roots.to_bytes()); +// buf[129..137].copy_from_slice(&earlier_proof_index.to_bytes()); +// buf[137..797].copy_from_slice(&single_pool_witness.to_bytes()); +// buf[797..2271].copy_from_slice(&double_balance_witness.to_bytes()); +// buf[2271..2326].copy_from_slice(&user_address.to_bytes()); +// buf[2326..2358].copy_from_slice(&base_token_id.to_bytes()); +// buf[2358..2390].copy_from_slice("e_token_id.to_bytes()); +// buf[2390..2398].copy_from_slice(&user_balance_base_token_amount.to_bytes()); +// buf[2398..2406].copy_from_slice(&user_balance_quote_token_amount.to_bytes()); +// buf[2406..2414].copy_from_slice(&pool_base_token_amount.to_bytes()); +// buf[2414..2422].copy_from_slice(&pool_quote_token_amount.to_bytes()); +// buf[2422..2454].copy_from_slice(&pool_total_liquidity_points.to_bytes()); +// buf[2454..2462].copy_from_slice(&user_base_token_amount_to_swap.to_bytes()); +// buf[2462..2470].copy_from_slice(&user_quote_token_amount_limit_to_swap.to_bytes()); +// buf[2470..2566].copy_from_slice(&user_signature.to_bytes()); +// } +// Method::SellTokens { +// state_roots, +// earlier_proof_index, +// single_pool_witness, +// double_balance_witness, +// user_address, +// base_token_id, +// quote_token_id, +// user_balance_base_token_amount, +// user_balance_quote_token_amount, +// pool_base_token_amount, +// pool_quote_token_amount, +// pool_total_liquidity_points, +// user_base_token_amount_limit_to_swap, +// user_quote_token_amount_to_swap, +// user_signature, +// } => { +// buf[0] = 7; +// buf[888..129].copy_from_slice(&state_roots.to_bytes()); +// buf[129..137].copy_from_slice(&earlier_proof_index.to_bytes()); +// buf[137..797].copy_from_slice(&single_pool_witness.to_bytes()); +// buf[797..2271].copy_from_slice(&double_balance_witness.to_bytes()); +// buf[2271..2326].copy_from_slice(&user_address.to_bytes()); +// buf[2326..2358].copy_from_slice(&base_token_id.to_bytes()); +// buf[2358..2390].copy_from_slice("e_token_id.to_bytes()); +// buf[2390..2398].copy_from_slice(&user_balance_base_token_amount.to_bytes()); +// buf[2398..2406].copy_from_slice(&user_balance_quote_token_amount.to_bytes()); +// buf[2406..2414].copy_from_slice(&pool_base_token_amount.to_bytes()); +// buf[2414..2422].copy_from_slice(&pool_quote_token_amount.to_bytes()); +// buf[2422..2454].copy_from_slice(&pool_total_liquidity_points.to_bytes()); +// buf[2454..2462].copy_from_slice(&user_base_token_amount_limit_to_swap.to_bytes()); +// buf[2462..2470].copy_from_slice(&user_quote_token_amount_to_swap.to_bytes()); +// buf[2470..2566].copy_from_slice(&user_signature.to_bytes()); +// } +// } + +// buf +// } +// } diff --git a/liquidities-db/src/liqudities_db.rs b/liquidities-db/src/liqudities_db.rs index cfa378e..8af1865 100644 --- a/liquidities-db/src/liqudities_db.rs +++ b/liquidities-db/src/liqudities_db.rs @@ -2,7 +2,7 @@ use crate::{ LiquiditiesDbError, SingleLiquidityWitness, LIQUIDITIES_TREE_HEIGHT, LIQUIDITIES_TREE_SIBLING_COUNT, LIQUIDITY_SIZE_IN_BYTES, }; -use nacho_data_structures::{Address, FromBytes, Liquidity, ToBytes, ToFields, U256}; +use nacho_data_structures::{Address, ByteConversion, FieldConversion, Liquidity, U256}; use nacho_dynamic_list::DynamicList; use nacho_merkle_tree::MerkleTree; use nacho_poseidon_hash::{create_poseidon_hasher, poseidon_hash, PoseidonHasher}; @@ -27,7 +27,7 @@ impl LiquiditiesDb { let hasher = create_poseidon_hasher(); list.for_each(&mut indexes, |buf, index, indexes| { - let liquidity = Liquidity::from_bytes(buf); + let liquidity = Liquidity::from_bytes(&buf); match indexes.get_mut(&liquidity.provider) { Some(indexes) => { @@ -132,7 +132,7 @@ impl LiquiditiesDb { let buf = self.list.get(index).await?; - let liquidity = Liquidity::from_bytes(buf); + let liquidity = Liquidity::from_bytes(&buf); Ok(liquidity) } @@ -148,7 +148,7 @@ impl LiquiditiesDb { for &(index, _, _) in indexes { let buf = self.list.get(index).await?; - let liquidity = Liquidity::from_bytes(buf); + let liquidity = Liquidity::from_bytes(&buf); liquidities.push(liquidity) } diff --git a/mempool/src/mempool.rs b/mempool/src/mempool.rs index cb3d75a..c1d4e12 100644 --- a/mempool/src/mempool.rs +++ b/mempool/src/mempool.rs @@ -6,7 +6,7 @@ use nacho_dynamic_queue::DynamicQueue; use crate::MempoolError; pub struct Mempool { - queue: DynamicQueue<264, Transaction>, + queue: DynamicQueue<232, Transaction>, } type Result = std::result::Result; diff --git a/merkle-tree/src/double_witness.rs b/merkle-tree/src/double_witness.rs index 414ee04..d6b6d3d 100644 --- a/merkle-tree/src/double_witness.rs +++ b/merkle-tree/src/double_witness.rs @@ -1,8 +1,8 @@ use crate::{choose, put_in_order, Sibling}; -use nacho_data_structures::{Field, ToBytes}; +use nacho_data_structures::{ByteConversion, Field, FieldConversion}; use nacho_poseidon_hash::{poseidon_hash, PoseidonHasher}; -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct DoubleWitness { pub siblings_x1: [Sibling; L], pub siblings_x2: [Sibling; L], @@ -23,7 +23,7 @@ impl DoubleWitness { let sibling_x1 = choose!( self.siblings_at[i], root_x2, - Field::from(&self.siblings_x1[i].value) + self.siblings_x1[i].value.to_fields()[0] ); root_x1 = poseidon_hash( @@ -35,7 +35,7 @@ impl DoubleWitness { hasher, put_in_order!( self.siblings_x2[i].is_left, - &[root_x2, Field::from(&self.siblings_x2[i].value)] + &[root_x2, self.siblings_x2[i].value.to_fields()[0]] ), ); } @@ -44,10 +44,8 @@ impl DoubleWitness { } } -impl ToBytes for DoubleWitness<22> { - type Bytes = [u8; 1474]; - - fn to_bytes(&self) -> Self::Bytes { +impl ByteConversion<1474> for DoubleWitness<22> { + fn to_bytes(&self) -> [u8; 1474] { let mut buf = [0u8; 1474]; for (i, sibling) in self.siblings_x1.iter().enumerate() { @@ -70,6 +68,10 @@ impl ToBytes for DoubleWitness<22> { buf } + + fn from_bytes(_: &[u8; 1474]) -> Self { + panic!("this function is not intended for use") + } } #[cfg(test)] diff --git a/merkle-tree/src/merkle_tree.rs b/merkle-tree/src/merkle_tree.rs index 956f7a1..c773535 100644 --- a/merkle-tree/src/merkle_tree.rs +++ b/merkle-tree/src/merkle_tree.rs @@ -2,9 +2,9 @@ use crate::{ calculate_sibling_index, double_witness::DoubleWitness, single_witness::SingleWitness, MerkleTreeError, Sibling, }; -use nacho_data_structures::{Field, U256}; +use nacho_data_structures::{Field, FieldConversion, U256}; use nacho_poseidon_hash::{create_poseidon_hasher, poseidon_hash, PoseidonHasher}; -use std::{array, borrow::Borrow, io::SeekFrom, path::Path}; +use std::{array, io::SeekFrom, path::Path}; use tokio::{ fs::{create_dir_all, File, OpenOptions}, io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt}, @@ -184,7 +184,7 @@ impl MerkleTree { let u256 = U256(buf); - Ok(u256.borrow().into()) + Ok(u256.to_fields()[0]) } /// Returns the value of the leaf at the given index of the Merkle tree. @@ -212,7 +212,7 @@ impl MerkleTree { if leaves_file_len <= padding { let u256 = U256(buf); - return Ok(u256.borrow().into()); + return Ok(u256.to_fields()[0]); } leaves_file.seek(SeekFrom::Start(padding)).await?; @@ -220,7 +220,7 @@ impl MerkleTree { let u256 = U256(buf); - Ok(u256.borrow().into()) + Ok(u256.to_fields()[0]) } /// Assigns the given value to the leaf at the given index of the Merkle tree. @@ -276,7 +276,7 @@ impl MerkleTree { let mut buf = [0_u8; 32]; current_file.seek(SeekFrom::Start(sibling_padding)).await?; current_file.read_exact(&mut buf).await?; - U256(buf).borrow().into() + U256(buf).to_fields()[0] }; let (left, right) = if sibling_is_left { @@ -622,7 +622,7 @@ mod tests { assert_eq!( single_witness .siblings - .map(|sibling| Field::from(&sibling.value)), + .map(|sibling| sibling.value.to_fields()[0]), [ "0".parse().unwrap(), "21565680844461314807147611702860246336805372493508489110556896454939225549736" @@ -642,7 +642,7 @@ mod tests { let witness = tree.get_single_witness(1).await?; assert_eq!( - witness.siblings.map(|sibling| Field::from(&sibling.value)), + witness.siblings.map(|sibling| sibling.value.to_fields()[0]), [ "42".parse().unwrap(), "21565680844461314807147611702860246336805372493508489110556896454939225549736" @@ -671,7 +671,7 @@ mod tests { assert_eq!( double_witness .siblings_x1 - .map(|sibling| Field::from(&sibling.value)), + .map(|sibling| sibling.value.to_fields()[0]), [ "0".parse().unwrap(), "21565680844461314807147611702860246336805372493508489110556896454939225549736" @@ -689,7 +689,7 @@ mod tests { assert_eq!( double_witness .siblings_x2 - .map(|sibling| Field::from(&sibling.value)), + .map(|sibling| sibling.value.to_fields()[0]), [ "0".parse().unwrap(), "21565680844461314807147611702860246336805372493508489110556896454939225549736" @@ -713,7 +713,7 @@ mod tests { assert_eq!( double_witness .siblings_x1 - .map(|sibling| Field::from(&sibling.value)), + .map(|sibling| sibling.value.to_fields()[0]), [ "0".parse().unwrap(), "21565680844461314807147611702860246336805372493508489110556896454939225549736" @@ -731,7 +731,7 @@ mod tests { assert_eq!( double_witness .siblings_x2 - .map(|sibling| Field::from(&sibling.value)), + .map(|sibling| sibling.value.to_fields()[0]), [ "42".parse().unwrap(), "21565680844461314807147611702860246336805372493508489110556896454939225549736" diff --git a/merkle-tree/src/sibling.rs b/merkle-tree/src/sibling.rs index b0a05c9..6d1ec21 100644 --- a/merkle-tree/src/sibling.rs +++ b/merkle-tree/src/sibling.rs @@ -1,4 +1,4 @@ -use nacho_data_structures::{ToBytes, U256}; +use nacho_data_structures::{ByteConversion, U256}; /// The element that represents a sibling of a leaf or one that leaf's hashes. #[derive(Clone, Debug)] @@ -16,10 +16,8 @@ impl Default for Sibling { } } -impl ToBytes for Sibling { - type Bytes = [u8; 33]; - - fn to_bytes(&self) -> Self::Bytes { +impl ByteConversion<33> for Sibling { + fn to_bytes(&self) -> [u8; 33] { let mut buf = [0u8; 33]; buf[0..32].copy_from_slice(&self.value.to_bytes()); @@ -27,4 +25,8 @@ impl ToBytes for Sibling { buf } + + fn from_bytes(_: &[u8; 33]) -> Self { + panic!("this function is not intended for use") + } } diff --git a/merkle-tree/src/single_witness.rs b/merkle-tree/src/single_witness.rs index 0bc48d6..ac3c35a 100644 --- a/merkle-tree/src/single_witness.rs +++ b/merkle-tree/src/single_witness.rs @@ -1,8 +1,8 @@ use crate::{put_in_order, Sibling}; -use nacho_data_structures::{Field, ToBytes}; +use nacho_data_structures::{ByteConversion, Field, FieldConversion}; use nacho_poseidon_hash::{poseidon_hash, PoseidonHasher}; -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct SingleWitness { pub siblings: [Sibling; L], } @@ -16,7 +16,7 @@ impl SingleWitness { hasher, put_in_order!( self.siblings[i].is_left, - &[root, Field::from(&self.siblings[i].value)] + &[root, self.siblings[i].value.to_fields()[0]] ), ); } @@ -25,10 +25,8 @@ impl SingleWitness { } } -impl ToBytes for SingleWitness<22> { - type Bytes = [u8; 726]; - - fn to_bytes(&self) -> Self::Bytes { +impl ByteConversion<726> for SingleWitness<22> { + fn to_bytes(&self) -> [u8; 726] { let mut buf = [0u8; 726]; for (i, sibling) in self.siblings.iter().enumerate() { @@ -39,12 +37,14 @@ impl ToBytes for SingleWitness<22> { buf } -} -impl ToBytes for SingleWitness<21> { - type Bytes = [u8; 693]; + fn from_bytes(_: &[u8; 726]) -> Self { + panic!("this function is not intended for use") + } +} - fn to_bytes(&self) -> Self::Bytes { +impl ByteConversion<693> for SingleWitness<21> { + fn to_bytes(&self) -> [u8; 693] { let mut buf = [0u8; 693]; for (i, sibling) in self.siblings.iter().enumerate() { @@ -55,12 +55,14 @@ impl ToBytes for SingleWitness<21> { buf } -} -impl ToBytes for SingleWitness<20> { - type Bytes = [u8; 660]; + fn from_bytes(_: &[u8; 693]) -> Self { + panic!("this function is not intended for use") + } +} - fn to_bytes(&self) -> Self::Bytes { +impl ByteConversion<660> for SingleWitness<20> { + fn to_bytes(&self) -> [u8; 660] { let mut buf = [0u8; 660]; for (i, sibling) in self.siblings.iter().enumerate() { @@ -71,12 +73,14 @@ impl ToBytes for SingleWitness<20> { buf } -} -impl ToBytes for SingleWitness<19> { - type Bytes = [u8; 627]; + fn from_bytes(_: &[u8; 660]) -> Self { + panic!("this function is not intended for use") + } +} - fn to_bytes(&self) -> Self::Bytes { +impl ByteConversion<627> for SingleWitness<19> { + fn to_bytes(&self) -> [u8; 627] { let mut buf = [0u8; 627]; for (i, sibling) in self.siblings.iter().enumerate() { @@ -87,12 +91,14 @@ impl ToBytes for SingleWitness<19> { buf } -} -impl ToBytes for SingleWitness<18> { - type Bytes = [u8; 594]; + fn from_bytes(_: &[u8; 627]) -> Self { + panic!("this function is not intended for use") + } +} - fn to_bytes(&self) -> Self::Bytes { +impl ByteConversion<594> for SingleWitness<18> { + fn to_bytes(&self) -> [u8; 594] { let mut buf = [0u8; 594]; for (i, sibling) in self.siblings.iter().enumerate() { @@ -103,6 +109,10 @@ impl ToBytes for SingleWitness<18> { buf } + + fn from_bytes(_: &[u8; 594]) -> Self { + panic!("this function is not intended for use") + } } #[cfg(test)] diff --git a/pools-db/src/pools_db.rs b/pools-db/src/pools_db.rs index 85a0507..bcb3132 100644 --- a/pools-db/src/pools_db.rs +++ b/pools-db/src/pools_db.rs @@ -2,7 +2,7 @@ use crate::{ PoolsDbError, SinglePoolWitness, POOLS_TREE_HEIGHT, POOLS_TREE_SIBLING_COUNT, POOL_SIZE_IN_BYTES, }; -use nacho_data_structures::{FromBytes, Pool, ToBytes, ToFields, U256}; +use nacho_data_structures::{ByteConversion, FieldConversion, Pool, U256}; use nacho_dynamic_list::DynamicList; use nacho_merkle_tree::MerkleTree; use nacho_poseidon_hash::{create_poseidon_hasher, poseidon_hash, PoseidonHasher}; @@ -27,7 +27,7 @@ impl PoolsDb { let hasher = create_poseidon_hasher(); list.for_each(&mut indexes, |buf, index, indexes| { - let pool = Pool::from_bytes(buf); + let pool = Pool::from_bytes(&buf); if indexes.contains_key(&(pool.base_token_id.clone(), pool.quote_token_id.clone())) { return Err(PoolsDbError::PoolAlreadyExists); @@ -85,7 +85,7 @@ impl PoolsDb { let buf = self.list.get(index).await?; - let pool = Pool::from_bytes(buf); + let pool = Pool::from_bytes(&buf); Ok(pool) } @@ -99,7 +99,7 @@ impl PoolsDb { for &index in indexes { let buf = self.list.get(index).await?; - let pool = Pool::from_bytes(buf); + let pool = Pool::from_bytes(&buf); pools.push(pool) } diff --git a/poseidon-hash/Cargo.toml b/poseidon-hash/Cargo.toml index 5f655d4..6e3a1a6 100644 --- a/poseidon-hash/Cargo.toml +++ b/poseidon-hash/Cargo.toml @@ -11,3 +11,6 @@ nacho-data-structures.workspace = true # GitHub dependencies. mina-poseidon.workspace = true +mina-signer.workspace = true +mina-hasher.workspace = true +o1-utils.workspace = true diff --git a/poseidon-hash/src/lib.rs b/poseidon-hash/src/lib.rs index 94b4a87..0750abb 100644 --- a/poseidon-hash/src/lib.rs +++ b/poseidon-hash/src/lib.rs @@ -1,3 +1,67 @@ mod poseidon_hash; pub use poseidon_hash::{create_poseidon_hasher, poseidon_hash, PoseidonHasher}; + +#[cfg(test)] +mod tests { + + use mina_hasher::{Hashable, ROInput}; + use mina_signer::{BaseField, PubKey, Signature, Signer}; + use nacho_data_structures::Field; + + #[derive(Clone)] + pub struct Message { + pub fields: Vec, + } + + impl Hashable for Message { + type D = (); + + fn to_roinput(&self) -> ROInput { + let mut ro = ROInput::new(); + + for field in &self.fields { + ro = ro.append_field(field.clone()) + } + + ro + } + + fn domain_string(_: ()) -> Option { + Some("CodaSignature*******".to_string()) + } + } + + pub fn verify(signature: &Signature, pubkey: &PubKey, msg: &Message) -> bool { + let mut signer = mina_signer::create_kimchi::(()); + + let is_verified = signer.verify(signature, pubkey, msg); + + is_verified + } + + #[test] + fn test() { + let signature = Signature::new( + "12626512238778647911464193864684212148694812649518775397660142722643855540120" + .parse() + .unwrap(), + "6857963855629205000115548765552901267271269444339596195027304307126718438170" + .parse() + .unwrap(), + ); + + let pubkey = + PubKey::from_address("B62qoTFrus93Ryi1VzbFakzErBBmcikHEq27vhMkU4FfjGfCovv41fb") + .unwrap(); + + let is_valid = verify( + &signature, + &pubkey, + &Message { + fields: vec![Field::from(42)], + }, + ); + assert_eq!(is_valid, true); + } +} diff --git a/processes/src/authenticator/process.rs b/processes/src/authenticator/process.rs index 9534127..71f0352 100644 --- a/processes/src/authenticator/process.rs +++ b/processes/src/authenticator/process.rs @@ -1,7 +1,7 @@ use std::process::Stdio; use super::{Processor, Request}; -use nacho_data_structures::Transaction; +use nacho_data_structures::{ByteConversion, Transaction}; use tokio::io::{AsyncReadExt, AsyncWriteExt, BufReader}; use tokio::process::{ChildStdin, ChildStdout, Command}; use tokio::sync::mpsc; @@ -53,7 +53,7 @@ pub async fn check_signature( stdout: &mut BufReader<&mut ChildStdout>, tx: Transaction, ) -> Option { - let tx_buf: [u8; 264] = (&tx).into(); + let tx_buf = tx.to_bytes(); stdin.write_all(&tx_buf).await.ok()?; diff --git a/processes/src/lib.rs b/processes/src/lib.rs index eb3e4ff..9657d71 100644 --- a/processes/src/lib.rs +++ b/processes/src/lib.rs @@ -2,9 +2,11 @@ pub mod authenticator; pub mod balances; pub mod burns; pub mod executor; +pub mod generator; pub mod liquidities; pub mod mempool; pub mod pools; pub mod proofpool; +pub mod prover; pub mod transactions; pub mod withdrawals; diff --git a/processes/src/withdrawals/process.rs b/processes/src/withdrawals/process.rs index e8fb1c6..3c7fc4e 100644 --- a/processes/src/withdrawals/process.rs +++ b/processes/src/withdrawals/process.rs @@ -1,3 +1,4 @@ +use nacho_data_structures::FieldConversion; use nacho_withdrawals_db::WithdrawalsDb; use tokio::sync::mpsc; @@ -23,7 +24,7 @@ pub fn process(path: &str) -> Processor { burn_id, value, } => { - let result = withdrawals_db.set(burn_id, (&value).into()).await; + let result = withdrawals_db.set(burn_id, value.to_fields()[0]).await; sender.send(result.ok()).unwrap(); } diff --git a/proof-generator/tests/proof-generator.test.ts b/proof-generator/tests/proof-generator.test.ts index 9f5a658..a30eb97 100644 --- a/proof-generator/tests/proof-generator.test.ts +++ b/proof-generator/tests/proof-generator.test.ts @@ -19,6 +19,8 @@ describe("proof generator", async () => { assert.deepEqual(proof.publicInput, stateUtil.stateRoots) assert.deepEqual(proof.publicOutput, stateUtil.stateRoots) stateUtil.pushProof(proof) + + console.log(JSON.stringify(proof.toJSON()).length) }) it("generates deposit tokens proof", async () => { @@ -46,6 +48,7 @@ describe("proof generator", async () => { proof.publicOutput.assertEquals(stateUtil.stateRoots) stateUtil.pushProof(proof) + console.log(JSON.stringify(proof.toJSON()).length) }) it("generates make burn tokens proof", async () => { @@ -74,6 +77,7 @@ describe("proof generator", async () => { proof.publicOutput.assertEquals(stateUtil.stateRoots) stateUtil.pushProof(proof) + console.log(JSON.stringify(proof.toJSON()).length) }) it("generates deposit tokens proof one more time", async () => { @@ -101,6 +105,7 @@ describe("proof generator", async () => { proof.publicOutput.assertEquals(stateUtil.stateRoots) stateUtil.pushProof(proof) + console.log(JSON.stringify(proof.toJSON()).length) }) it("generates make create pool proof", async () => { diff --git a/proofpool/src/proofpool.rs b/proofpool/src/proofpool.rs index a6074de..31b589b 100644 --- a/proofpool/src/proofpool.rs +++ b/proofpool/src/proofpool.rs @@ -6,7 +6,7 @@ use nacho_dynamic_queue::DynamicQueue; use crate::ProofpoolError; pub struct Proofpool { - queue: DynamicQueue<264, Transaction>, + queue: DynamicQueue<232, Transaction>, } type Result = std::result::Result; diff --git a/rpc-server/src/rpc_method.rs b/rpc-server/src/rpc_method.rs index 41454d0..6e5fb22 100644 --- a/rpc-server/src/rpc_method.rs +++ b/rpc-server/src/rpc_method.rs @@ -1,4 +1,4 @@ -use nacho_data_structures::{Address, FromBytes, Signature, U256}; +use nacho_data_structures::{Address, ByteConversion, Signature, U256}; /// The enum that represents RPC methods. /// @@ -94,11 +94,15 @@ pub enum RpcMethod { impl RpcMethod { /// The size of an RPC method over the network. - pub const SIZE_IN_BYTES: usize = 264; + pub const SIZE_IN_BYTES: usize = 232; } -impl From<[u8; RpcMethod::SIZE_IN_BYTES]> for RpcMethod { - fn from(bytes: [u8; RpcMethod::SIZE_IN_BYTES]) -> Self { +impl ByteConversion<{ RpcMethod::SIZE_IN_BYTES }> for RpcMethod { + fn to_bytes(&self) -> [u8; RpcMethod::SIZE_IN_BYTES] { + panic!("this function is not intended for use") + } + + fn from_bytes(bytes: &[u8; RpcMethod::SIZE_IN_BYTES]) -> Self { match bytes[0] { 1 => RpcMethod::GetTotalTxCount, @@ -126,55 +130,55 @@ impl From<[u8; RpcMethod::SIZE_IN_BYTES]> for RpcMethod { 8 => RpcMethod::BurnTokens { address: Address::from_bytes(bytes[1..56].try_into().unwrap()), - signature: Signature::from_bytes(bytes[56..152].try_into().unwrap()), - token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), - token_amount: u64::from_bytes(bytes[184..192].try_into().unwrap()), + signature: Signature::from_bytes(bytes[56..120].try_into().unwrap()), + token_id: U256::from_bytes(bytes[120..152].try_into().unwrap()), + token_amount: u64::from_bytes(bytes[152..160].try_into().unwrap()), }, 9 => RpcMethod::CreatePool { address: Address::from_bytes(bytes[1..56].try_into().unwrap()), - signature: Signature::from_bytes(bytes[56..152].try_into().unwrap()), - base_token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), - quote_token_id: U256::from_bytes(bytes[184..216].try_into().unwrap()), - base_token_amount: u64::from_bytes(bytes[216..224].try_into().unwrap()), - quote_token_amount: u64::from_bytes(bytes[224..232].try_into().unwrap()), + signature: Signature::from_bytes(bytes[56..120].try_into().unwrap()), + base_token_id: U256::from_bytes(bytes[120..152].try_into().unwrap()), + quote_token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), + base_token_amount: u64::from_bytes(bytes[184..192].try_into().unwrap()), + quote_token_amount: u64::from_bytes(bytes[192..200].try_into().unwrap()), }, 10 => RpcMethod::ProvideLiquidity { address: Address::from_bytes(bytes[1..56].try_into().unwrap()), - signature: Signature::from_bytes(bytes[56..152].try_into().unwrap()), - base_token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), - quote_token_id: U256::from_bytes(bytes[184..216].try_into().unwrap()), - base_token_amount: u64::from_bytes(bytes[216..224].try_into().unwrap()), - quote_token_amount_limit: u64::from_bytes(bytes[224..232].try_into().unwrap()), + signature: Signature::from_bytes(bytes[56..120].try_into().unwrap()), + base_token_id: U256::from_bytes(bytes[120..152].try_into().unwrap()), + quote_token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), + base_token_amount: u64::from_bytes(bytes[184..192].try_into().unwrap()), + quote_token_amount_limit: u64::from_bytes(bytes[192..200].try_into().unwrap()), }, 11 => RpcMethod::RemoveLiquidity { address: Address::from_bytes(bytes[1..56].try_into().unwrap()), - signature: Signature::from_bytes(bytes[56..152].try_into().unwrap()), - base_token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), - quote_token_id: U256::from_bytes(bytes[184..216].try_into().unwrap()), - base_token_amount_limit: u64::from_bytes(bytes[216..224].try_into().unwrap()), - quote_token_amount_limit: u64::from_bytes(bytes[224..232].try_into().unwrap()), - liquidity_point_amount: U256::from_bytes(bytes[232..264].try_into().unwrap()), + signature: Signature::from_bytes(bytes[56..120].try_into().unwrap()), + base_token_id: U256::from_bytes(bytes[120..152].try_into().unwrap()), + quote_token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), + base_token_amount_limit: u64::from_bytes(bytes[184..192].try_into().unwrap()), + quote_token_amount_limit: u64::from_bytes(bytes[192..200].try_into().unwrap()), + liquidity_point_amount: U256::from_bytes(bytes[200..232].try_into().unwrap()), }, 12 => RpcMethod::BuyTokens { address: Address::from_bytes(bytes[1..56].try_into().unwrap()), - signature: Signature::from_bytes(bytes[56..152].try_into().unwrap()), - base_token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), - quote_token_id: U256::from_bytes(bytes[184..216].try_into().unwrap()), - base_token_amount: u64::from_bytes(bytes[216..224].try_into().unwrap()), - quote_token_amount_limit: u64::from_bytes(bytes[224..232].try_into().unwrap()), + signature: Signature::from_bytes(bytes[56..120].try_into().unwrap()), + base_token_id: U256::from_bytes(bytes[120..152].try_into().unwrap()), + quote_token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), + base_token_amount: u64::from_bytes(bytes[184..192].try_into().unwrap()), + quote_token_amount_limit: u64::from_bytes(bytes[192..200].try_into().unwrap()), }, 13 => RpcMethod::SellTokens { address: Address::from_bytes(bytes[1..56].try_into().unwrap()), - signature: Signature::from_bytes(bytes[56..152].try_into().unwrap()), - base_token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), - quote_token_id: U256::from_bytes(bytes[184..216].try_into().unwrap()), - base_token_amount_limit: u64::from_bytes(bytes[216..224].try_into().unwrap()), - quote_token_amount: u64::from_bytes(bytes[224..232].try_into().unwrap()), + signature: Signature::from_bytes(bytes[56..120].try_into().unwrap()), + base_token_id: U256::from_bytes(bytes[120..152].try_into().unwrap()), + quote_token_id: U256::from_bytes(bytes[152..184].try_into().unwrap()), + base_token_amount_limit: u64::from_bytes(bytes[184..192].try_into().unwrap()), + quote_token_amount: u64::from_bytes(bytes[192..200].try_into().unwrap()), }, _ => RpcMethod::Unknown, diff --git a/rpc-server/src/rpc_response.rs b/rpc-server/src/rpc_response.rs index 65d4633..d03d6a4 100644 --- a/rpc-server/src/rpc_response.rs +++ b/rpc-server/src/rpc_response.rs @@ -1,7 +1,7 @@ use http_body_util::Full; use hyper::{body::Bytes, Response}; use nacho_burns_db::SingleBurnWitness; -use nacho_data_structures::{ToBytes, TxStatus, U256}; +use nacho_data_structures::{ByteConversion, TxStatus, U256}; use nacho_withdrawals_db::SingleWithdrawalWitness; /// The alias that represents the type of token IDs. diff --git a/rpc-server/src/start_rpc_server.rs b/rpc-server/src/start_rpc_server.rs index 15600a6..f4b34e8 100644 --- a/rpc-server/src/start_rpc_server.rs +++ b/rpc-server/src/start_rpc_server.rs @@ -2,6 +2,7 @@ use crate::{RpcMethod, RpcResponse}; use http_body_util::BodyExt; use hyper::{body::Buf, server::conn::http1, service::service_fn}; use hyper_util::rt::TokioIo; +use nacho_data_structures::ByteConversion; use std::future::Future; use tokio::net::{TcpListener, ToSocketAddrs}; @@ -83,7 +84,7 @@ fn parse_body( let mut body_bytes = [0_u8; RpcMethod::SIZE_IN_BYTES]; buf.copy_to_slice(body_bytes.as_mut_slice()); - let rpc_method = body_bytes.into(); + let rpc_method = RpcMethod::from_bytes(&body_bytes); rpc_method } diff --git a/withdrawals-db/src/withdrawals_db.rs b/withdrawals-db/src/withdrawals_db.rs index 184f266..8fbbc0d 100644 --- a/withdrawals-db/src/withdrawals_db.rs +++ b/withdrawals-db/src/withdrawals_db.rs @@ -1,6 +1,6 @@ use std::{array, io::SeekFrom, path::Path}; -use nacho_data_structures::{Field, FromBytes, ToBytes, U256}; +use nacho_data_structures::{ByteConversion, Field, FieldConversion, U256}; use nacho_merkle_tree::Sibling; use nacho_poseidon_hash::{create_poseidon_hasher, poseidon_hash, PoseidonHasher}; use tokio::{ @@ -117,7 +117,7 @@ impl WithdrawalsDb { .await?; self.file.read_exact(&mut sibling_buf).await?; - let sibling_value: Field = (&U256::from_bytes(sibling_buf)).into(); + let sibling_value: Field = U256::from_bytes(&sibling_buf).to_fields()[0]; let (left_value, right_value) = if sibling_is_left { (sibling_value, current_value) @@ -145,7 +145,7 @@ impl WithdrawalsDb { self.file.seek(SeekFrom::Start(padding)).await?; self.file.read_exact(&mut buf).await?; - let value = (&U256(buf)).into(); + let value = U256(buf).to_fields()[0]; Ok(value) } @@ -158,7 +158,7 @@ impl WithdrawalsDb { self.file.seek(SeekFrom::Start(padding)).await?; self.file.read_exact(&mut buf).await?; - let value = (&U256(buf)).into(); + let value = U256(buf).to_fields()[0]; Ok(value) } @@ -193,7 +193,7 @@ impl WithdrawalsDb { .await?; self.file.read_exact(&mut sibling_buf).await?; - let sibling_value = U256::from_bytes(sibling_buf); + let sibling_value = U256::from_bytes(&sibling_buf); siblings[i] = Sibling { value: sibling_value, @@ -295,7 +295,7 @@ mod tests { witness .siblings .clone() - .map(|sibling| Field::from(&sibling.value)), + .map(|sibling| sibling.value.to_fields()[0]), [ "0".parse().unwrap(), "21565680844461314807147611702860246336805372493508489110556896454939225549736" @@ -368,7 +368,7 @@ mod tests { witness .siblings .clone() - .map(|sibling| Field::from(&sibling.value)), + .map(|sibling| sibling.value.to_fields()[0]), [ "0".parse().unwrap(), "21565680844461314807147611702860246336805372493508489110556896454939225549736" @@ -441,7 +441,7 @@ mod tests { witness .siblings .clone() - .map(|sibling| Field::from(&sibling.value)), + .map(|sibling| sibling.value.to_fields()[0]), [ "0".parse().unwrap(), "21565680844461314807147611702860246336805372493508489110556896454939225549736"