From 5d5dde33b776390a3f6eb74e9e745b3ae7635fc6 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 26 Jun 2025 07:21:31 +0300 Subject: [PATCH 01/31] fix: utxo nullifier calculation fix and circuits updates --- accounts/src/account_core/mod.rs | 18 ++ common/src/merkle_tree_public/merkle_tree.rs | 1 + sc_core/src/blob_utils.rs | 136 ++++++++ sc_core/src/cryptography.rs | 3 +- sc_core/src/lib.rs | 2 + sc_core/src/proofs_circuits.rs | 308 +++++++++++-------- sc_core/src/public_context.rs | 194 ++++++++++++ storage/src/sc_db_utils.rs | 178 ++++------- 8 files changed, 581 insertions(+), 259 deletions(-) create mode 100644 sc_core/src/blob_utils.rs create mode 100644 sc_core/src/public_context.rs diff --git a/accounts/src/account_core/mod.rs b/accounts/src/account_core/mod.rs index 192c158..079e725 100644 --- a/accounts/src/account_core/mod.rs +++ b/accounts/src/account_core/mod.rs @@ -93,6 +93,24 @@ pub struct AccountPublicMask { pub balance: u64, } +impl AccountPublicMask { + pub fn encrypt_data( + ephemeral_key_holder: &EphemeralKeyHolder, + viewing_public_key_receiver: AffinePoint, + data: &[u8], + ) -> (CipherText, Nonce) { + ephemeral_key_holder.encrypt_data(viewing_public_key_receiver, data) + } + + pub fn make_tag(&self) -> Tag { + self.address[0] + } + + pub fn produce_ephemeral_key_holder(&self) -> EphemeralKeyHolder { + EphemeralKeyHolder::new_os_random() + } +} + impl Account { pub fn new() -> Self { let key_holder = AddressKeyHolder::new_os_random(); diff --git a/common/src/merkle_tree_public/merkle_tree.rs b/common/src/merkle_tree_public/merkle_tree.rs index 3540b06..d8e99ec 100644 --- a/common/src/merkle_tree_public/merkle_tree.rs +++ b/common/src/merkle_tree_public/merkle_tree.rs @@ -11,6 +11,7 @@ use crate::{transaction::Transaction, utxo_commitment::UTXOCommitment}; use super::{hasher::OwnHasher, tree_leav_item::TreeLeavItem, TreeHashType}; +#[derive(Clone)] pub struct HashStorageMerkleTree { leaves: HashMap, hash_to_id_map: HashMap, diff --git a/sc_core/src/blob_utils.rs b/sc_core/src/blob_utils.rs new file mode 100644 index 0000000..d0a3485 --- /dev/null +++ b/sc_core/src/blob_utils.rs @@ -0,0 +1,136 @@ +use serde::Serialize; +use storage::{ + sc_db_utils::{produce_blob_from_fit_vec, DataBlob, DataBlobChangeVariant}, + SC_DATA_BLOB_SIZE, +}; + +///Creates blob list from generic serializable state +/// +///`ToDo`: Find a way to align data in a way, to minimize read and write operations in db +pub fn produce_blob_list_from_sc_public_state( + state: &S, +) -> Result, serde_json::Error> { + let mut blob_list = vec![]; + + let ser_data = serde_json::to_vec(state)?; + + //`ToDo` Replace with `next_chunk` usage, when feature stabilizes in Rust + for i in 0..=(ser_data.len() / SC_DATA_BLOB_SIZE) { + let next_chunk: Vec; + + if (i + 1) * SC_DATA_BLOB_SIZE < ser_data.len() { + next_chunk = ser_data[(i * SC_DATA_BLOB_SIZE)..((i + 1) * SC_DATA_BLOB_SIZE)] + .iter() + .cloned() + .collect(); + } else { + next_chunk = ser_data[(i * SC_DATA_BLOB_SIZE)..(ser_data.len())] + .iter() + .cloned() + .collect(); + } + + blob_list.push(produce_blob_from_fit_vec(next_chunk)); + } + + Ok(blob_list) +} + +///Compare two consecutive in time blob lists to produce list of modified ids +pub fn compare_blob_lists( + blob_list_old: &[DataBlob], + blob_list_new: &[DataBlob], +) -> Vec { + let mut changed_ids = vec![]; + let mut id_end = 0; + + let old_len = blob_list_old.len(); + let new_len = blob_list_new.len(); + + if old_len > new_len { + for id in new_len..old_len { + changed_ids.push(DataBlobChangeVariant::Deleted { id }); + } + } else if new_len > old_len { + for id in old_len..new_len { + changed_ids.push(DataBlobChangeVariant::Created { + id, + blob: blob_list_new[id], + }); + } + } + + loop { + let old_blob = blob_list_old.get(id_end); + let new_blob = blob_list_new.get(id_end); + + match (old_blob, new_blob) { + (Some(old), Some(new)) => { + if old != new { + changed_ids.push(DataBlobChangeVariant::Modified { + id: id_end, + blob_old: *old, + blob_new: *new, + }); + } + } + _ => break, + } + + id_end += 1; + } + + changed_ids +} + +#[cfg(test)] +mod tests { + use super::*; + use serde::Serialize; + + const TEST_BLOB_SIZE: usize = 256; // Define a test blob size for simplicity + static SC_DATA_BLOB_SIZE: usize = TEST_BLOB_SIZE; + + #[derive(Serialize)] + struct TestState { + a: u32, + b: u32, + } + + #[test] + fn test_produce_blob_list_from_sc_public_state() { + let state = TestState { a: 42, b: 99 }; + let result = produce_blob_list_from_sc_public_state(&state).unwrap(); + assert!(!result.is_empty()); + } + + #[test] + fn test_compare_blob_lists_created() { + let old_list: Vec = vec![]; + let new_list: Vec = vec![[1; SC_DATA_BLOB_SIZE].into()]; + + let changes = compare_blob_lists(&old_list, &new_list); + assert_eq!(changes.len(), 1); + assert!(matches!(changes[0], DataBlobChangeVariant::Created { .. })); + } + + #[test] + fn test_compare_blob_lists_deleted() { + let old_list: Vec = vec![[1; SC_DATA_BLOB_SIZE].into()]; + let new_list: Vec = vec![]; + + let changes = compare_blob_lists(&old_list, &new_list); + assert_eq!(changes.len(), 1); + assert!(matches!(changes[0], DataBlobChangeVariant::Deleted { .. })); + } + + #[test] + fn test_compare_blob_lists_modified() { + let old_list: Vec = vec![[1; SC_DATA_BLOB_SIZE].into()]; + let new_list: Vec = vec![[2; SC_DATA_BLOB_SIZE].into()]; + + let changes = compare_blob_lists(&old_list, &new_list); + assert_eq!(changes.len(), 1); + assert!(matches!(changes[0], DataBlobChangeVariant::Modified { .. })); + } +} diff --git a/sc_core/src/cryptography.rs b/sc_core/src/cryptography.rs index 23367c2..d93ce0e 100644 --- a/sc_core/src/cryptography.rs +++ b/sc_core/src/cryptography.rs @@ -1,8 +1,7 @@ use ark_bn254::Fr; use light_poseidon::{Poseidon, PoseidonBytesHasher}; -#[allow(unused)] -fn poseidon_hash(inputs: &[&[u8]]) -> anyhow::Result<[u8; 32]> { +pub fn poseidon_hash(inputs: &[&[u8]]) -> anyhow::Result<[u8; 32]> { let mut poseidon = Poseidon::::new_circom(2).unwrap(); let hash = poseidon.hash_bytes_be(inputs)?; diff --git a/sc_core/src/lib.rs b/sc_core/src/lib.rs index a41ab82..ed70205 100644 --- a/sc_core/src/lib.rs +++ b/sc_core/src/lib.rs @@ -1,3 +1,5 @@ +pub mod blob_utils; pub mod cryptography; pub mod proofs_circuits; +pub mod public_context; pub mod transaction_payloads_tools; diff --git a/sc_core/src/proofs_circuits.rs b/sc_core/src/proofs_circuits.rs index cbebe3e..03eea96 100644 --- a/sc_core/src/proofs_circuits.rs +++ b/sc_core/src/proofs_circuits.rs @@ -1,28 +1,42 @@ use bincode; -use k256::Scalar; +use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree; use rand::{thread_rng, RngCore}; use secp256k1_zkp::{CommitmentSecrets, Generator, PedersenCommitment, Tag, Tweak, SECP256K1}; use sha2::{Digest, Sha256}; +use std::collections::HashSet; use utxo::utxo_core::UTXO; +use crate::{cryptography::poseidon_hash, public_context::PublicSCContext}; + fn hash(input: &[u8]) -> Vec { Sha256::digest(input).to_vec() } -// Generate nullifiers - -// takes the input_utxo and nsk -// returns the nullifiers[i], where the nullifier[i] = hash(in_commitments[i] || nsk) where the hash function -pub fn generate_nullifiers(input_utxo: &UTXO, nsk: &[u8]) -> Vec { - let mut input = bincode::serialize(input_utxo).unwrap().to_vec(); - input.extend_from_slice(nsk); - hash(&input) +/// Generate nullifiers +/// +/// takes the input_utxo and npk +/// +/// returns the nullifiers[i], where the nullifiers[i] = poseidon_hash(in_commitments[i] || npk) +pub fn generate_nullifiers(input_utxo: &UTXO, npk: &[u8]) -> Vec { + let commitment = generate_commitment(input_utxo); + poseidon_hash(&[commitment.as_ref(), npk]).unwrap().to_vec() } -// Generate commitments for output UTXOs +/// Generate commitment for UTXO +/// +/// uses the input_utxo +/// +/// returns commitment here comminment is a hash(bincode(input_utxo)) +pub fn generate_commitment(input_utxo: &UTXO) -> Vec { + let serialized = bincode::serialize(input_utxo).unwrap(); // Serialize UTXO. + hash(&serialized) +} -// uses the list of input_utxos[] -// returns in_commitments[] where each in_commitments[i] = Commitment(in_utxos[i]) where the commitment +/// Generate commitments for UTXO +/// +/// uses the input_utxos +/// +/// returns commitments pub fn generate_commitments(input_utxos: &[UTXO]) -> Vec> { input_utxos .iter() @@ -33,60 +47,122 @@ pub fn generate_commitments(input_utxos: &[UTXO]) -> Vec> { .collect() } -// Validate inclusion proof for in_commitments - -// takes the in_commitments[i] as a leaf, the root hash root_commitment and the path in_commitments_proofs[i][], -// returns True if the in_commitments[i] is in the tree with root hash root_commitment otherwise returns False, as membership proof. +/// Validate inclusion proof for in_commitments +/// +/// ToDo: Solve it in more scalable way pub fn validate_in_commitments_proof( - _in_commitment: &Vec, - _root_commitment: Vec, - _in_commitments_proof: &[Vec], + in_commitment: &Vec, + commitment_tree: &UTXOCommitmentsMerkleTree, ) -> bool { - // ToDo: Implement correct check + let alighned_hash: [u8; 32] = in_commitment.clone().try_into().unwrap(); - todo!() + commitment_tree.get_proof(alighned_hash).is_some() } -// Validate that `nullifier` has not been present in set items before +/// Validate that `nullifier` has not been present in set items before pub fn validate_nullifier_not_present_in_set_items( nullifier: [u8; 32], - nullifiers_items: &[[u8; 32]], + nullifiers_set: &HashSet<[u8; 32]>, ) -> bool { - !nullifiers_items.contains(&nullifier) + !nullifiers_set.contains(&nullifier) } -#[allow(unused)] -fn private_kernel( - root_commitment: &[u8], - root_nullifier: [u8; 32], +/// Check, that input utxos balances is equal to out utxo balances +pub fn check_balances_private(in_utxos: &[UTXO], out_utxos: &[UTXO]) -> bool { + let in_sum = in_utxos.iter().fold(0, |prev, utxo| prev + utxo.amount); + let out_sum = out_utxos.iter().fold(0, |prev, utxo| prev + utxo.amount); + + in_sum == out_sum +} + +pub fn private_circuit( input_utxos: &[UTXO], - in_commitments_proof: &[Vec], - nullifiers_proof: &[[u8; 32]], - nullifier_secret_key: Scalar, -) -> (Vec, Vec>) { - let nullifiers: Vec<_> = input_utxos - .into_iter() - .map(|utxo| generate_nullifiers(&utxo, &nullifier_secret_key.to_bytes())) - .collect(); + output_utxos: &[UTXO], + public_context: &PublicSCContext, +) -> (Vec>, Vec>) { + assert!(check_balances_private(input_utxos, output_utxos)); let in_commitments = generate_commitments(&input_utxos); + let mut in_nullifiers = vec![]; + + for in_utxo in input_utxos { + let nullifier_public_key = public_context + .account_masks + .get(&in_utxo.owner) + .unwrap() + .nullifier_public_key; + + let key_ser = serde_json::to_vec(&nullifier_public_key).unwrap(); + + in_nullifiers.push(generate_nullifiers(in_utxo, &key_ser)); + } + for in_commitment in in_commitments { - validate_in_commitments_proof( + assert!(validate_in_commitments_proof( &in_commitment, - root_commitment.to_vec(), - in_commitments_proof, - ); + &public_context.commitments_tree, + )); } - for nullifier in nullifiers.iter() { - validate_nullifier_not_present_in_set_items( - nullifier[0..32].try_into().unwrap(), - nullifiers_proof, - ); + for nullifier in in_nullifiers.iter() { + assert!(validate_nullifier_not_present_in_set_items( + nullifier.clone().try_into().unwrap(), + &public_context.nullifiers_set, + )); } - (vec![], nullifiers) + (in_nullifiers, generate_commitments(&output_utxos)) +} + +/// Check balances DE +/// +/// takes the input_utxos[] and output_balance, +/// +/// returns the True if the token amount in output_balance matches the sum of all input_utxos[], otherwise return False. +pub fn check_balances_de(input_utxos: &[UTXO], output_balance: u128) -> bool { + let total_input: u128 = input_utxos.iter().map(|utxo| utxo.amount).sum(); + total_input == output_balance +} + +pub fn deshielded_circuit( + input_utxos: &[UTXO], + output_balance: u128, + public_context: &PublicSCContext, +) -> Vec> { + assert!(check_balances_de(input_utxos, output_balance)); + + let in_commitments = generate_commitments(&input_utxos); + + let mut in_nullifiers = vec![]; + + for in_utxo in input_utxos { + let nullifier_public_key = public_context + .account_masks + .get(&in_utxo.owner) + .unwrap() + .nullifier_public_key; + + let key_ser = serde_json::to_vec(&nullifier_public_key).unwrap(); + + in_nullifiers.push(generate_nullifiers(in_utxo, &key_ser)); + } + + for in_commitment in in_commitments { + assert!(validate_in_commitments_proof( + &in_commitment, + &public_context.commitments_tree, + )); + } + + for nullifier in in_nullifiers.iter() { + assert!(validate_nullifier_not_present_in_set_items( + nullifier.clone().try_into().unwrap(), + &public_context.nullifiers_set, + )); + } + + in_nullifiers } #[allow(unused)] @@ -114,16 +190,7 @@ pub fn commit(comm: &CommitmentSecrets, tag: Tag) -> PedersenCommitment { PedersenCommitment::new(SECP256K1, comm.value, comm.value_blinding_factor, generator) } -// Check balances - -// takes the public_info and output_utxos[], -// returns the True if the token amount in public_info matches the sum of all output_utxos[], otherwise return False. -pub fn check_balances(public_info: u128, output_utxos: &[UTXO]) -> bool { - let total_output: u128 = output_utxos.iter().map(|utxo| utxo.amount).sum(); - public_info == total_output -} - -// new_commitment for a Vec of values +/// new_commitment for a Vec of values pub fn pedersen_commitment_vec( public_info_vec: Vec, ) -> (Tweak, [u8; 32], Vec) { @@ -149,10 +216,11 @@ pub fn pedersen_commitment_vec( (generator_blinding_factor, random_val, vec_commitments) } -// Verify Pedersen commitment - -// takes the public_info, secret_r and pedersen_commitment and -// checks that commitment(public_info,secret_r) is equal pedersen_commitment where the commitment is pedersen commitment. +/// Verify Pedersen commitment +/// +/// takes the public_info, secret_r and pedersen_commitment and +/// +/// checks that commitment(public_info,secret_r) is equal pedersen_commitment where the commitment is pedersen commitment. pub fn verify_commitment( public_info: u64, secret_r: &[u8], @@ -170,95 +238,69 @@ pub fn verify_commitment( commitment == *pedersen_commitment } -#[allow(unused)] -fn de_kernel( - root_commitment: &[u8], - root_nullifier: [u8; 32], - public_info: u64, - input_utxos: &[UTXO], - in_commitments_proof: &[Vec], - nullifiers_proof: &[[u8; 32]], - nullifier_secret_key: Scalar, -) -> (Vec, Vec>) { - check_balances(public_info as u128, input_utxos); - - let nullifiers: Vec<_> = input_utxos - .into_iter() - .map(|utxo| generate_nullifiers(&utxo, &nullifier_secret_key.to_bytes())) - .collect(); - - let in_commitments = generate_commitments(&input_utxos); - - for in_commitment in in_commitments { - validate_in_commitments_proof( - &in_commitment, - root_commitment.to_vec(), - in_commitments_proof, - ); - } - - for nullifier in nullifiers.iter() { - validate_nullifier_not_present_in_set_items( - nullifier[0..32].try_into().unwrap(), - nullifiers_proof, - ); - } - - (vec![], nullifiers) -} - -// Validate inclusion proof for in_commitments - -// takes the pedersen_commitment as a leaf, the root hash root_commitment and the path in_commitments_proof[], -// returns True if the pedersen_commitment is in the tree with root hash root_commitment -// otherwise -// returns False, as membership proof. +/// Validate inclusion proof for pedersen_commitment +/// +/// ToDo: Solve it in more scalable way pub fn validate_in_commitments_proof_se( - _pedersen_commitment: &PedersenCommitment, - _root_commitment: Vec, - _in_commitments_proof: &[Vec], + pedersen_commitment: &PedersenCommitment, + commitment_tree: &UTXOCommitmentsMerkleTree, ) -> bool { - // ToDo: Implement correct check + let alighned_hash: [u8; 32] = pedersen_commitment.serialize()[0..32].try_into().unwrap(); - todo!() + commitment_tree.get_proof(alighned_hash).is_some() } -// Generate nullifiers SE +/// Generate nullifier SE +/// +/// takes the pedersen_commitment and npk then +/// returns a nullifier, where the nullifier = poseidon_hash(pedersen_commitment || npk) +pub fn generate_nullifiers_se(pedersen_commitment: &PedersenCommitment, npk: &[u8]) -> Vec { + let commitment_ser = pedersen_commitment.serialize().to_vec(); -// takes the pedersen_commitment and nsk then -// returns a list of nullifiers, where the nullifier = hash(pedersen_commitment || nsk) where the hash function will be determined - -pub fn generate_nullifiers_se(pedersen_commitment: &PedersenCommitment, nsk: &[u8]) -> Vec { - let mut input = pedersen_commitment.serialize().to_vec(); - input.extend_from_slice(nsk); - hash(&input) + poseidon_hash(&[&commitment_ser, npk]).unwrap().to_vec() } -#[allow(unused)] -fn se_kernel( - root_commitment: &[u8], - root_nullifier: [u8; 32], +/// Check balances SE +/// +/// takes the input_balance and output_utxos[], +/// +/// returns the True if the token amount in input_balance matches the sum of all output_utxos[], otherwise return False. +pub fn check_balances_se(input_balance: u128, output_utxos: &[UTXO]) -> bool { + let total_output: u128 = output_utxos.iter().map(|utxo| utxo.amount).sum(); + total_output == input_balance +} + +pub fn shielded_circuit( public_info: u64, + output_utxos: &[UTXO], pedersen_commitment: PedersenCommitment, secret_r: &[u8], - output_utxos: &[UTXO], - in_commitments_proof: &[Vec], - nullifiers_proof: &[[u8; 32]], - nullifier_secret_key: Scalar, -) -> (Vec, Vec>, Vec) { - check_balances(public_info as u128, output_utxos); + public_context: &PublicSCContext, +) -> (Vec>, Vec) { + assert!(check_balances_se(public_info as u128, output_utxos)); let out_commitments = generate_commitments(output_utxos); - let nullifier = generate_nullifiers_se(&pedersen_commitment, &nullifier_secret_key.to_bytes()); + let nullifier_public_key = public_context + .account_masks + .get(&public_context.caller_address) + .unwrap() + .nullifier_public_key; - validate_in_commitments_proof_se( + let key_ser = serde_json::to_vec(&nullifier_public_key).unwrap(); + + let nullifier = generate_nullifiers_se(&pedersen_commitment, &key_ser); + + assert!(validate_in_commitments_proof_se( &pedersen_commitment, - root_commitment.to_vec(), - in_commitments_proof, - ); + &public_context.commitments_tree, + )); - verify_commitment(public_info, secret_r, &pedersen_commitment); + assert!(verify_commitment( + public_info, + secret_r, + &pedersen_commitment + )); - (vec![], out_commitments, nullifier) + (out_commitments, nullifier) } diff --git a/sc_core/src/public_context.rs b/sc_core/src/public_context.rs new file mode 100644 index 0000000..9694fbc --- /dev/null +++ b/sc_core/src/public_context.rs @@ -0,0 +1,194 @@ +use std::collections::{BTreeMap, HashSet}; + +use accounts::account_core::{AccountAddress, AccountPublicMask}; +use common::merkle_tree_public::{merkle_tree::UTXOCommitmentsMerkleTree, TreeHashType}; +use serde::{ser::SerializeStruct, Serialize}; + +pub const PUBLIC_SC_CONTEXT: &str = "PublicSCContext"; +pub const CALLER_ADDRESS: &str = "caller_address"; +pub const CALLER_BALANCE: &str = "caller_balance"; +pub const ACCOUNT_MASKS_KEYS_SORTED: &str = "account_masks_keys_sorted"; +pub const ACCOUNT_MASKS_VALUES_SORTED: &str = "account_masks_values_sorted"; +pub const COMMITMENT_STORE_ROOT: &str = "commitment_store_root"; +pub const PUT_TX_STORE_ROOT: &str = "put_tx_store_root"; +pub const COMMITMENT_TREE: &str = "commitments_tree"; +pub const NULLIFIERS_SET: &str = "nullifiers_set"; + +///Strucutre, representing context, given to a smart contract on a call +pub struct PublicSCContext { + pub caller_address: AccountAddress, + pub caller_balance: u64, + pub account_masks: BTreeMap, + pub comitment_store_root: TreeHashType, + pub pub_tx_store_root: TreeHashType, + pub commitments_tree: UTXOCommitmentsMerkleTree, + pub nullifiers_set: HashSet<[u8; 32]>, +} + +impl Serialize for PublicSCContext { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut account_masks_keys: Vec<[u8; 32]> = self.account_masks.keys().cloned().collect(); + account_masks_keys.sort(); + + let mut account_mask_values: Vec = + self.account_masks.values().cloned().collect(); + account_mask_values.sort_by(|left, right| left.address.cmp(&right.address)); + + let mut s = serializer.serialize_struct(PUBLIC_SC_CONTEXT, 7)?; + + s.serialize_field(CALLER_ADDRESS, &self.caller_address)?; + s.serialize_field(CALLER_BALANCE, &self.caller_balance)?; + s.serialize_field(ACCOUNT_MASKS_KEYS_SORTED, &account_masks_keys)?; + s.serialize_field(ACCOUNT_MASKS_VALUES_SORTED, &account_mask_values)?; + s.serialize_field(COMMITMENT_STORE_ROOT, &self.comitment_store_root)?; + s.serialize_field(PUT_TX_STORE_ROOT, &self.pub_tx_store_root)?; + s.serialize_field(COMMITMENT_TREE, &self.commitments_tree)?; + s.serialize_field(NULLIFIERS_SET, &self.nullifiers_set)?; + + s.end() + } +} + +impl PublicSCContext { + ///Produces `u64` from bytes in a vector + /// + /// Assumes, that vector of le_bytes + pub fn produce_u64_from_fit_vec(data: Vec) -> u64 { + let data_len = data.len(); + + assert!(data_len <= 8); + let mut le_bytes: [u8; 8] = [0; 8]; + + for (idx, item) in data.into_iter().enumerate() { + le_bytes[idx] = item + } + + u64::from_le_bytes(le_bytes) + } + + ///Produces vector of `u64` from context + pub fn produce_u64_list_from_context(&self) -> Result, serde_json::Error> { + let mut u64_list = vec![]; + + let ser_data = serde_json::to_vec(self)?; + + //`ToDo` Replace with `next_chunk` usage, when feature stabilizes in Rust + for i in 0..=(ser_data.len() / 8) { + let next_chunk: Vec; + + if (i + 1) * 8 < ser_data.len() { + next_chunk = ser_data[(i * 8)..((i + 1) * 8)].iter().cloned().collect(); + } else { + next_chunk = ser_data[(i * 8)..(ser_data.len())] + .iter() + .cloned() + .collect(); + } + + u64_list.push(PublicSCContext::produce_u64_from_fit_vec(next_chunk)); + } + + Ok(u64_list) + } +} + +#[cfg(test)] +mod tests { + use accounts::account_core::Account; + use common::utxo_commitment::UTXOCommitment; + + use super::*; + + fn create_test_context() -> PublicSCContext { + let caller_address = [1; 32]; + let comitment_store_root = [3; 32]; + let pub_tx_store_root = [4; 32]; + + let commitments_tree = + UTXOCommitmentsMerkleTree::new(vec![UTXOCommitment { hash: [5; 32] }]); + let mut nullifiers_set = HashSet::new(); + nullifiers_set.insert([6; 32]); + + let mut account_masks = BTreeMap::new(); + + let acc_1 = Account::new(); + let acc_2 = Account::new(); + let acc_3 = Account::new(); + + account_masks.insert(acc_1.address, acc_1.make_account_public_mask()); + account_masks.insert(acc_2.address, acc_2.make_account_public_mask()); + account_masks.insert(acc_3.address, acc_3.make_account_public_mask()); + + PublicSCContext { + caller_address, + caller_balance: 100, + account_masks, + comitment_store_root, + pub_tx_store_root, + commitments_tree, + nullifiers_set, + } + } + + #[test] + fn bin_ser_stability_test() { + let test_context = create_test_context(); + + let serialization_1 = serde_json::to_vec(&test_context).unwrap(); + let serialization_2 = serde_json::to_vec(&test_context).unwrap(); + + assert_eq!(serialization_1, serialization_2); + } + + #[test] + fn correct_u64_production_from_fit_vec() { + let le_vec = vec![1, 1, 1, 1, 2, 1, 1, 1]; + + let num = PublicSCContext::produce_u64_from_fit_vec(le_vec); + + assert_eq!(num, 72340177133043969); + } + + #[test] + fn correct_u64_production_from_small_vec() { + //7 items instead of 8 + let le_vec = vec![1, 1, 1, 1, 2, 1, 1]; + + let num = PublicSCContext::produce_u64_from_fit_vec(le_vec); + + assert_eq!(num, 282583095116033); + } + + #[test] + fn correct_u64_production_from_small_vec_le_bytes() { + //7 items instead of 8 + let le_vec = vec![1, 1, 1, 1, 2, 1, 1]; + let le_vec_res = [1, 1, 1, 1, 2, 1, 1, 0]; + + let num = PublicSCContext::produce_u64_from_fit_vec(le_vec); + + assert_eq!(num.to_le_bytes(), le_vec_res); + } + + #[test] + #[should_panic] + fn correct_u64_production_from_unfit_vec_should_panic() { + //9 items instead of 8 + let le_vec = vec![1, 1, 1, 1, 2, 1, 1, 1, 1]; + + PublicSCContext::produce_u64_from_fit_vec(le_vec); + } + + #[test] + fn consistent_len_of_context_commitments() { + let test_context = create_test_context(); + + let context_num_vec1 = test_context.produce_u64_list_from_context().unwrap(); + let context_num_vec2 = test_context.produce_u64_list_from_context().unwrap(); + + assert_eq!(context_num_vec1.len(), context_num_vec2.len()); + } +} diff --git a/storage/src/sc_db_utils.rs b/storage/src/sc_db_utils.rs index b059de7..3ef12c5 100644 --- a/storage/src/sc_db_utils.rs +++ b/storage/src/sc_db_utils.rs @@ -49,7 +49,7 @@ impl DataBlob { } } -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] pub enum DataBlobChangeVariant { Created { id: usize, @@ -83,93 +83,66 @@ pub fn produce_blob_from_fit_vec(data: Vec) -> DataBlob { blob } -///Creates blob list from generic serializable state -/// -///`ToDo`: Find a way to align data in a way, to minimize read and write operations in db -pub fn produce_blob_list_from_sc_public_state( - state: &S, -) -> Result, serde_json::Error> { - let mut blob_list = vec![]; - - let ser_data = serde_json::to_vec(state)?; - - //`ToDo` Replace with `next_chunk` usage, when feature stabilizes in Rust - for i in 0..=(ser_data.len() / SC_DATA_BLOB_SIZE) { - let next_chunk: Vec; - - if (i + 1) * SC_DATA_BLOB_SIZE < ser_data.len() { - next_chunk = ser_data[(i * SC_DATA_BLOB_SIZE)..((i + 1) * SC_DATA_BLOB_SIZE)] - .iter() - .cloned() - .collect(); - } else { - next_chunk = ser_data[(i * SC_DATA_BLOB_SIZE)..(ser_data.len())] - .iter() - .cloned() - .collect(); - } - - blob_list.push(produce_blob_from_fit_vec(next_chunk)); - } - - Ok(blob_list) -} - -///Compare two consecutive in time blob lists to produce list of modified ids -pub fn compare_blob_lists( - blob_list_old: &[DataBlob], - blob_list_new: &[DataBlob], -) -> Vec { - let mut changed_ids = vec![]; - let mut id_end = 0; - - let old_len = blob_list_old.len(); - let new_len = blob_list_new.len(); - - if old_len > new_len { - for id in new_len..old_len { - changed_ids.push(DataBlobChangeVariant::Deleted { id }); - } - } else if new_len > old_len { - for id in old_len..new_len { - changed_ids.push(DataBlobChangeVariant::Created { - id, - blob: blob_list_new[id], - }); - } - } - - loop { - let old_blob = blob_list_old.get(id_end); - let new_blob = blob_list_new.get(id_end); - - match (old_blob, new_blob) { - (Some(old), Some(new)) => { - if old != new { - changed_ids.push(DataBlobChangeVariant::Modified { - id: id_end, - blob_old: *old, - blob_new: *new, - }); - } - } - _ => break, - } - - id_end += 1; - } - - changed_ids -} - #[cfg(test)] mod tests { use super::*; - use serde::Serialize; + use serde_json; const TEST_BLOB_SIZE: usize = 256; // Define a test blob size for simplicity static SC_DATA_BLOB_SIZE: usize = TEST_BLOB_SIZE; + fn sample_vec() -> Vec { + (0..SC_DATA_BLOB_SIZE) + .collect::>() + .iter() + .map(|&x| x as u8) + .collect() + } + + fn sample_data_blob() -> DataBlob { + let vec: Vec = sample_vec(); + produce_blob_from_fit_vec(vec) + } + + #[test] + fn test_serialize_data_blob() { + let blob = sample_data_blob(); + let json = serde_json::to_string(&blob).unwrap(); + + let expected_json = serde_json::to_string(&sample_vec()).unwrap(); + assert_eq!(json, expected_json); + } + + #[test] + fn test_deserialize_data_blob() { + let data = sample_vec(); + let json = serde_json::to_string(&data).unwrap(); + let deserialized: DataBlob = serde_json::from_str(&json).unwrap(); + assert_eq!(deserialized.to_vec(), data); + } + + #[test] + fn test_serialize_deserialize_data_blob_change_variant() { + let blob1 = sample_data_blob(); + let blob2 = produce_blob_from_fit_vec((50..50 + SC_DATA_BLOB_SIZE as u8).collect()); + + let variants = vec![ + DataBlobChangeVariant::Created { id: 1, blob: blob1 }, + DataBlobChangeVariant::Modified { + id: 2, + blob_old: blob1, + blob_new: blob2, + }, + DataBlobChangeVariant::Deleted { id: 3 }, + ]; + + for variant in variants { + let json = serde_json::to_string(&variant).unwrap(); + let deserialized: DataBlobChangeVariant = serde_json::from_str(&json).unwrap(); + assert_eq!(variant, deserialized); + } + } + #[test] fn test_produce_blob_from_fit_vec() { let data = (0..0 + 255).collect(); @@ -183,47 +156,4 @@ mod tests { let data = vec![0; SC_DATA_BLOB_SIZE + 1]; let _ = produce_blob_from_fit_vec(data); } - - #[derive(Serialize)] - struct TestState { - a: u32, - b: u32, - } - - #[test] - fn test_produce_blob_list_from_sc_public_state() { - let state = TestState { a: 42, b: 99 }; - let result = produce_blob_list_from_sc_public_state(&state).unwrap(); - assert!(!result.is_empty()); - } - - #[test] - fn test_compare_blob_lists_created() { - let old_list: Vec = vec![]; - let new_list: Vec = vec![[1; SC_DATA_BLOB_SIZE].into()]; - - let changes = compare_blob_lists(&old_list, &new_list); - assert_eq!(changes.len(), 1); - assert!(matches!(changes[0], DataBlobChangeVariant::Created { .. })); - } - - #[test] - fn test_compare_blob_lists_deleted() { - let old_list: Vec = vec![[1; SC_DATA_BLOB_SIZE].into()]; - let new_list: Vec = vec![]; - - let changes = compare_blob_lists(&old_list, &new_list); - assert_eq!(changes.len(), 1); - assert!(matches!(changes[0], DataBlobChangeVariant::Deleted { .. })); - } - - #[test] - fn test_compare_blob_lists_modified() { - let old_list: Vec = vec![[1; SC_DATA_BLOB_SIZE].into()]; - let new_list: Vec = vec![[2; SC_DATA_BLOB_SIZE].into()]; - - let changes = compare_blob_lists(&old_list, &new_list); - assert_eq!(changes.len(), 1); - assert!(matches!(changes[0], DataBlobChangeVariant::Modified { .. })); - } } From c1aa0d0004977ffe0e0e9986b996f6a4535f7c2d Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Thu, 26 Jun 2025 22:19:10 -0400 Subject: [PATCH 02/31] fix unused results --- zkvm/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs index 7ab1225..052afe9 100644 --- a/zkvm/src/lib.rs +++ b/zkvm/src/lib.rs @@ -432,7 +432,7 @@ mod tests { let (digest, receipt) = prove(vec![message, message_2], SUMMATION_ELF).unwrap(); - verify(receipt, SUMMATION_ID); + verify(receipt, SUMMATION_ID).unwrap(); assert_eq!(digest, message + message_2); } @@ -443,7 +443,7 @@ mod tests { let (digest, receipt) = prove(vec![message, message_2], SUMMATION_ELF).unwrap(); - verify(receipt, SUMMATION_ID); + verify(receipt, SUMMATION_ID).unwrap(); assert_eq!(digest, message + message_2); } @@ -454,7 +454,7 @@ mod tests { let (digest, receipt) = prove(vec![message, message_2], MULTIPLICATION_ELF).unwrap(); - verify(receipt, MULTIPLICATION_ID); + verify(receipt, MULTIPLICATION_ID).unwrap(); assert_eq!(digest, message * message_2); } @@ -465,7 +465,7 @@ mod tests { let (digest, receipt) = prove(vec![message, message_2], MULTIPLICATION_ELF).unwrap(); - verify(receipt, MULTIPLICATION_ID); + verify(receipt, MULTIPLICATION_ID).unwrap(); assert_eq!(digest, message * message_2); } From 2fadf0c82f0383dd0702027c7c000fc808f9146c Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Thu, 26 Jun 2025 23:15:14 -0400 Subject: [PATCH 03/31] add test_gas_limits_check_sufficient_funds --- zkvm/src/lib.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs index 052afe9..9ea223e 100644 --- a/zkvm/src/lib.rs +++ b/zkvm/src/lib.rs @@ -420,6 +420,8 @@ pub fn verify(receipt: Receipt, image_id: impl Into) -> anyhow::Result<( #[cfg(test)] mod tests { + use crate::gas_calculator::GasCalculator; + use super::*; use test_methods::BIG_CALCULATION_ELF; use test_methods::{MULTIPLICATION_ELF, MULTIPLICATION_ID}; @@ -514,4 +516,15 @@ mod tests { res } + + #[test] + fn test_gas_limits_check_sufficient_funds() { + let message = 1; + let message_2 = 2; + let gas_calc = GasCalculator::new(1, 1, 1, 1, 1, 1000000, 1000000); + + let result = gas_limits_check(vec![message, message_2], SUMMATION_ELF, &gas_calc, 1000000); + assert!(result.is_ok()); + } + } From eb14d632d998b7258bf4d05546360caec5748c3d Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Thu, 26 Jun 2025 23:15:45 -0400 Subject: [PATCH 04/31] add test_gas_limits_check_insufficient_funds --- zkvm/src/lib.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs index 9ea223e..ab61f45 100644 --- a/zkvm/src/lib.rs +++ b/zkvm/src/lib.rs @@ -527,4 +527,14 @@ mod tests { assert!(result.is_ok()); } +#[test] + fn test_gas_limits_check_insufficient_funds() { + let message = 1; + let message_2 = 2; + let gas_calc = GasCalculator::new(1, 1, 1, 1, 1, 1000000, 1000000); + + let result = gas_limits_check(vec![message, message_2], SUMMATION_ELF, &gas_calc, 1); + assert!(matches!(result, Err(ExecutionFailureKind::InsufficientFundsError))); + } + } From d0c5040fe94679c671acd5da71e56a92ff61c7c0 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Thu, 26 Jun 2025 23:16:37 -0400 Subject: [PATCH 05/31] add test_execute_mint_utxo --- zkvm/src/lib.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs index ab61f45..29ebd45 100644 --- a/zkvm/src/lib.rs +++ b/zkvm/src/lib.rs @@ -317,11 +317,12 @@ pub fn prove_mint_utxo_multiple_assets( )) } -pub fn execute_mint_utxo(amount_to_mint: u128, owner: AccountAddress) -> anyhow::Result { +pub fn execute_mint_utxo(amount_to_mint: u128, owner: AccountAddress, randomness: [u8; 32]) -> anyhow::Result { let mut builder = ExecutorEnv::builder(); builder.write(&amount_to_mint)?; builder.write(&owner)?; + builder.write(&randomness)?; let env = builder.build()?; @@ -537,4 +538,16 @@ mod tests { assert!(matches!(result, Err(ExecutionFailureKind::InsufficientFundsError))); } + #[test] + fn test_execute_mint_utxo() { + let owner = AccountAddress::default(); + let amount = 123456789; + let mut randomness = [0u8; 32]; + OsRng.fill_bytes(&mut randomness); + + let utxo_exec = execute_mint_utxo(amount, owner, randomness).expect("execution failed"); + assert_eq!(utxo_exec.amount, amount); + assert_eq!(utxo_exec.owner, owner); + } + } From d9696e77eb1d89122965ef4d3d0550fc0c49ed6f Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Thu, 26 Jun 2025 23:16:56 -0400 Subject: [PATCH 06/31] add test_prove_mint_utxo --- zkvm/src/lib.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs index 29ebd45..1a971a0 100644 --- a/zkvm/src/lib.rs +++ b/zkvm/src/lib.rs @@ -550,4 +550,14 @@ mod tests { assert_eq!(utxo_exec.owner, owner); } +#[test] + fn test_prove_mint_utxo() { + let owner = AccountAddress::default(); + let amount = 123456789; + + let (utxo, _) = prove_mint_utxo(amount, owner).expect("proof failed"); + assert_eq!(utxo.amount, amount); + assert_eq!(utxo.owner, owner); + } + } From 90231f76cc03b14bc39dcf8d9360720e85f0d009 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Thu, 26 Jun 2025 23:17:14 -0400 Subject: [PATCH 07/31] add test_prove_send_utxo --- zkvm/src/lib.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs index 1a971a0..fe777db 100644 --- a/zkvm/src/lib.rs +++ b/zkvm/src/lib.rs @@ -560,4 +560,18 @@ mod tests { assert_eq!(utxo.owner, owner); } +#[test] + fn test_prove_send_utxo() { + let owner = AccountAddress::default(); + let amount = 100; + let (input_utxo, _) = prove_mint_utxo(amount, owner).expect("mint failed"); + + let parts = vec![(40, owner), (60, owner)]; + let (outputs, _receipt) = prove_send_utxo(input_utxo, parts.clone()).expect("send failed"); + + let total: u128 = outputs.iter().map(|(utxo, _)| utxo.amount).sum(); + assert_eq!(total, amount); + assert_eq!(outputs.len(), 2); + } + } From 553e37b7013407c64dfdcf70544bdfc625841867 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Thu, 26 Jun 2025 23:17:34 -0400 Subject: [PATCH 08/31] add test_prove_send_utxo_deshielded --- zkvm/src/lib.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs index fe777db..cc66c2d 100644 --- a/zkvm/src/lib.rs +++ b/zkvm/src/lib.rs @@ -574,4 +574,18 @@ mod tests { assert_eq!(outputs.len(), 2); } +#[test] + fn test_prove_send_utxo_deshielded() { + let owner = AccountAddress::default(); + let amount = 100; + let (utxo, _) = prove_mint_utxo(amount, owner).unwrap(); + let parts = vec![(60, owner), (40, owner)]; + + let (outputs, _) = prove_send_utxo_deshielded(utxo, parts.clone()).unwrap(); + + let total: u128 = outputs.iter().map(|(amt, _)| amt).sum(); + assert_eq!(total, amount); + assert_eq!(outputs.len(), 2); + } + } From a5c8e5125c29582cb2e1bad47ed29c013aa710fc Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Thu, 26 Jun 2025 23:17:58 -0400 Subject: [PATCH 09/31] add test_prove_send_utxo_shielded --- zkvm/src/lib.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs index cc66c2d..5481724 100644 --- a/zkvm/src/lib.rs +++ b/zkvm/src/lib.rs @@ -588,4 +588,17 @@ mod tests { assert_eq!(outputs.len(), 2); } + #[test] + fn test_prove_send_utxo_shielded() { + let owner = AccountAddress::default(); + let amount = 100; + let parts = vec![(60, owner), (40, owner)]; + + let (outputs, _) = prove_send_utxo_shielded(owner, amount, parts.clone()).unwrap(); + + let total: u128 = outputs.iter().map(|(utxo, _)| utxo.amount).sum(); + assert_eq!(total, amount); + assert_eq!(outputs.len(), 2); + } + } From b31f753c11b49c889eb0af41220693336d639e93 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Thu, 26 Jun 2025 23:18:18 -0400 Subject: [PATCH 10/31] add test_prove_send_utxo_multiple_assets_one_receiver --- zkvm/src/lib.rs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs index 5481724..a967bd3 100644 --- a/zkvm/src/lib.rs +++ b/zkvm/src/lib.rs @@ -528,7 +528,7 @@ mod tests { assert!(result.is_ok()); } -#[test] + #[test] fn test_gas_limits_check_insufficient_funds() { let message = 1; let message_2 = 2; @@ -550,7 +550,7 @@ mod tests { assert_eq!(utxo_exec.owner, owner); } -#[test] + #[test] fn test_prove_mint_utxo() { let owner = AccountAddress::default(); let amount = 123456789; @@ -560,7 +560,7 @@ mod tests { assert_eq!(utxo.owner, owner); } -#[test] + #[test] fn test_prove_send_utxo() { let owner = AccountAddress::default(); let amount = 100; @@ -574,7 +574,7 @@ mod tests { assert_eq!(outputs.len(), 2); } -#[test] + #[test] fn test_prove_send_utxo_deshielded() { let owner = AccountAddress::default(); let amount = 100; @@ -601,4 +601,20 @@ mod tests { assert_eq!(outputs.len(), 2); } + #[test] + fn test_prove_send_utxo_multiple_assets_one_receiver() { + let owner = AccountAddress::default(); + let receiver = AccountAddress::default(); + + let utxos = vec![ + prove_mint_utxo(100, owner).unwrap().0, + prove_mint_utxo(50, owner).unwrap().0, + ]; + + let (to_receiver, to_change, _receipt) = prove_send_utxo_multiple_assets_one_receiver(utxos, 1, receiver).unwrap(); + let total_to_receiver: u128 = to_receiver.iter().map(|u| u.amount).sum(); + + assert!(total_to_receiver > 0); + assert_eq!(to_receiver.len() + to_change.len(), 2); + } } From 28005ae633109aa4f32ff4331545063c4ac81879 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Thu, 26 Jun 2025 23:18:30 -0400 Subject: [PATCH 11/31] fmt --- zkvm/src/lib.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs index a967bd3..075657e 100644 --- a/zkvm/src/lib.rs +++ b/zkvm/src/lib.rs @@ -317,7 +317,11 @@ pub fn prove_mint_utxo_multiple_assets( )) } -pub fn execute_mint_utxo(amount_to_mint: u128, owner: AccountAddress, randomness: [u8; 32]) -> anyhow::Result { +pub fn execute_mint_utxo( + amount_to_mint: u128, + owner: AccountAddress, + randomness: [u8; 32], +) -> anyhow::Result { let mut builder = ExecutorEnv::builder(); builder.write(&amount_to_mint)?; @@ -535,7 +539,10 @@ mod tests { let gas_calc = GasCalculator::new(1, 1, 1, 1, 1, 1000000, 1000000); let result = gas_limits_check(vec![message, message_2], SUMMATION_ELF, &gas_calc, 1); - assert!(matches!(result, Err(ExecutionFailureKind::InsufficientFundsError))); + assert!(matches!( + result, + Err(ExecutionFailureKind::InsufficientFundsError) + )); } #[test] @@ -611,7 +618,8 @@ mod tests { prove_mint_utxo(50, owner).unwrap().0, ]; - let (to_receiver, to_change, _receipt) = prove_send_utxo_multiple_assets_one_receiver(utxos, 1, receiver).unwrap(); + let (to_receiver, to_change, _receipt) = + prove_send_utxo_multiple_assets_one_receiver(utxos, 1, receiver).unwrap(); let total_to_receiver: u128 = to_receiver.iter().map(|u| u.amount).sum(); assert!(total_to_receiver > 0); From 8e987847eeffe99326292e9d3ccde4c17d96c074 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Wed, 9 Jul 2025 08:16:12 +0300 Subject: [PATCH 12/31] feat: AccountPublicData struct changed --- .../src/sequencer_store/accounts_store.rs | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/sequencer_core/src/sequencer_store/accounts_store.rs b/sequencer_core/src/sequencer_store/accounts_store.rs index fe1286f..3e43e67 100644 --- a/sequencer_core/src/sequencer_store/accounts_store.rs +++ b/sequencer_core/src/sequencer_store/accounts_store.rs @@ -1,29 +1,13 @@ -use accounts::account_core::{AccountAddress, PublicKey}; -use k256::AffinePoint; +use accounts::account_core::AccountAddress; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct AccountPublicData { - pub nullifier_public_key: PublicKey, - pub viewing_public_key: PublicKey, + pub balance: u64, pub address: AccountAddress, } -impl AccountPublicData { - pub fn from_raw( - address: AccountAddress, - nullifier_public_key: Vec, - viewing_public_key: Vec, - ) -> Self { - Self { - nullifier_public_key: serde_json::from_slice::(&nullifier_public_key) - .unwrap(), - viewing_public_key: serde_json::from_slice::(&viewing_public_key).unwrap(), - address, - } - } -} - #[derive(Debug, Clone)] pub struct SequencerAccountsStore { pub accounts: HashMap, From 54284be74b88673a03c629b4be99c4df1dc435b1 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Wed, 9 Jul 2025 16:03:30 +0300 Subject: [PATCH 13/31] fix: account data public only for sequencer --- common/src/rpc_primitives/requests.rs | 2 -- node_core/src/sequencer_client/mod.rs | 3 --- sequencer_core/src/lib.rs | 16 ++++++++-------- .../src/sequencer_store/accounts_store.rs | 17 +++++++++++++---- sequencer_rpc/src/process.rs | 7 +------ 5 files changed, 22 insertions(+), 23 deletions(-) diff --git a/common/src/rpc_primitives/requests.rs b/common/src/rpc_primitives/requests.rs index 6cad01d..395badf 100644 --- a/common/src/rpc_primitives/requests.rs +++ b/common/src/rpc_primitives/requests.rs @@ -13,8 +13,6 @@ pub struct HelloRequest {} #[derive(Serialize, Deserialize, Debug)] pub struct RegisterAccountRequest { - pub nullifier_public_key: Vec, - pub viewing_public_key: Vec, pub address: [u8; 32], } diff --git a/node_core/src/sequencer_client/mod.rs b/node_core/src/sequencer_client/mod.rs index 7accd5f..c348395 100644 --- a/node_core/src/sequencer_client/mod.rs +++ b/node_core/src/sequencer_client/mod.rs @@ -7,7 +7,6 @@ use common::rpc_primitives::requests::{ use common::transaction::Transaction; use common::{SequencerClientError, SequencerRpcError}; use json::{SendTxRequest, SendTxResponse, SequencerRpcRequest, SequencerRpcResponse}; -use k256::elliptic_curve::group::GroupEncoding; use reqwest::Client; use serde_json::Value; @@ -94,8 +93,6 @@ impl SequencerClient { account: &Account, ) -> Result { let acc_req = RegisterAccountRequest { - nullifier_public_key: account.key_holder.nullifer_public_key.to_bytes().to_vec(), - viewing_public_key: account.key_holder.viewing_public_key.to_bytes().to_vec(), address: account.address, }; diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index 7a083f1..1ed603b 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -1,5 +1,6 @@ use std::fmt::Display; +use accounts::account_core::AccountAddress; use anyhow::Result; use common::{ block::{Block, HashableBlockData}, @@ -10,7 +11,7 @@ use common::{ }; use config::SequencerConfig; use mempool::MemPool; -use sequencer_store::{accounts_store::AccountPublicData, SequecerChainStore}; +use sequencer_store::SequecerChainStore; use serde::{Deserialize, Serialize}; use transaction_mempool::TransactionMempool; @@ -209,11 +210,8 @@ impl SequencerCore { Ok(()) } - pub fn register_account(&mut self, acc_data: AccountPublicData) { - self.store - .acc_store - .accounts - .insert(acc_data.address, acc_data); + pub fn register_account(&mut self, account_addr: AccountAddress) { + self.store.acc_store.register_account(account_addr); } ///Produces new block from transactions in mempool @@ -306,12 +304,14 @@ mod tests { } } - fn common_setup(mut sequencer: &mut SequencerCore) { + fn common_setup(sequencer: &mut SequencerCore) { let tx = create_dummy_transaction([12; 32], vec![[9; 32]], vec![[7; 32]], vec![[8; 32]]); let tx_mempool = TransactionMempool { tx }; sequencer.mempool.push_item(tx_mempool); - sequencer.produce_new_block_with_mempool_transactions(); + sequencer + .produce_new_block_with_mempool_transactions() + .unwrap(); } #[test] diff --git a/sequencer_core/src/sequencer_store/accounts_store.rs b/sequencer_core/src/sequencer_store/accounts_store.rs index 3e43e67..8f3eef0 100644 --- a/sequencer_core/src/sequencer_store/accounts_store.rs +++ b/sequencer_core/src/sequencer_store/accounts_store.rs @@ -3,14 +3,23 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct AccountPublicData { +pub(crate) struct AccountPublicData { pub balance: u64, pub address: AccountAddress, } +impl AccountPublicData { + pub fn new(address: AccountAddress) -> Self { + Self { + balance: 0, + address, + } + } +} + #[derive(Debug, Clone)] pub struct SequencerAccountsStore { - pub accounts: HashMap, + accounts: HashMap, } impl SequencerAccountsStore { @@ -20,9 +29,9 @@ impl SequencerAccountsStore { } } - pub fn register_account(&mut self, account_pub_data: AccountPublicData) { + pub fn register_account(&mut self, account_addr: AccountAddress) { self.accounts - .insert(account_pub_data.address, account_pub_data); + .insert(account_addr, AccountPublicData::new(account_addr)); } pub fn unregister_account(&mut self, account_addr: AccountAddress) { diff --git a/sequencer_rpc/src/process.rs b/sequencer_rpc/src/process.rs index 5bac835..cab07bf 100644 --- a/sequencer_rpc/src/process.rs +++ b/sequencer_rpc/src/process.rs @@ -1,5 +1,4 @@ use actix_web::Error as HttpError; -use sequencer_core::sequencer_store::accounts_store::AccountPublicData; use serde_json::Value; use common::rpc_primitives::{ @@ -61,11 +60,7 @@ impl JsonHandler { { let mut acc_store = self.sequencer_state.lock().await; - acc_store.register_account(AccountPublicData::from_raw( - acc_req.address, - acc_req.nullifier_public_key, - acc_req.viewing_public_key, - )); + acc_store.register_account(acc_req.address); } let helperstruct = RegisterAccountResponse { From 5e9c6a0677c4dc73b0148d7dbad915378b202170 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Fri, 11 Jul 2025 10:34:13 +0300 Subject: [PATCH 14/31] feat: preset accounts in sequencer account store --- .../src/sequencer_store/accounts_store.rs | 119 +++++++++++++++++- 1 file changed, 115 insertions(+), 4 deletions(-) diff --git a/sequencer_core/src/sequencer_store/accounts_store.rs b/sequencer_core/src/sequencer_store/accounts_store.rs index 8f3eef0..bc65565 100644 --- a/sequencer_core/src/sequencer_store/accounts_store.rs +++ b/sequencer_core/src/sequencer_store/accounts_store.rs @@ -15,6 +15,10 @@ impl AccountPublicData { address, } } + + pub fn new_with_balance(address: AccountAddress, balance: u64) -> Self { + Self { balance, address } + } } #[derive(Debug, Clone)] @@ -23,10 +27,17 @@ pub struct SequencerAccountsStore { } impl SequencerAccountsStore { - pub fn new() -> Self { - Self { - accounts: HashMap::new(), + pub fn new(initial_accounts: &[(AccountAddress, u64)]) -> Self { + let mut accounts = HashMap::new(); + + for (account_addr, balance) in initial_accounts { + accounts.insert( + *account_addr, + AccountPublicData::new_with_balance(*account_addr, *balance), + ); } + + Self { accounts } } pub fn register_account(&mut self, account_addr: AccountAddress) { @@ -34,6 +45,14 @@ impl SequencerAccountsStore { .insert(account_addr, AccountPublicData::new(account_addr)); } + pub fn contains_account(&self, account_addr: &AccountAddress) -> bool { + self.accounts.contains_key(account_addr) + } + + pub fn get_account_balance(&self, account_addr: &AccountAddress) -> Option { + self.accounts.get(account_addr).map(|acc| acc.balance) + } + pub fn unregister_account(&mut self, account_addr: AccountAddress) { self.accounts.remove(&account_addr); } @@ -41,6 +60,98 @@ impl SequencerAccountsStore { impl Default for SequencerAccountsStore { fn default() -> Self { - Self::new() + Self::new(&[]) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_zero_balance_account_data_creation() { + let new_acc = AccountPublicData::new([1; 32]); + + assert_eq!(new_acc.balance, 0); + assert_eq!(new_acc.address, [1; 32]); + } + + #[test] + fn test_non_zero_balance_account_data_creation() { + let new_acc = AccountPublicData::new_with_balance([1; 32], 10); + + assert_eq!(new_acc.balance, 10); + assert_eq!(new_acc.address, [1; 32]); + } + + #[test] + fn default_account_sequencer_store() { + let seq_acc_store = SequencerAccountsStore::default(); + + assert!(seq_acc_store.accounts.is_empty()); + } + + #[test] + fn account_sequencer_store_register_acc() { + let mut seq_acc_store = SequencerAccountsStore::default(); + + seq_acc_store.register_account([1; 32]); + + assert!(seq_acc_store.contains_account(&[1; 32])); + + let acc_balance = seq_acc_store.get_account_balance(&[1; 32]).unwrap(); + + assert_eq!(acc_balance, 0); + } + + #[test] + fn account_sequencer_store_unregister_acc() { + let mut seq_acc_store = SequencerAccountsStore::default(); + + seq_acc_store.register_account([1; 32]); + + assert!(seq_acc_store.contains_account(&[1; 32])); + + seq_acc_store.unregister_account([1; 32]); + + assert!(!seq_acc_store.contains_account(&[1; 32])); + } + + #[test] + fn account_sequencer_store_with_preset_accounts_1() { + let seq_acc_store = SequencerAccountsStore::new(&[([1; 32], 12), ([2; 32], 100)]); + + assert!(seq_acc_store.contains_account(&[1; 32])); + assert!(seq_acc_store.contains_account(&[2; 32])); + + let acc_balance = seq_acc_store.get_account_balance(&[1; 32]).unwrap(); + + assert_eq!(acc_balance, 12); + + let acc_balance = seq_acc_store.get_account_balance(&[2; 32]).unwrap(); + + assert_eq!(acc_balance, 100); + } + + #[test] + fn account_sequencer_store_with_preset_accounts_2() { + let seq_acc_store = + SequencerAccountsStore::new(&[([6; 32], 120), ([7; 32], 15), ([8; 32], 10)]); + + assert!(seq_acc_store.contains_account(&[6; 32])); + assert!(seq_acc_store.contains_account(&[7; 32])); + assert!(seq_acc_store.contains_account(&[8; 32])); + + let acc_balance = seq_acc_store.get_account_balance(&[6; 32]).unwrap(); + + assert_eq!(acc_balance, 120); + + let acc_balance = seq_acc_store.get_account_balance(&[7; 32]).unwrap(); + + assert_eq!(acc_balance, 15); + + let acc_balance = seq_acc_store.get_account_balance(&[8; 32]).unwrap(); + + assert_eq!(acc_balance, 10); } } From d76358c37fd19fd4bc06f08c7a2135d34f8cb1dd Mon Sep 17 00:00:00 2001 From: Moudy Date: Sun, 13 Jul 2025 23:12:31 +0200 Subject: [PATCH 15/31] Update README.md --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index b38464b..c7536ef 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,7 @@ Request: } ``` -Responce: +Response: ```yaml { @@ -171,7 +171,7 @@ Request: } ``` -Responce: +Response: ```yaml { @@ -200,7 +200,7 @@ Request: } ``` -Responce: +Response: ```yaml { @@ -231,7 +231,7 @@ Request: } ``` -Responce: +Response: ```yaml { @@ -265,7 +265,7 @@ Request: } ``` -Responce: +Response: ```yaml { @@ -298,7 +298,7 @@ Request: } ``` -Responce: +Response: ```yaml { @@ -335,7 +335,7 @@ Request: } ``` -Responce: +Response: ```yaml { @@ -373,7 +373,7 @@ Request: } ``` -Responce: +Response: ```yaml { @@ -414,7 +414,7 @@ Request: } ``` -Responce: +Response: ```yaml { @@ -449,7 +449,7 @@ Request: } ``` -Responce: +Response: ```yaml { From a43a32fc551221f06a6ac281e67f24c3841aad16 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Mon, 14 Jul 2025 10:43:35 +0300 Subject: [PATCH 16/31] feat: initial accounts configuration --- Cargo.lock | 1 + sequencer_core/Cargo.toml | 1 + sequencer_core/src/config.rs | 10 +++- sequencer_core/src/lib.rs | 48 +++++++++++++++++++ sequencer_core/src/sequencer_store/mod.rs | 26 +++++++++- .../configs/debug/sequencer_config.json | 12 ++++- 6 files changed, 94 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0200d46..8c4a396 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4336,6 +4336,7 @@ dependencies = [ "common", "elliptic-curve", "env_logger", + "hex", "k256", "log", "mempool", diff --git a/sequencer_core/Cargo.toml b/sequencer_core/Cargo.toml index 06df7c5..14c047c 100644 --- a/sequencer_core/Cargo.toml +++ b/sequencer_core/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] +hex.workspace = true anyhow.workspace = true serde_json.workspace = true env_logger.workspace = true diff --git a/sequencer_core/src/config.rs b/sequencer_core/src/config.rs index 53b18a9..707b8b9 100644 --- a/sequencer_core/src/config.rs +++ b/sequencer_core/src/config.rs @@ -1,6 +1,12 @@ +use serde::{Deserialize, Serialize}; use std::path::PathBuf; -use serde::{Deserialize, Serialize}; +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct AccountInitialData { + ///Hex encoded AccountAddress + pub addr: String, + pub balance: u64, +} #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SequencerConfig { @@ -18,4 +24,6 @@ pub struct SequencerConfig { pub block_create_timeout_millis: u64, ///Port to listen pub port: u16, + ///List of pairs (account_address, initial_balance) + pub initial_accounts: Vec, } diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index 1ed603b..2ebff42 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -53,6 +53,7 @@ impl SequencerCore { &config.home, config.genesis_id, config.is_genesis_random, + &config.initial_accounts, ), mempool: MemPool::::default(), chain_height: config.genesis_id, @@ -252,6 +253,8 @@ impl SequencerCore { #[cfg(test)] mod tests { + use crate::config::AccountInitialData; + use super::*; use std::path::PathBuf; @@ -274,6 +277,18 @@ mod tests { max_num_tx_in_block: 10, block_create_timeout_millis: 1000, port: 8080, + initial_accounts: vec![ + AccountInitialData { + addr: "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117d09a8c" + .to_string(), + balance: 10, + }, + AccountInitialData { + addr: "20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1e376f31" + .to_string(), + balance: 100, + }, + ], } } @@ -322,6 +337,39 @@ mod tests { assert_eq!(sequencer.chain_height, config.genesis_id); assert_eq!(sequencer.sequencer_config.max_num_tx_in_block, 10); assert_eq!(sequencer.sequencer_config.port, 8080); + + let acc1_addr: [u8; 32] = hex::decode( + "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117d09a8c".to_string(), + ) + .unwrap() + .try_into() + .unwrap(); + let acc2_addr: [u8; 32] = hex::decode( + "20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1e376f31".to_string(), + ) + .unwrap() + .try_into() + .unwrap(); + + assert!(sequencer.store.acc_store.contains_account(&acc1_addr)); + assert!(sequencer.store.acc_store.contains_account(&acc2_addr)); + + assert_eq!( + 10, + sequencer + .store + .acc_store + .get_account_balance(&acc1_addr) + .unwrap() + ); + assert_eq!( + 100, + sequencer + .store + .acc_store + .get_account_balance(&acc2_addr) + .unwrap() + ); } #[test] diff --git a/sequencer_core/src/sequencer_store/mod.rs b/sequencer_core/src/sequencer_store/mod.rs index 322c99d..daffc91 100644 --- a/sequencer_core/src/sequencer_store/mod.rs +++ b/sequencer_core/src/sequencer_store/mod.rs @@ -9,6 +9,8 @@ use common::{ }; use rand::{rngs::OsRng, RngCore}; +use crate::config::AccountInitialData; + pub mod accounts_store; pub mod block_store; @@ -21,8 +23,28 @@ pub struct SequecerChainStore { } impl SequecerChainStore { - pub fn new_with_genesis(home_dir: &Path, genesis_id: u64, is_genesis_random: bool) -> Self { - let acc_store = SequencerAccountsStore::default(); + pub fn new_with_genesis( + home_dir: &Path, + genesis_id: u64, + is_genesis_random: bool, + initial_accounts: &[AccountInitialData], + ) -> Self { + let acc_data_decoded: Vec<([u8; 32], u64)> = initial_accounts + .iter() + .map(|acc_data| { + ( + //ToDo: Handle this error for direct error message + //Failure to produce account address is critical, so error handling is needed only for clarity + hex::decode(acc_data.addr.clone()) + .unwrap() + .try_into() + .unwrap(), + acc_data.balance, + ) + }) + .collect(); + + let acc_store = SequencerAccountsStore::new(&acc_data_decoded); let nullifier_store = HashSet::new(); let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]); let pub_tx_store = PublicTransactionMerkleTree::new(vec![]); diff --git a/sequencer_runner/configs/debug/sequencer_config.json b/sequencer_runner/configs/debug/sequencer_config.json index 5eccadd..18d1b72 100644 --- a/sequencer_runner/configs/debug/sequencer_config.json +++ b/sequencer_runner/configs/debug/sequencer_config.json @@ -5,5 +5,15 @@ "is_genesis_random": true, "max_num_tx_in_block": 20, "block_create_timeout_millis": 10000, - "port": 3040 + "port": 3040, + "initial_accounts": [ + { + "addr": "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117d09a8c", + "balance": 10 + }, + { + "addr": "20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1e376f31", + "balance": 100 + } + ] } \ No newline at end of file From 5f4d6c0f8d05b34f97a37e59fe7e5f250866a169 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Mon, 14 Jul 2025 13:17:46 +0300 Subject: [PATCH 17/31] fix: additional test with other accounts --- sequencer_core/src/lib.rs | 72 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index 2ebff42..308b2f6 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -292,6 +292,26 @@ mod tests { } } + fn setup_sequencer_config_variable_initial_accounts( + initial_accounts: Vec, + ) -> SequencerConfig { + let mut rng = rand::thread_rng(); + let random_u8: u8 = rng.gen(); + + let path_str = format!("/tmp/sequencer_{:?}", random_u8); + + SequencerConfig { + home: PathBuf::from(path_str), + override_rust_log: Some("info".to_string()), + genesis_id: 1, + is_genesis_random: false, + max_num_tx_in_block: 10, + block_create_timeout_millis: 1000, + port: 8080, + initial_accounts, + } + } + fn create_dummy_transaction( hash: TreeHashType, nullifier_created_hashes: Vec<[u8; 32]>, @@ -372,6 +392,58 @@ mod tests { ); } + #[test] + fn test_start_different_intial_accounts() { + let initial_accounts = vec![ + AccountInitialData { + addr: "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117ffffff" + .to_string(), + balance: 1000, + }, + AccountInitialData { + addr: "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117ffffff" + .to_string(), + balance: 1000, + }, + ]; + + let config = setup_sequencer_config_variable_initial_accounts(initial_accounts); + let sequencer = SequencerCore::start_from_config(config.clone()); + + let acc1_addr: [u8; 32] = hex::decode( + "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117ffffff".to_string(), + ) + .unwrap() + .try_into() + .unwrap(); + let acc2_addr: [u8; 32] = hex::decode( + "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117ffffff".to_string(), + ) + .unwrap() + .try_into() + .unwrap(); + + assert!(sequencer.store.acc_store.contains_account(&acc1_addr)); + assert!(sequencer.store.acc_store.contains_account(&acc2_addr)); + + assert_eq!( + 1000, + sequencer + .store + .acc_store + .get_account_balance(&acc1_addr) + .unwrap() + ); + assert_eq!( + 1000, + sequencer + .store + .acc_store + .get_account_balance(&acc2_addr) + .unwrap() + ); + } + #[test] fn test_get_tree_roots() { let config = setup_sequencer_config(); From a24a40f4bc597bdb161c8e69575d92513c3220bb Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Mon, 14 Jul 2025 13:25:40 +0300 Subject: [PATCH 18/31] fix: docs added --- sequencer_core/src/config.rs | 3 ++- sequencer_core/src/sequencer_store/accounts_store.rs | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sequencer_core/src/config.rs b/sequencer_core/src/config.rs index 707b8b9..374a940 100644 --- a/sequencer_core/src/config.rs +++ b/sequencer_core/src/config.rs @@ -2,8 +2,9 @@ use serde::{Deserialize, Serialize}; use std::path::PathBuf; #[derive(Debug, Serialize, Deserialize, Clone)] +///Helperstruct for account serialization pub struct AccountInitialData { - ///Hex encoded AccountAddress + ///Hex encoded `AccountAddress` pub addr: String, pub balance: u64, } diff --git a/sequencer_core/src/sequencer_store/accounts_store.rs b/sequencer_core/src/sequencer_store/accounts_store.rs index bc65565..49df8ea 100644 --- a/sequencer_core/src/sequencer_store/accounts_store.rs +++ b/sequencer_core/src/sequencer_store/accounts_store.rs @@ -40,19 +40,27 @@ impl SequencerAccountsStore { Self { accounts } } + ///Register new account in accounts store + /// + ///Starts with zero public balance pub fn register_account(&mut self, account_addr: AccountAddress) { self.accounts .insert(account_addr, AccountPublicData::new(account_addr)); } + ///Check, if `account_addr` present in account store pub fn contains_account(&self, account_addr: &AccountAddress) -> bool { self.accounts.contains_key(account_addr) } + ///Check `account_addr` balance, + /// + ///returns `None`, if account address not found pub fn get_account_balance(&self, account_addr: &AccountAddress) -> Option { self.accounts.get(account_addr).map(|acc| acc.balance) } + ///Remove account from storage pub fn unregister_account(&mut self, account_addr: AccountAddress) { self.accounts.remove(&account_addr); } From 90205c6330eaba881bb49dbd1b846bbe4b7a6e71 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Tue, 15 Jul 2025 12:49:19 +0300 Subject: [PATCH 19/31] fix: account masks updates to safe state --- accounts/src/account_core/mod.rs | 22 ++- accounts/src/key_management/mod.rs | 14 +- node_core/src/chain_storage/mod.rs | 9 +- node_core/src/chain_storage/public_context.rs | 180 ------------------ node_core/src/lib.rs | 17 +- sc_core/src/transaction_payloads_tools.rs | 4 +- 6 files changed, 37 insertions(+), 209 deletions(-) delete mode 100644 node_core/src/chain_storage/public_context.rs diff --git a/accounts/src/account_core/mod.rs b/accounts/src/account_core/mod.rs index 079e725..b1b4a91 100644 --- a/accounts/src/account_core/mod.rs +++ b/accounts/src/account_core/mod.rs @@ -85,6 +85,8 @@ impl<'de> Deserialize<'de> for Account { ///A strucure, which represents all the visible(public) information /// /// known to each node about account `address` +/// +/// Main usage is to encode data for other account #[derive(Serialize, Clone)] pub struct AccountPublicMask { pub nullifier_public_key: AffinePoint, @@ -99,16 +101,13 @@ impl AccountPublicMask { viewing_public_key_receiver: AffinePoint, data: &[u8], ) -> (CipherText, Nonce) { - ephemeral_key_holder.encrypt_data(viewing_public_key_receiver, data) + //Using of parent Account fuction + Account::encrypt_data(ephemeral_key_holder, viewing_public_key_receiver, data) } pub fn make_tag(&self) -> Tag { self.address[0] } - - pub fn produce_ephemeral_key_holder(&self) -> EphemeralKeyHolder { - EphemeralKeyHolder::new_os_random() - } } impl Account { @@ -139,10 +138,6 @@ impl Account { } } - pub fn produce_ephemeral_key_holder(&self) -> EphemeralKeyHolder { - self.key_holder.produce_ephemeral_key_holder() - } - pub fn encrypt_data( ephemeral_key_holder: &EphemeralKeyHolder, viewing_public_key_receiver: AffinePoint, @@ -267,4 +262,13 @@ mod tests { assert!(result.is_ok()); assert_eq!(account.utxos.len(), 1); } + + #[test] + fn accounts_accounts_mask_tag_consistency() { + let account = Account::new(); + + let account_mask = account.make_account_public_mask(); + + assert_eq!(account.make_tag(), account_mask.make_tag()); + } } diff --git a/accounts/src/key_management/mod.rs b/accounts/src/key_management/mod.rs index 69b8ce0..24ac045 100644 --- a/accounts/src/key_management/mod.rs +++ b/accounts/src/key_management/mod.rs @@ -2,7 +2,6 @@ use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit}; use common::merkle_tree_public::TreeHashType; use constants_types::{CipherText, Nonce}; use elliptic_curve::point::AffineCoordinates; -use ephemeral_key_holder::EphemeralKeyHolder; use k256::AffinePoint; use log::info; use secret_holders::{SeedHolder, TopSecretKeyHolder, UTXOSecretKeyHolder}; @@ -55,10 +54,6 @@ impl AddressKeyHolder { (ephemeral_public_key_sender * self.utxo_secret_key_holder.viewing_secret_key).into() } - pub fn produce_ephemeral_key_holder(&self) -> EphemeralKeyHolder { - EphemeralKeyHolder::new_os_random() - } - pub fn decrypt_data( &self, ephemeral_public_key_sender: AffinePoint, @@ -114,6 +109,8 @@ mod tests { use elliptic_curve::point::AffineCoordinates; use k256::{AffinePoint, ProjectivePoint, Scalar}; + use crate::key_management::ephemeral_key_holder::EphemeralKeyHolder; + use super::*; #[test] @@ -136,7 +133,7 @@ mod tests { // Generate a random ephemeral public key sender let scalar = Scalar::random(&mut OsRng); - let ephemeral_public_key_sender = (ProjectivePoint::generator() * scalar).to_affine(); + let ephemeral_public_key_sender = (ProjectivePoint::GENERATOR * scalar).to_affine(); // Calculate shared secret let shared_secret = @@ -151,9 +148,8 @@ mod tests { let address_key_holder = AddressKeyHolder::new_os_random(); // Generate an ephemeral key and shared secret - let ephemeral_public_key_sender = address_key_holder - .produce_ephemeral_key_holder() - .generate_ephemeral_public_key(); + let ephemeral_public_key_sender = + EphemeralKeyHolder::new_os_random().generate_ephemeral_public_key(); let shared_secret = address_key_holder.calculate_shared_secret_receiver(ephemeral_public_key_sender); diff --git a/node_core/src/chain_storage/mod.rs b/node_core/src/chain_storage/mod.rs index f6b1343..d8e8065 100644 --- a/node_core/src/chain_storage/mod.rs +++ b/node_core/src/chain_storage/mod.rs @@ -11,7 +11,7 @@ use common::{ }; use k256::AffinePoint; use log::{info, warn}; -use public_context::PublicSCContext; +use sc_core::public_context::PublicSCContext; use serde::{Deserialize, Serialize}; use utxo::utxo_core::UTXO; @@ -19,7 +19,6 @@ use crate::{config::NodeConfig, ActionData}; pub mod accounts_store; pub mod block_store; -pub mod public_context; #[derive(Deserialize, Serialize)] pub struct AccMap { @@ -267,6 +266,12 @@ impl NodeChainStore { account_masks, comitment_store_root: self.utxo_commitments_store.get_root().unwrap_or([0; 32]), pub_tx_store_root: self.pub_tx_store.get_root().unwrap_or([0; 32]), + nullifiers_set: self + .nullifier_store + .iter() + .map(|item| item.utxo_hash) + .collect(), + commitments_tree: self.utxo_commitments_store.clone(), } } } diff --git a/node_core/src/chain_storage/public_context.rs b/node_core/src/chain_storage/public_context.rs deleted file mode 100644 index 438fa50..0000000 --- a/node_core/src/chain_storage/public_context.rs +++ /dev/null @@ -1,180 +0,0 @@ -use std::collections::BTreeMap; - -use accounts::account_core::{AccountAddress, AccountPublicMask}; -use common::merkle_tree_public::TreeHashType; -use serde::{ser::SerializeStruct, Serialize}; - -pub const PUBLIC_SC_CONTEXT: &str = "PublicSCContext"; -pub const CALLER_ADDRESS: &str = "caller_address"; -pub const CALLER_BALANCE: &str = "caller_balance"; -pub const ACCOUNT_MASKS_KEYS_SORTED: &str = "account_masks_keys_sorted"; -pub const ACCOUNT_MASKS_VALUES_SORTED: &str = "account_masks_values_sorted"; -pub const COMMITMENT_STORE_ROOT: &str = "commitment_store_root"; -pub const PUT_TX_STORE_ROOT: &str = "put_tx_store_root"; - -///Strucutre, representing context, given to a smart contract on a call -pub struct PublicSCContext { - pub caller_address: AccountAddress, - pub caller_balance: u64, - pub account_masks: BTreeMap, - pub comitment_store_root: TreeHashType, - pub pub_tx_store_root: TreeHashType, -} - -impl Serialize for PublicSCContext { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut account_masks_keys: Vec<[u8; 32]> = self.account_masks.keys().cloned().collect(); - account_masks_keys.sort(); - - let mut account_mask_values: Vec = - self.account_masks.values().cloned().collect(); - account_mask_values.sort_by(|left, right| left.address.cmp(&right.address)); - - let mut s = serializer.serialize_struct(PUBLIC_SC_CONTEXT, 7)?; - - s.serialize_field(CALLER_ADDRESS, &self.caller_address)?; - s.serialize_field(CALLER_BALANCE, &self.caller_balance)?; - s.serialize_field(ACCOUNT_MASKS_KEYS_SORTED, &account_masks_keys)?; - s.serialize_field(ACCOUNT_MASKS_VALUES_SORTED, &account_mask_values)?; - s.serialize_field(COMMITMENT_STORE_ROOT, &self.comitment_store_root)?; - s.serialize_field(PUT_TX_STORE_ROOT, &self.pub_tx_store_root)?; - - s.end() - } -} - -impl PublicSCContext { - ///Produces `u64` from bytes in a vector - /// - /// Assumes, that vector of le_bytes - pub fn produce_u64_from_fit_vec(data: Vec) -> u64 { - let data_len = data.len(); - - assert!(data_len <= 8); - let mut le_bytes: [u8; 8] = [0; 8]; - - for (idx, item) in data.into_iter().enumerate() { - le_bytes[idx] = item - } - - u64::from_le_bytes(le_bytes) - } - - ///Produces vector of `u64` from context - pub fn produce_u64_list_from_context(&self) -> Result, serde_json::Error> { - let mut u64_list = vec![]; - - let ser_data = serde_json::to_vec(self)?; - - //`ToDo` Replace with `next_chunk` usage, when feature stabilizes in Rust - for i in 0..=(ser_data.len() / 8) { - let next_chunk: Vec; - - if (i + 1) * 8 < ser_data.len() { - next_chunk = ser_data[(i * 8)..((i + 1) * 8)].iter().cloned().collect(); - } else { - next_chunk = ser_data[(i * 8)..(ser_data.len())] - .iter() - .cloned() - .collect(); - } - - u64_list.push(PublicSCContext::produce_u64_from_fit_vec(next_chunk)); - } - - Ok(u64_list) - } -} - -#[cfg(test)] -mod tests { - use accounts::account_core::Account; - - use super::*; - - fn create_test_context() -> PublicSCContext { - let caller_address = [1; 32]; - let comitment_store_root = [3; 32]; - let pub_tx_store_root = [4; 32]; - - let mut account_masks = BTreeMap::new(); - - let acc_1 = Account::new(); - let acc_2 = Account::new(); - let acc_3 = Account::new(); - - account_masks.insert(acc_1.address, acc_1.make_account_public_mask()); - account_masks.insert(acc_2.address, acc_2.make_account_public_mask()); - account_masks.insert(acc_3.address, acc_3.make_account_public_mask()); - - PublicSCContext { - caller_address, - caller_balance: 100, - account_masks, - comitment_store_root, - pub_tx_store_root, - } - } - - #[test] - fn bin_ser_stability_test() { - let test_context = create_test_context(); - - let serialization_1 = serde_json::to_vec(&test_context).unwrap(); - let serialization_2 = serde_json::to_vec(&test_context).unwrap(); - - assert_eq!(serialization_1, serialization_2); - } - - #[test] - fn correct_u64_production_from_fit_vec() { - let le_vec = vec![1, 1, 1, 1, 2, 1, 1, 1]; - - let num = PublicSCContext::produce_u64_from_fit_vec(le_vec); - - assert_eq!(num, 72340177133043969); - } - - #[test] - fn correct_u64_production_from_small_vec() { - //7 items instead of 8 - let le_vec = vec![1, 1, 1, 1, 2, 1, 1]; - - let num = PublicSCContext::produce_u64_from_fit_vec(le_vec); - - assert_eq!(num, 282583095116033); - } - - #[test] - fn correct_u64_production_from_small_vec_le_bytes() { - //7 items instead of 8 - let le_vec = vec![1, 1, 1, 1, 2, 1, 1]; - let le_vec_res = [1, 1, 1, 1, 2, 1, 1, 0]; - - let num = PublicSCContext::produce_u64_from_fit_vec(le_vec); - - assert_eq!(num.to_le_bytes(), le_vec_res); - } - - #[test] - #[should_panic] - fn correct_u64_production_from_unfit_vec_should_panic() { - //9 items instead of 8 - let le_vec = vec![1, 1, 1, 1, 2, 1, 1, 1, 1]; - - PublicSCContext::produce_u64_from_fit_vec(le_vec); - } - - #[test] - fn consistent_len_of_context_commitments() { - let test_context = create_test_context(); - - let context_num_vec1 = test_context.produce_u64_list_from_context().unwrap(); - let context_num_vec2 = test_context.produce_u64_list_from_context().unwrap(); - - assert_eq!(context_num_vec1.len(), context_num_vec2.len()); - } -} diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index 49f1285..2ef3595 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -5,7 +5,10 @@ use std::sync::{ use common::ExecutionFailureKind; -use accounts::account_core::{Account, AccountAddress}; +use accounts::{ + account_core::{Account, AccountAddress}, + key_management::ephemeral_key_holder::EphemeralKeyHolder, +}; use anyhow::Result; use chain_storage::NodeChainStore; use common::transaction::{Transaction, TransactionPayload, TxKind}; @@ -197,7 +200,7 @@ impl NodeCore { let account = acc_map_read_guard.acc_map.get(&acc).unwrap(); - let ephm_key_holder = &account.produce_ephemeral_key_holder(); + let ephm_key_holder = EphemeralKeyHolder::new_os_random(); ephm_key_holder.log(); let eph_pub_key = @@ -286,7 +289,7 @@ impl NodeCore { let account = acc_map_read_guard.acc_map.get(&acc).unwrap(); - let ephm_key_holder = &account.produce_ephemeral_key_holder(); + let ephm_key_holder = EphemeralKeyHolder::new_os_random(); ephm_key_holder.log(); let eph_pub_key = @@ -401,7 +404,7 @@ impl NodeCore { .map(|(utxo, _)| utxo.clone()) .collect(); - let ephm_key_holder = &account.produce_ephemeral_key_holder(); + let ephm_key_holder = EphemeralKeyHolder::new_os_random(); ephm_key_holder.log(); let eph_pub_key = @@ -523,7 +526,7 @@ impl NodeCore { .map(|utxo| utxo.hash) .collect(); - let ephm_key_holder = &account.produce_ephemeral_key_holder(); + let ephm_key_holder = EphemeralKeyHolder::new_os_random(); ephm_key_holder.log(); let eph_pub_key = @@ -669,7 +672,7 @@ impl NodeCore { .map(|(utxo, _)| utxo.clone()) .collect(); - let ephm_key_holder = &account.produce_ephemeral_key_holder(); + let ephm_key_holder = EphemeralKeyHolder::new_os_random(); ephm_key_holder.log(); let eph_pub_key = @@ -1387,7 +1390,7 @@ impl NodeCore { .map(|(utxo, _)| utxo.clone()) .collect(); - let ephm_key_holder = &account.produce_ephemeral_key_holder(); + let ephm_key_holder = EphemeralKeyHolder::new_os_random(); ephm_key_holder.log(); let eph_pub_key = diff --git a/sc_core/src/transaction_payloads_tools.rs b/sc_core/src/transaction_payloads_tools.rs index 24ad8f2..cba56dc 100644 --- a/sc_core/src/transaction_payloads_tools.rs +++ b/sc_core/src/transaction_payloads_tools.rs @@ -1,4 +1,4 @@ -use accounts::account_core::Account; +use accounts::{account_core::Account, key_management::ephemeral_key_holder::EphemeralKeyHolder}; use anyhow::Result; use common::transaction::{TransactionPayload, TxKind}; use rand::thread_rng; @@ -40,7 +40,7 @@ pub fn encode_utxos_to_receivers( let mut all_encoded_data = vec![]; for (utxo, receiver) in utxos_receivers { - let ephm_key_holder = &receiver.produce_ephemeral_key_holder(); + let ephm_key_holder = EphemeralKeyHolder::new_os_random(); let encoded_data = Account::encrypt_data( &ephm_key_holder, From eee7cc13979a875ddb8fad1b293d4baf3bb03436 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Wed, 16 Jul 2025 08:10:49 +0300 Subject: [PATCH 20/31] fix: comments fix --- sc_core/src/proofs_circuits.rs | 35 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/sc_core/src/proofs_circuits.rs b/sc_core/src/proofs_circuits.rs index 03eea96..86b5886 100644 --- a/sc_core/src/proofs_circuits.rs +++ b/sc_core/src/proofs_circuits.rs @@ -3,7 +3,6 @@ use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree; use rand::{thread_rng, RngCore}; use secp256k1_zkp::{CommitmentSecrets, Generator, PedersenCommitment, Tag, Tweak, SECP256K1}; use sha2::{Digest, Sha256}; -use std::collections::HashSet; use utxo::utxo_core::UTXO; use crate::{cryptography::poseidon_hash, public_context::PublicSCContext}; @@ -26,7 +25,7 @@ pub fn generate_nullifiers(input_utxo: &UTXO, npk: &[u8]) -> Vec { /// /// uses the input_utxo /// -/// returns commitment here comminment is a hash(bincode(input_utxo)) +/// returns commitment here commitment is a hash(bincode(input_utxo)) pub fn generate_commitment(input_utxo: &UTXO) -> Vec { let serialized = bincode::serialize(input_utxo).unwrap(); // Serialize UTXO. hash(&serialized) @@ -50,7 +49,7 @@ pub fn generate_commitments(input_utxos: &[UTXO]) -> Vec> { /// Validate inclusion proof for in_commitments /// /// ToDo: Solve it in more scalable way -pub fn validate_in_commitments_proof( +pub fn validate_in_commitments_tree( in_commitment: &Vec, commitment_tree: &UTXOCommitmentsMerkleTree, ) -> bool { @@ -59,14 +58,6 @@ pub fn validate_in_commitments_proof( commitment_tree.get_proof(alighned_hash).is_some() } -/// Validate that `nullifier` has not been present in set items before -pub fn validate_nullifier_not_present_in_set_items( - nullifier: [u8; 32], - nullifiers_set: &HashSet<[u8; 32]>, -) -> bool { - !nullifiers_set.contains(&nullifier) -} - /// Check, that input utxos balances is equal to out utxo balances pub fn check_balances_private(in_utxos: &[UTXO], out_utxos: &[UTXO]) -> bool { let in_sum = in_utxos.iter().fold(0, |prev, utxo| prev + utxo.amount); @@ -99,17 +90,16 @@ pub fn private_circuit( } for in_commitment in in_commitments { - assert!(validate_in_commitments_proof( + assert!(validate_in_commitments_tree( &in_commitment, &public_context.commitments_tree, )); } for nullifier in in_nullifiers.iter() { - assert!(validate_nullifier_not_present_in_set_items( - nullifier.clone().try_into().unwrap(), - &public_context.nullifiers_set, - )); + let nullifier: [u8; 32] = nullifier.clone().try_into().unwrap(); + + assert!(!public_context.nullifiers_set.contains(&nullifier)); } (in_nullifiers, generate_commitments(&output_utxos)) @@ -149,17 +139,16 @@ pub fn deshielded_circuit( } for in_commitment in in_commitments { - assert!(validate_in_commitments_proof( + assert!(validate_in_commitments_tree( &in_commitment, &public_context.commitments_tree, )); } for nullifier in in_nullifiers.iter() { - assert!(validate_nullifier_not_present_in_set_items( - nullifier.clone().try_into().unwrap(), - &public_context.nullifiers_set, - )); + let nullifier: [u8; 32] = nullifier.clone().try_into().unwrap(); + + assert!(!public_context.nullifiers_set.contains(&nullifier)); } in_nullifiers @@ -241,7 +230,7 @@ pub fn verify_commitment( /// Validate inclusion proof for pedersen_commitment /// /// ToDo: Solve it in more scalable way -pub fn validate_in_commitments_proof_se( +pub fn validate_in_commitments_tree_se( pedersen_commitment: &PedersenCommitment, commitment_tree: &UTXOCommitmentsMerkleTree, ) -> bool { @@ -291,7 +280,7 @@ pub fn shielded_circuit( let nullifier = generate_nullifiers_se(&pedersen_commitment, &key_ser); - assert!(validate_in_commitments_proof_se( + assert!(validate_in_commitments_tree_se( &pedersen_commitment, &public_context.commitments_tree, )); From 38b57df8831a298e73383e82366f4be230a80e7a Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Wed, 16 Jul 2025 08:18:44 +0300 Subject: [PATCH 21/31] fix: rate limit refetch --- sc_core/src/proofs_circuits.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sc_core/src/proofs_circuits.rs b/sc_core/src/proofs_circuits.rs index 86b5886..b5627f0 100644 --- a/sc_core/src/proofs_circuits.rs +++ b/sc_core/src/proofs_circuits.rs @@ -5,6 +5,8 @@ use secp256k1_zkp::{CommitmentSecrets, Generator, PedersenCommitment, Tag, Tweak use sha2::{Digest, Sha256}; use utxo::utxo_core::UTXO; +// + use crate::{cryptography::poseidon_hash, public_context::PublicSCContext}; fn hash(input: &[u8]) -> Vec { From f0c8e19e64f8546a0d32c6d479d369df7c36f33d Mon Sep 17 00:00:00 2001 From: Sergio Chouhy <41742639+schouhy@users.noreply.github.com> Date: Wed, 16 Jul 2025 10:38:59 -0300 Subject: [PATCH 22/31] Create MIT LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8cb5284 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Vac + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 19de364958ce76f04611059dfaab663b8a8f0b69 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 17 Jul 2025 07:53:03 +0300 Subject: [PATCH 23/31] fix: zkvm version bump --- Cargo.lock | 40 ++++++++++++++++++------------------ common/Cargo.toml | 2 +- node_core/Cargo.toml | 2 +- sc_core/Cargo.toml | 2 +- zkvm/Cargo.toml | 2 +- zkvm/test_methods/Cargo.toml | 2 +- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0200d46..72b6e1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -767,7 +767,7 @@ dependencies = [ [[package]] name = "bonsai-sdk" version = "1.4.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "duplicate", "maybe-async", @@ -3716,7 +3716,7 @@ checksum = "3df6368f71f205ff9c33c076d170dd56ebf68e8161c733c0caa07a7a5509ed53" [[package]] name = "risc0-binfmt" version = "2.0.2" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "borsh", @@ -3733,8 +3733,8 @@ dependencies = [ [[package]] name = "risc0-build" -version = "2.2.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +version = "2.3.0" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "cargo_metadata", @@ -3757,7 +3757,7 @@ dependencies = [ [[package]] name = "risc0-build-kernel" version = "2.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "cc", "directories", @@ -3771,7 +3771,7 @@ dependencies = [ [[package]] name = "risc0-circuit-keccak" version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "bytemuck", @@ -3792,7 +3792,7 @@ dependencies = [ [[package]] name = "risc0-circuit-keccak-sys" version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "cc", "cust", @@ -3807,7 +3807,7 @@ dependencies = [ [[package]] name = "risc0-circuit-recursion" version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "bytemuck", @@ -3832,7 +3832,7 @@ dependencies = [ [[package]] name = "risc0-circuit-recursion-sys" version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "glob", "risc0-build-kernel", @@ -3844,7 +3844,7 @@ dependencies = [ [[package]] name = "risc0-circuit-rv32im" version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "auto_ops", @@ -3875,7 +3875,7 @@ dependencies = [ [[package]] name = "risc0-circuit-rv32im-sys" version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "cc", "cust", @@ -3890,7 +3890,7 @@ dependencies = [ [[package]] name = "risc0-core" version = "2.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "bytemuck", "bytemuck_derive", @@ -3902,7 +3902,7 @@ dependencies = [ [[package]] name = "risc0-groth16" version = "2.0.2" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "ark-bn254", @@ -3926,7 +3926,7 @@ dependencies = [ [[package]] name = "risc0-sys" version = "1.4.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "cust", @@ -3937,7 +3937,7 @@ dependencies = [ [[package]] name = "risc0-zkos-v1compat" version = "2.0.1" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "include_bytes_aligned", "no_std_strings", @@ -3946,7 +3946,7 @@ dependencies = [ [[package]] name = "risc0-zkp" version = "2.0.2" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "blake2", @@ -3976,8 +3976,8 @@ dependencies = [ [[package]] name = "risc0-zkvm" -version = "2.2.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +version = "2.3.0" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "addr2line 0.22.0", "anyhow", @@ -4023,7 +4023,7 @@ dependencies = [ [[package]] name = "risc0-zkvm-platform" version = "2.0.3" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "bytemuck", "cfg-if", @@ -4185,7 +4185,7 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "rzup" version = "0.4.1" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "semver", "serde", diff --git a/common/Cargo.toml b/common/Cargo.toml index b1988ad..bc929e3 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -9,7 +9,7 @@ thiserror.workspace = true serde_json.workspace = true serde.workspace = true reqwest.workspace = true -risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.2" } +risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } rs_merkle.workspace = true sha2.workspace = true diff --git a/node_core/Cargo.toml b/node_core/Cargo.toml index c85e0e0..969e4ec 100644 --- a/node_core/Cargo.toml +++ b/node_core/Cargo.toml @@ -18,7 +18,7 @@ reqwest.workspace = true thiserror.workspace = true tokio.workspace = true tempfile.workspace = true -risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.2" } +risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } hex.workspace = true actix-rt.workspace = true diff --git a/sc_core/Cargo.toml b/sc_core/Cargo.toml index 3d6a213..bc6bade 100644 --- a/sc_core/Cargo.toml +++ b/sc_core/Cargo.toml @@ -19,7 +19,7 @@ light-poseidon.workspace = true ark-bn254.workspace = true ark-ff.workspace = true -risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.2" } +risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } [dependencies.accounts] path = "../accounts" diff --git a/zkvm/Cargo.toml b/zkvm/Cargo.toml index a0701cb..d87d142 100644 --- a/zkvm/Cargo.toml +++ b/zkvm/Cargo.toml @@ -12,7 +12,7 @@ serde.workspace = true thiserror.workspace = true rand.workspace = true -risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.2" } +risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } test-methods = { path = "test_methods" } [dependencies.accounts] diff --git a/zkvm/test_methods/Cargo.toml b/zkvm/test_methods/Cargo.toml index eb771c5..48f27b8 100644 --- a/zkvm/test_methods/Cargo.toml +++ b/zkvm/test_methods/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [build-dependencies] -risc0-build = { git = "https://github.com/risc0/risc0.git", branch = "release-2.2" } +risc0-build = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } [package.metadata.risc0] methods = ["guest"] From 00532b564b23afd4d1134025fece8cbf6bcb0f0e Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 17 Jul 2025 08:09:27 +0300 Subject: [PATCH 24/31] fix: comments fix 1 --- sequencer_core/src/lib.rs | 54 ++++++++----------- .../src/sequencer_store/accounts_store.rs | 17 +++++- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index 308b2f6..5ec58ca 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -263,35 +263,6 @@ mod tests { use secp256k1_zkp::Tweak; use transaction_mempool::TransactionMempool; - fn setup_sequencer_config() -> SequencerConfig { - let mut rng = rand::thread_rng(); - let random_u8: u8 = rng.gen(); - - let path_str = format!("/tmp/sequencer_{:?}", random_u8); - - SequencerConfig { - home: PathBuf::from(path_str), - override_rust_log: Some("info".to_string()), - genesis_id: 1, - is_genesis_random: false, - max_num_tx_in_block: 10, - block_create_timeout_millis: 1000, - port: 8080, - initial_accounts: vec![ - AccountInitialData { - addr: "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117d09a8c" - .to_string(), - balance: 10, - }, - AccountInitialData { - addr: "20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1e376f31" - .to_string(), - balance: 100, - }, - ], - } - } - fn setup_sequencer_config_variable_initial_accounts( initial_accounts: Vec, ) -> SequencerConfig { @@ -312,6 +283,23 @@ mod tests { } } + fn setup_sequencer_config() -> SequencerConfig { + let initial_accounts = vec![ + AccountInitialData { + addr: "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117d09a8c" + .to_string(), + balance: 10, + }, + AccountInitialData { + addr: "20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1e376f31" + .to_string(), + balance: 100, + }, + ]; + + setup_sequencer_config_variable_initial_accounts(initial_accounts) + } + fn create_dummy_transaction( hash: TreeHashType, nullifier_created_hashes: Vec<[u8; 32]>, @@ -401,12 +389,14 @@ mod tests { balance: 1000, }, AccountInitialData { - addr: "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117ffffff" + addr: "20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1effffff" .to_string(), balance: 1000, }, ]; + let intial_accounts_len = initial_accounts.len(); + let config = setup_sequencer_config_variable_initial_accounts(initial_accounts); let sequencer = SequencerCore::start_from_config(config.clone()); @@ -417,7 +407,7 @@ mod tests { .try_into() .unwrap(); let acc2_addr: [u8; 32] = hex::decode( - "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117ffffff".to_string(), + "20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1effffff".to_string(), ) .unwrap() .try_into() @@ -426,6 +416,8 @@ mod tests { assert!(sequencer.store.acc_store.contains_account(&acc1_addr)); assert!(sequencer.store.acc_store.contains_account(&acc2_addr)); + assert_eq!(sequencer.store.acc_store.len(), intial_accounts_len); + assert_eq!( 1000, sequencer diff --git a/sequencer_core/src/sequencer_store/accounts_store.rs b/sequencer_core/src/sequencer_store/accounts_store.rs index 49df8ea..2f49319 100644 --- a/sequencer_core/src/sequencer_store/accounts_store.rs +++ b/sequencer_core/src/sequencer_store/accounts_store.rs @@ -16,7 +16,7 @@ impl AccountPublicData { } } - pub fn new_with_balance(address: AccountAddress, balance: u64) -> Self { + fn new_with_balance(address: AccountAddress, balance: u64) -> Self { Self { balance, address } } } @@ -64,6 +64,11 @@ impl SequencerAccountsStore { pub fn unregister_account(&mut self, account_addr: AccountAddress) { self.accounts.remove(&account_addr); } + + ///Number of accounts present in store + pub fn len(&self) -> usize { + self.accounts.len() + } } impl Default for SequencerAccountsStore { @@ -162,4 +167,14 @@ mod tests { assert_eq!(acc_balance, 10); } + + #[test] + fn account_sequencer_store_fetch_unknown_account() { + let seq_acc_store = + SequencerAccountsStore::new(&[([6; 32], 120), ([7; 32], 15), ([8; 32], 10)]); + + let acc_balance = seq_acc_store.get_account_balance(&[9; 32]); + + assert!(acc_balance.is_none()); + } } From 8b6769d7e8739459672f29795f0bf2079204ac37 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 17 Jul 2025 08:22:04 +0300 Subject: [PATCH 25/31] fix: comments fix 2 --- .../src/sequencer_store/accounts_store.rs | 42 +++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/sequencer_core/src/sequencer_store/accounts_store.rs b/sequencer_core/src/sequencer_store/accounts_store.rs index 2f49319..853247f 100644 --- a/sequencer_core/src/sequencer_store/accounts_store.rs +++ b/sequencer_core/src/sequencer_store/accounts_store.rs @@ -1,4 +1,5 @@ use accounts::account_core::AccountAddress; +use anyhow::Result; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -61,8 +62,23 @@ impl SequencerAccountsStore { } ///Remove account from storage - pub fn unregister_account(&mut self, account_addr: AccountAddress) { - self.accounts.remove(&account_addr); + /// + /// Fails, if `balance` is != 0 + /// + /// Returns `Option` which is `None` if `account_addr` vere not present in store + pub fn unregister_account( + &mut self, + account_addr: AccountAddress, + ) -> Result> { + if let Some(account_balance) = self.get_account_balance(&account_addr) { + if account_balance == 0 { + Ok(self.accounts.remove(&account_addr).map(|data| data.address)) + } else { + anyhow::bail!("Chain consistency violation: It is forbidden to remove account with nonzero balance"); + } + } else { + Ok(None) + } } ///Number of accounts present in store @@ -117,6 +133,26 @@ mod tests { assert_eq!(acc_balance, 0); } + #[test] + fn account_sequencer_store_unregister_acc_not_present() { + let mut seq_acc_store = SequencerAccountsStore::default(); + + seq_acc_store.register_account([1; 32]); + + let rem_res = seq_acc_store.unregister_account([2; 32]).unwrap(); + + assert!(rem_res.is_none()); + } + + #[test] + fn account_sequencer_store_unregister_acc_not_zero_balance() { + let mut seq_acc_store = SequencerAccountsStore::new(&[([1; 32], 12), ([2; 32], 100)]); + + let rem_res = seq_acc_store.unregister_account([1; 32]); + + assert!(rem_res.is_err()); + } + #[test] fn account_sequencer_store_unregister_acc() { let mut seq_acc_store = SequencerAccountsStore::default(); @@ -125,7 +161,7 @@ mod tests { assert!(seq_acc_store.contains_account(&[1; 32])); - seq_acc_store.unregister_account([1; 32]); + seq_acc_store.unregister_account([1; 32]).unwrap().unwrap(); assert!(!seq_acc_store.contains_account(&[1; 32])); } From 0211ff78e1c222761e50417592706810544d2f42 Mon Sep 17 00:00:00 2001 From: Pravdyvy <46261001+Pravdyvy@users.noreply.github.com> Date: Thu, 17 Jul 2025 08:56:11 +0300 Subject: [PATCH 26/31] Update Cargo.toml --- common/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/Cargo.toml b/common/Cargo.toml index b1988ad..bc929e3 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -9,7 +9,7 @@ thiserror.workspace = true serde_json.workspace = true serde.workspace = true reqwest.workspace = true -risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.2" } +risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } rs_merkle.workspace = true sha2.workspace = true From 14da838637893da77900845e8cbea46466da5536 Mon Sep 17 00:00:00 2001 From: Pravdyvy <46261001+Pravdyvy@users.noreply.github.com> Date: Thu, 17 Jul 2025 09:01:26 +0300 Subject: [PATCH 27/31] Update Cargo.toml --- node_core/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node_core/Cargo.toml b/node_core/Cargo.toml index c85e0e0..969e4ec 100644 --- a/node_core/Cargo.toml +++ b/node_core/Cargo.toml @@ -18,7 +18,7 @@ reqwest.workspace = true thiserror.workspace = true tokio.workspace = true tempfile.workspace = true -risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.2" } +risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } hex.workspace = true actix-rt.workspace = true From d1a7b03b554bcd0c45798397dced46b298351a61 Mon Sep 17 00:00:00 2001 From: Pravdyvy <46261001+Pravdyvy@users.noreply.github.com> Date: Thu, 17 Jul 2025 09:02:27 +0300 Subject: [PATCH 28/31] Update Cargo.toml --- sc_core/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sc_core/Cargo.toml b/sc_core/Cargo.toml index 3d6a213..bc6bade 100644 --- a/sc_core/Cargo.toml +++ b/sc_core/Cargo.toml @@ -19,7 +19,7 @@ light-poseidon.workspace = true ark-bn254.workspace = true ark-ff.workspace = true -risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.2" } +risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } [dependencies.accounts] path = "../accounts" From 085d7b4c95b093160c51df15b057625f8a96fb74 Mon Sep 17 00:00:00 2001 From: Pravdyvy <46261001+Pravdyvy@users.noreply.github.com> Date: Thu, 17 Jul 2025 09:04:00 +0300 Subject: [PATCH 29/31] Update Cargo.toml --- zkvm/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zkvm/Cargo.toml b/zkvm/Cargo.toml index a0701cb..d87d142 100644 --- a/zkvm/Cargo.toml +++ b/zkvm/Cargo.toml @@ -12,7 +12,7 @@ serde.workspace = true thiserror.workspace = true rand.workspace = true -risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.2" } +risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } test-methods = { path = "test_methods" } [dependencies.accounts] From 9954f8e0da8afe412ea33576e98ae44b752dff3b Mon Sep 17 00:00:00 2001 From: Pravdyvy <46261001+Pravdyvy@users.noreply.github.com> Date: Thu, 17 Jul 2025 09:04:24 +0300 Subject: [PATCH 30/31] Update Cargo.toml --- zkvm/test_methods/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zkvm/test_methods/Cargo.toml b/zkvm/test_methods/Cargo.toml index eb771c5..48f27b8 100644 --- a/zkvm/test_methods/Cargo.toml +++ b/zkvm/test_methods/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [build-dependencies] -risc0-build = { git = "https://github.com/risc0/risc0.git", branch = "release-2.2" } +risc0-build = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } [package.metadata.risc0] methods = ["guest"] From de8462803d99739ff678e8436350d2df06342d5f Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 17 Jul 2025 11:51:46 +0300 Subject: [PATCH 31/31] fix: api rate limit refetch --- Cargo.lock | 40 ++++++++++++++++++------------------ sequencer_core/src/config.rs | 2 ++ 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c4a396..10ab1e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -767,7 +767,7 @@ dependencies = [ [[package]] name = "bonsai-sdk" version = "1.4.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "duplicate", "maybe-async", @@ -3716,7 +3716,7 @@ checksum = "3df6368f71f205ff9c33c076d170dd56ebf68e8161c733c0caa07a7a5509ed53" [[package]] name = "risc0-binfmt" version = "2.0.2" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "borsh", @@ -3733,8 +3733,8 @@ dependencies = [ [[package]] name = "risc0-build" -version = "2.2.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +version = "2.3.0" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "cargo_metadata", @@ -3757,7 +3757,7 @@ dependencies = [ [[package]] name = "risc0-build-kernel" version = "2.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "cc", "directories", @@ -3771,7 +3771,7 @@ dependencies = [ [[package]] name = "risc0-circuit-keccak" version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "bytemuck", @@ -3792,7 +3792,7 @@ dependencies = [ [[package]] name = "risc0-circuit-keccak-sys" version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "cc", "cust", @@ -3807,7 +3807,7 @@ dependencies = [ [[package]] name = "risc0-circuit-recursion" version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "bytemuck", @@ -3832,7 +3832,7 @@ dependencies = [ [[package]] name = "risc0-circuit-recursion-sys" version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "glob", "risc0-build-kernel", @@ -3844,7 +3844,7 @@ dependencies = [ [[package]] name = "risc0-circuit-rv32im" version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "auto_ops", @@ -3875,7 +3875,7 @@ dependencies = [ [[package]] name = "risc0-circuit-rv32im-sys" version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "cc", "cust", @@ -3890,7 +3890,7 @@ dependencies = [ [[package]] name = "risc0-core" version = "2.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "bytemuck", "bytemuck_derive", @@ -3902,7 +3902,7 @@ dependencies = [ [[package]] name = "risc0-groth16" version = "2.0.2" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "ark-bn254", @@ -3926,7 +3926,7 @@ dependencies = [ [[package]] name = "risc0-sys" version = "1.4.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "cust", @@ -3937,7 +3937,7 @@ dependencies = [ [[package]] name = "risc0-zkos-v1compat" version = "2.0.1" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "include_bytes_aligned", "no_std_strings", @@ -3946,7 +3946,7 @@ dependencies = [ [[package]] name = "risc0-zkp" version = "2.0.2" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "anyhow", "blake2", @@ -3976,8 +3976,8 @@ dependencies = [ [[package]] name = "risc0-zkvm" -version = "2.2.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +version = "2.3.0" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "addr2line 0.22.0", "anyhow", @@ -4023,7 +4023,7 @@ dependencies = [ [[package]] name = "risc0-zkvm-platform" version = "2.0.3" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "bytemuck", "cfg-if", @@ -4185,7 +4185,7 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "rzup" version = "0.4.1" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.2#eff3c74bf9992401c2c68bea95eb6c93b27999ec" +source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#c6297fc2075cb66aadb733ee677223b5a7f8c85a" dependencies = [ "semver", "serde", diff --git a/sequencer_core/src/config.rs b/sequencer_core/src/config.rs index 374a940..95ed7bc 100644 --- a/sequencer_core/src/config.rs +++ b/sequencer_core/src/config.rs @@ -1,6 +1,8 @@ use serde::{Deserialize, Serialize}; use std::path::PathBuf; +// + #[derive(Debug, Serialize, Deserialize, Clone)] ///Helperstruct for account serialization pub struct AccountInitialData {