From 8fc244b2713e3c71fc15d71816eaa04ea1992780 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:28:56 -0400 Subject: [PATCH 01/31] add pedersen commitments to `Transaction` and `TransactionPayload` struct --- storage/src/transaction.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/storage/src/transaction.rs b/storage/src/transaction.rs index 2a7f23c6..32cb1f06 100644 --- a/storage/src/transaction.rs +++ b/storage/src/transaction.rs @@ -1,6 +1,7 @@ use log::info; use serde::{Deserialize, Serialize}; use sha2::{digest::FixedOutput, Digest}; +use secp256k1_zkp::{rand, PedersenCommitment, Tweak}; use crate::merkle_tree_public::TreeHashType; @@ -43,6 +44,12 @@ pub struct Transaction { pub encoded_data: Vec<(CipherText, Vec, Tag)>, ///Transaction senders ephemeral pub key pub ephemeral_pub_key: Vec, + ///Public (Pedersen) commitment + pub commitment: Vec, + ///tweak + pub tweak: Tweak, + ///secret_r + pub secret_r: [u8; 32], } #[derive(Debug, Serialize, Deserialize, Clone)] @@ -65,6 +72,12 @@ pub struct TransactionPayload { pub encoded_data: Vec<(CipherText, Vec, Tag)>, ///Transaction senders ephemeral pub key pub ephemeral_pub_key: Vec, + ///Public (Pedersen) commitment + pub commitment: Vec, + ///tweak + pub tweak: Tweak, + ///secret_r + pub secret_r: [u8; 32], } impl From for Transaction { @@ -77,6 +90,8 @@ impl From for Transaction { let hash = ::from(hasher.finalize_fixed()); + let mut rng = rand::thread_rng(); + Self { hash, tx_kind: value.tx_kind, @@ -88,6 +103,9 @@ impl From for Transaction { execution_proof_private: value.execution_proof_private, encoded_data: value.encoded_data, ephemeral_pub_key: value.ephemeral_pub_key, + commitment: value.commitment, + tweak: Tweak::new(&mut rng), + secret_r: [0; 32], } } } From 250dec1ae637c894d3519a34bb83d641c1bcfbf7 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:29:19 -0400 Subject: [PATCH 02/31] fix transaction payload --- sc_core/src/transaction_payloads_tools.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sc_core/src/transaction_payloads_tools.rs b/sc_core/src/transaction_payloads_tools.rs index f1a99e0f..2541bc6e 100644 --- a/sc_core/src/transaction_payloads_tools.rs +++ b/sc_core/src/transaction_payloads_tools.rs @@ -2,13 +2,18 @@ use accounts::account_core::Account; use anyhow::Result; use rand::thread_rng; use risc0_zkvm::Receipt; -use secp256k1_zkp::{CommitmentSecrets, PedersenCommitment, Tweak}; +use secp256k1_zkp::{CommitmentSecrets, Generator, PedersenCommitment, Tag, Tweak, SECP256K1}; use storage::transaction::{TransactionPayload, TxKind}; use utxo::utxo_core::UTXO; use crate::proofs_circuits::{commit, generate_nullifiers, tag_random}; pub fn create_public_transaction_payload(execution_input: Vec) -> TransactionPayload { + let tag = tag_random(); + let unblinded_gen = Generator::new_unblinded(SECP256K1, tag); + + let mut rng = rand::thread_rng(); + TransactionPayload { tx_kind: TxKind::Public, execution_input, @@ -19,6 +24,9 @@ pub fn create_public_transaction_payload(execution_input: Vec) -> Transactio execution_proof_private: "".to_string(), encoded_data: vec![], ephemeral_pub_key: vec![], + commitment: vec![PedersenCommitment::new_unblinded(SECP256K1, 0, unblinded_gen)], + tweak: Tweak::new(&mut rng), + secret_r: [0; 32], } } From 0113925b92d23a143eb0d8b08121e8546d4a25b5 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:29:35 -0400 Subject: [PATCH 03/31] fix rtansaction for tests --- sequencer_core/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index e07f49e0..265bcfe1 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -300,6 +300,9 @@ mod tests { execution_proof_private: "dummy_proof".to_string(), encoded_data: vec![], ephemeral_pub_key: vec![10, 11, 12], + commitment: vec![], + tweak: Tweak::new(&mut rng), + secret_r: [0; 32], } } From bbb84cd849792f0dff02608597385f6c9bdbb554 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:30:10 -0400 Subject: [PATCH 04/31] add new type of error, since we have a new interaction --- common/src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/common/src/lib.rs b/common/src/lib.rs index 2049ae65..16ff6388 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -40,6 +40,8 @@ impl From for SequencerClientError { pub enum ExecutionFailureKind { #[error("Failed to write into builder err: {0:?}")] WriteError(anyhow::Error), + #[error("Failed to interact with a db err: {0:?}")] + DBError(anyhow::Error), #[error("Failed to build builder err: {0:?}")] BuilderError(anyhow::Error), #[error("Failed prove execution err: {0:?}")] @@ -70,4 +72,8 @@ impl ExecutionFailureKind { pub fn prove_error(err: anyhow::Error) -> Self { Self::ProveError(err) } + + pub fn db_error(err: anyhow::Error) -> Self { + Self::DBError(err) + } } From 97aeb4810944617429b7bdeb1433a2da74e2213a Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:30:26 -0400 Subject: [PATCH 05/31] rpc error pushthrough --- node_rpc/src/types/err_rpc.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/node_rpc/src/types/err_rpc.rs b/node_rpc/src/types/err_rpc.rs index df80de93..22e9d299 100644 --- a/node_rpc/src/types/err_rpc.rs +++ b/node_rpc/src/types/err_rpc.rs @@ -66,6 +66,7 @@ pub fn cast_common_execution_error_into_rpc_error(comm_exec_err: ExecutionFailur match comm_exec_err { ExecutionFailureKind::BuilderError(_) => RpcError::new_internal_error(None, &error_string), ExecutionFailureKind::WriteError(_) => RpcError::new_internal_error(None, &error_string), + ExecutionFailureKind::DBError(_) => RpcError::new_internal_error(None, &error_string), ExecutionFailureKind::DecodeError(_) => RpcError::new_internal_error(None, &error_string), ExecutionFailureKind::ProveError(_) => RpcError::new_internal_error(None, &error_string), ExecutionFailureKind::AmountMismatchError => { From 31655f2c35ce79475cb80d34bb97d8479f2db8ee Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:31:05 -0400 Subject: [PATCH 06/31] function to create pedersen commitments --- node_core/src/executions/de.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/node_core/src/executions/de.rs b/node_core/src/executions/de.rs index c2ddd592..fc345005 100644 --- a/node_core/src/executions/de.rs +++ b/node_core/src/executions/de.rs @@ -154,6 +154,26 @@ pub fn verify_commitment( commitment == *pedersen_commitment } +// new_commitment +pub fn new_commitment( + public_info: u64, + secret_r: &[u8], +) -> (Tweak, &[u8], PedersenCommitment) { + let generator_blinding_factor = Tweak::new(&mut thread_rng()); + let commitment_secrets = CommitmentSecrets { + value: public_info, + value_blinding_factor: Tweak::from_slice(secret_r).unwrap(), + generator_blinding_factor, + }; + + let tag = tag_random(); + let commitment = commit(&commitment_secrets, tag); + + (generator_blinding_factor, secret_r, commitment) +} + + + #[allow(unused)] fn de_kernel( root_commitment: &[u8], From aa93d26b808f93c6f8b37d6279c276f0d60f0de2 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:31:20 -0400 Subject: [PATCH 07/31] function to create pedersen commitments for multiple values --- node_core/src/executions/de.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/node_core/src/executions/de.rs b/node_core/src/executions/de.rs index fc345005..8e8ba60b 100644 --- a/node_core/src/executions/de.rs +++ b/node_core/src/executions/de.rs @@ -172,7 +172,26 @@ pub fn new_commitment( (generator_blinding_factor, secret_r, commitment) } +// new_commitment for a Vec of values +pub fn new_commitment_vec( + public_info_vec: Vec, + secret_r: &[u8], +) -> (Tweak, &[u8], Vec) { + let generator_blinding_factor = Tweak::new(&mut thread_rng()); + let tag = tag_random(); + let vec_commitments = public_info_vec.into_iter().map(|public_info| { + let commitment_secrets = CommitmentSecrets { + value: public_info, + value_blinding_factor: Tweak::from_slice(secret_r).unwrap(), + generator_blinding_factor, + }; + + commit(&commitment_secrets, tag) + }).collect(); + + (generator_blinding_factor, secret_r, vec_commitments) +} #[allow(unused)] fn de_kernel( From ded84933b2b170a6deff3c6b3daf6d06cca3703b Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:31:39 -0400 Subject: [PATCH 08/31] get_sc_sc_state for `NodeBlockStore` --- node_core/src/storage/block_store.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/node_core/src/storage/block_store.rs b/node_core/src/storage/block_store.rs index 6991ee5a..828d8acd 100644 --- a/node_core/src/storage/block_store.rs +++ b/node_core/src/storage/block_store.rs @@ -2,6 +2,7 @@ use std::path::Path; use anyhow::{anyhow, Result}; use storage::{block::Block, RocksDBIO}; +use storage::sc_db_utils::DataBlob; pub struct NodeBlockStore { dbio: RocksDBIO, @@ -41,6 +42,10 @@ impl NodeBlockStore { pub fn put_block_at_id(&self, block: Block) -> Result<()> { Ok(self.dbio.put_block(block, false)?) } + + pub fn get_sc_sc_state(&self, sc_addr: &str) -> Result> { + Ok(self.dbio.get_sc_sc_state(sc_addr)?) + } } #[cfg(test)] From d6b6d92122d674a5855275b9a981f420c9514231 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:31:52 -0400 Subject: [PATCH 09/31] add dependency to storage --- storage/Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/storage/Cargo.toml b/storage/Cargo.toml index 0da0fc36..6e27eda0 100644 --- a/storage/Cargo.toml +++ b/storage/Cargo.toml @@ -18,3 +18,7 @@ rocksdb.workspace = true rs_merkle.workspace = true sha2.workspace = true monotree.workspace = true + +[dependencies.secp256k1-zkp] +workspace = true +features = ["std", "rand-std", "rand", "serde", "global-context"] \ No newline at end of file From 6447545ec4ea3c0dd6f00041e8ad64c375bd2944 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:32:16 -0400 Subject: [PATCH 10/31] serialiaze `PublicSCContext` --- node_core/src/storage/public_context.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/node_core/src/storage/public_context.rs b/node_core/src/storage/public_context.rs index db0503fb..f4c406cc 100644 --- a/node_core/src/storage/public_context.rs +++ b/node_core/src/storage/public_context.rs @@ -1,9 +1,11 @@ use std::collections::BTreeMap; use accounts::account_core::{AccountAddress, AccountPublicMask}; +use serde::{Serialize}; use storage::merkle_tree_public::TreeHashType; ///Strucutre, representing context, given to a smart contract on a call +#[derive(Serialize)] pub struct PublicSCContext { pub caller_address: AccountAddress, pub caller_balance: u64, From 593235a09f1400bd308877e883106e86ff5c3c0a Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:32:34 -0400 Subject: [PATCH 11/31] add dependency to sequencer_core --- sequencer_core/Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sequencer_core/Cargo.toml b/sequencer_core/Cargo.toml index 634337e0..992992a6 100644 --- a/sequencer_core/Cargo.toml +++ b/sequencer_core/Cargo.toml @@ -21,3 +21,7 @@ path = "../mempool" [dependencies.accounts] path = "../accounts" + +[dependencies.secp256k1-zkp] +workspace = true +features = ["std", "rand-std", "rand", "serde", "global-context"] \ No newline at end of file From 94493d1051e8d3928b0aae0570e3a8f2c938ac94 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:32:57 -0400 Subject: [PATCH 12/31] fix core primitives --- core_primitives/src/transaction.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core_primitives/src/transaction.rs b/core_primitives/src/transaction.rs index be0fb8ea..2ffd65ac 100644 --- a/core_primitives/src/transaction.rs +++ b/core_primitives/src/transaction.rs @@ -7,6 +7,7 @@ use elliptic_curve::{ generic_array::GenericArray, }; use sha2::digest::typenum::{UInt, UTerm}; +use secp256k1_zkp::PedersenCommitment; pub type CipherText = Vec; pub type Nonce = GenericArray, B1>, B0>, B0>>; @@ -40,6 +41,8 @@ pub struct Transaction { pub encoded_data: Vec<(CipherText, Vec)>, ///Transaction senders ephemeral pub key pub ephemeral_pub_key: Vec, + ///Public (Pedersen) commitment + pub commitment: PedersenCommitment, } #[derive(Debug, Serialize, Deserialize, Clone)] @@ -62,4 +65,6 @@ pub struct TransactionPayload { pub encoded_data: Vec<(CipherText, Vec)>, ///Transaction senders ephemeral pub key pub ephemeral_pub_key: Vec, + ///Public (Pedersen) commitment + pub commitment: PedersenCommitment, } From 8b811ae65fa951f9244fc23141105abc8b17b904 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:33:09 -0400 Subject: [PATCH 13/31] add dependency to core_primitives --- core_primitives/Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core_primitives/Cargo.toml b/core_primitives/Cargo.toml index c3a6f728..39885b27 100644 --- a/core_primitives/Cargo.toml +++ b/core_primitives/Cargo.toml @@ -13,6 +13,10 @@ sha2.workspace = true elliptic-curve.workspace = true monotree.workspace = true +[dependencies.secp256k1-zkp] +workspace = true +features = ["std", "rand-std", "rand", "serde", "global-context"] + [dependencies.storage] path = "../storage" From def10dea1840265ee5103b96d6afef1d3ce5ef3e Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:33:20 -0400 Subject: [PATCH 14/31] serialiaze `AccountPublicMask` --- accounts/src/account_core/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/accounts/src/account_core/mod.rs b/accounts/src/account_core/mod.rs index 647ca24c..3f6ac0dd 100644 --- a/accounts/src/account_core/mod.rs +++ b/accounts/src/account_core/mod.rs @@ -29,6 +29,7 @@ pub struct Account { ///A strucure, which represents all the visible(public) information /// /// known to each node about account `address` +#[derive(Serialize)] pub struct AccountPublicMask { pub nullifier_public_key: AffinePoint, pub viewing_public_key: AffinePoint, From 3d56c52291d13c4a9928821088445e5e4b20c8ab Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:33:27 -0400 Subject: [PATCH 15/31] lock file --- Cargo.lock | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index babf1b82..d4522c0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1154,6 +1154,7 @@ dependencies = [ "env_logger", "log", "monotree", + "secp256k1-zkp", "sequencer_core", "serde", "serde_json", @@ -4685,6 +4686,7 @@ dependencies = [ "log", "mempool", "rand 0.8.5", + "secp256k1-zkp", "serde", "serde_json", "storage", @@ -4975,6 +4977,7 @@ dependencies = [ "monotree", "rocksdb", "rs_merkle", + "secp256k1-zkp", "serde", "serde_json", "sha2 0.10.8", From 10e779c1e92ba34746f643bc1e8b5d8527a06faf Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:34:03 -0400 Subject: [PATCH 16/31] mint_utxo_private commitments --- node_core/src/lib.rs | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index 33bc2283..fef36a36 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -175,9 +175,9 @@ impl NodeCore { let acc_map_read_guard = self.storage.read().await; - let accout = acc_map_read_guard.acc_map.get(&acc).unwrap(); + let account = acc_map_read_guard.acc_map.get(&acc).unwrap(); - let ephm_key_holder = &accout.produce_ephemeral_key_holder(); + let ephm_key_holder = &account.produce_ephemeral_key_holder(); ephm_key_holder.log(); let eph_pub_key = @@ -185,14 +185,35 @@ impl NodeCore { let encoded_data = Account::encrypt_data( &ephm_key_holder, - accout.key_holder.viewing_public_key, + account.key_holder.viewing_public_key, &serde_json::to_vec(&utxo).unwrap(), ); - let tag = accout.make_tag(); + let tag = account.make_tag(); let comm = generate_commitments(&vec![utxo]); + // TODO: fix address when correspoding method will be added + let sc_addr = ""; + let mut rng = rand::thread_rng(); + let secret_r: [u8; 32] = rng.gen(); + + let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; + + let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| Self::vec_u8_to_vec_u64(slice.to_vec())).collect(); + + let context = acc_map_read_guard.produce_context(account.address); + + let serialized_context = serde_json::to_vec(&context).unwrap(); + + let serialized_context_u64 = Self::vec_u8_to_vec_u64(serialized_context); + + vec_values_u64.push(serialized_context_u64); + + let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); + + let (tweak, secret_r, commitment) = new_commitment_vec(vec_public_info, &secret_r); + Ok(( TransactionPayload { tx_kind: TxKind::Private, @@ -210,6 +231,9 @@ impl NodeCore { .unwrap(), encoded_data: vec![(encoded_data.0, encoded_data.1.to_vec(), tag)], ephemeral_pub_key: eph_pub_key.to_vec(), + commitment, + tweak, + secret_r: secret_r.try_into().unwrap(), } .into(), result_hash, From 7a57b4f51ca27bb85ce08ad6abc711fa30a23b38 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:34:21 -0400 Subject: [PATCH 17/31] vec_u8_to_vec_u64 helper --- node_core/src/lib.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index fef36a36..009949c8 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -240,6 +240,24 @@ impl NodeCore { )) } + fn vec_u8_to_vec_u64(bytes: Vec) -> Vec { + // Pad with zeros to make sure it's a multiple of 8 + let mut padded = bytes.clone(); + while padded.len() % 8 != 0 { + padded.push(0); + } + + padded + .chunks(8) + .map(|chunk| { + let mut array = [0u8; 8]; + array.copy_from_slice(chunk); + u64::from_le_bytes(array) + }) + .collect() + } + + pub async fn mint_utxo_multiple_assets_private( &self, acc: AccountAddress, From e7249002e5010adfd3eaf4782a84f4e3c6c9a0e9 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:34:57 -0400 Subject: [PATCH 18/31] mint_utxo_multiple_assets_private add commitments --- node_core/src/lib.rs | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index 009949c8..e7a17f13 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -269,9 +269,9 @@ impl NodeCore { let acc_map_read_guard = self.storage.read().await; - let accout = acc_map_read_guard.acc_map.get(&acc).unwrap(); + let account = acc_map_read_guard.acc_map.get(&acc).unwrap(); - let ephm_key_holder = &accout.produce_ephemeral_key_holder(); + let ephm_key_holder = &account.produce_ephemeral_key_holder(); ephm_key_holder.log(); let eph_pub_key = @@ -283,10 +283,10 @@ impl NodeCore { ( Account::encrypt_data( &ephm_key_holder, - accout.key_holder.viewing_public_key, + account.key_holder.viewing_public_key, &serde_json::to_vec(&utxo).unwrap(), ), - accout.make_tag(), + account.make_tag(), ) }) .map(|((ciphertext, nonce), tag)| (ciphertext, nonce.to_vec(), tag)) @@ -294,6 +294,27 @@ impl NodeCore { let comm = generate_commitments(&utxos); + // TODO: fix address when correspoding method will be added + let sc_addr = ""; + let mut rng = rand::thread_rng(); + let secret_r: [u8; 32] = rng.gen(); + + let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; + + let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| Self::vec_u8_to_vec_u64(slice.to_vec())).collect(); + + let context = acc_map_read_guard.produce_context(account.address); + + let serialized_context = serde_json::to_vec(&context).unwrap(); + + let serialized_context_u64 = Self::vec_u8_to_vec_u64(serialized_context); + + vec_values_u64.push(serialized_context_u64); + + let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); + + let (tweak, secret_r, commitment) = new_commitment_vec(vec_public_info, &secret_r); + Ok(( TransactionPayload { tx_kind: TxKind::Private, @@ -311,6 +332,9 @@ impl NodeCore { .unwrap(), encoded_data, ephemeral_pub_key: eph_pub_key.to_vec(), + commitment, + tweak, + secret_r: secret_r.try_into().unwrap(), } .into(), result_hashes, From 8a4606f5d32f0c7ea9e0f23947f11fd027454992 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:35:19 -0400 Subject: [PATCH 19/31] transfer_utxo_private add commitments --- node_core/src/lib.rs | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index e7a17f13..e3d719fb 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -349,11 +349,11 @@ impl NodeCore { ) -> Result<(Transaction, Vec<(AccountAddress, [u8; 32])>), ExecutionFailureKind> { let acc_map_read_guard = self.storage.read().await; - let accout = acc_map_read_guard.acc_map.get(&utxo.owner).unwrap(); + let account = acc_map_read_guard.acc_map.get(&utxo.owner).unwrap(); let nullifier = generate_nullifiers( &utxo, - &accout + &account .key_holder .utxo_secret_key_holder .nullifier_secret_key @@ -372,7 +372,7 @@ impl NodeCore { .map(|(utxo, _)| utxo.clone()) .collect(); - let ephm_key_holder = &accout.produce_ephemeral_key_holder(); + let ephm_key_holder = &account.produce_ephemeral_key_holder(); ephm_key_holder.log(); let eph_pub_key = @@ -396,6 +396,27 @@ impl NodeCore { .collect(); let commitments = generate_commitments(&utxos); + + // TODO: fix address when correspoding method will be added + let sc_addr = ""; + let mut rng = rand::thread_rng(); + let secret_r: [u8; 32] = rng.gen(); + + let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; + + let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| Self::vec_u8_to_vec_u64(slice.to_vec())).collect(); + + let context = acc_map_read_guard.produce_context(account.address); + + let serialized_context = serde_json::to_vec(&context).unwrap(); + + let serialized_context_u64 = Self::vec_u8_to_vec_u64(serialized_context); + + vec_values_u64.push(serialized_context_u64); + + let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); + + let (tweak, secret_r, commitment) = new_commitment_vec(vec_public_info, &secret_r); Ok(( TransactionPayload { @@ -414,6 +435,9 @@ impl NodeCore { .unwrap(), encoded_data, ephemeral_pub_key: eph_pub_key.to_vec(), + commitment, + tweak, + secret_r: secret_r.try_into().unwrap(), } .into(), utxo_hashes, From e9a2cf361d004b2332a4db34e4e308df7626f1ea Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:35:44 -0400 Subject: [PATCH 20/31] transfer_utxo_multiple_assets_private add commitments --- node_core/src/lib.rs | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index e3d719fb..7d333944 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -453,9 +453,9 @@ impl NodeCore { ) -> Result<(Transaction, Vec<[u8; 32]>, Vec<[u8; 32]>), ExecutionFailureKind> { let acc_map_read_guard = self.storage.read().await; - let accout = acc_map_read_guard.acc_map.get(&utxos[0].owner).unwrap(); + let account = acc_map_read_guard.acc_map.get(&utxos[0].owner).unwrap(); - let nsk = accout + let nsk = account .key_holder .utxo_secret_key_holder .nullifier_secret_key @@ -481,7 +481,7 @@ impl NodeCore { .map(|utxo| utxo.hash) .collect(); - let ephm_key_holder = &accout.produce_ephemeral_key_holder(); + let ephm_key_holder = &account.produce_ephemeral_key_holder(); ephm_key_holder.log(); let eph_pub_key = @@ -528,6 +528,27 @@ impl NodeCore { commitments.extend(commitments_1); + // TODO: fix address when correspoding method will be added + let sc_addr = ""; + let mut rng = rand::thread_rng(); + let secret_r: [u8; 32] = rng.gen(); + + let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; + + let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| Self::vec_u8_to_vec_u64(slice.to_vec())).collect(); + + let context = acc_map_read_guard.produce_context(account.address); + + let serialized_context = serde_json::to_vec(&context).unwrap(); + + let serialized_context_u64 = Self::vec_u8_to_vec_u64(serialized_context); + + vec_values_u64.push(serialized_context_u64); + + let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); + + let (tweak, secret_r, commitment) = new_commitment_vec(vec_public_info, &secret_r); + Ok(( TransactionPayload { tx_kind: TxKind::Private, @@ -545,6 +566,9 @@ impl NodeCore { .unwrap(), encoded_data, ephemeral_pub_key: eph_pub_key.to_vec(), + commitment, + tweak, + secret_r: secret_r.try_into().unwrap(), } .into(), utxo_hashes_receiver, From 9f5276a49737f40782b7e4a2c7b0810ddfd82bb9 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:36:07 -0400 Subject: [PATCH 21/31] transfer_balance_shielded add commitments --- node_core/src/lib.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index 7d333944..b02e5183 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -586,6 +586,7 @@ impl NodeCore { let account = acc_map_read_guard.acc_map.get(&acc).unwrap(); + // TODO: add to transaction structure and do the check. Research has to update the scheme as well. let commitment = sc_core::transaction_payloads_tools::generate_secret_random_commitment( balance, account, ) @@ -637,6 +638,24 @@ impl NodeCore { let commitments = generate_commitments(&utxos); + // TODO: fix address when correspoding method will be added + let sc_addr = ""; + + let mut rng = rand::thread_rng(); + let secret_r: [u8; 32] = rng.gen(); + + let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; + + let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| Self::vec_u8_to_vec_u64(slice.to_vec())).collect(); + + let serialized_context_u64 = Self::vec_u8_to_vec_u64(serde_json::to_vec(&acc_map_read_guard.produce_context(account.address)).unwrap()); + + vec_values_u64.push(serialized_context_u64); + + let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); + + let (tweak, secret_r, commitment) = new_commitment_vec(vec_public_info, &secret_r); + Ok(( TransactionPayload { tx_kind: TxKind::Shielded, @@ -660,6 +679,9 @@ impl NodeCore { .unwrap(), encoded_data, ephemeral_pub_key: eph_pub_key.to_vec(), + commitment, + tweak, + secret_r: secret_r.try_into().unwrap(), } .into(), utxo_hashes, From cce349ff15a32991fc2b733327765cfc72aba234 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:36:23 -0400 Subject: [PATCH 22/31] transfer_utxo_deshielded add commitments --- node_core/src/lib.rs | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index b02e5183..06737a9c 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -702,11 +702,11 @@ impl NodeCore { .unwrap() .hash; - let accout = acc_map_read_guard.acc_map.get(&utxo.owner).unwrap(); + let account = acc_map_read_guard.acc_map.get(&utxo.owner).unwrap(); let nullifier = generate_nullifiers( &utxo, - &accout + &account .key_holder .utxo_secret_key_holder .nullifier_secret_key @@ -716,6 +716,27 @@ impl NodeCore { let (resulting_balances, receipt) = prove_send_utxo_deshielded(utxo, receivers)?; + // TODO: fix address when correspoding method will be added + let sc_addr = ""; + let mut rng = rand::thread_rng(); + let secret_r: [u8; 32] = rng.gen(); + + let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; + + let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| Self::vec_u8_to_vec_u64(slice.to_vec())).collect(); + + let context = acc_map_read_guard.produce_context(account.address); + + let serialized_context = serde_json::to_vec(&context).unwrap(); + + let serialized_context_u64 = Self::vec_u8_to_vec_u64(serialized_context); + + vec_values_u64.push(serialized_context_u64); + + let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); + + let (tweak, secret_r, commitment) = new_commitment_vec(vec_public_info, &secret_r); + Ok(TransactionPayload { tx_kind: TxKind::Deshielded, execution_input: serde_json::to_vec(&ActionData::SendMoneyDeshieldedTx( @@ -732,6 +753,9 @@ impl NodeCore { .unwrap(), encoded_data: vec![], ephemeral_pub_key: vec![], + commitment, + tweak, + secret_r: secret_r.try_into().unwrap(), } .into()) } From 0b37cb66342417416fb51c890d88361732470008 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:36:44 -0400 Subject: [PATCH 23/31] split_utxo add commitments --- node_core/src/lib.rs | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index 06737a9c..cdad2cfa 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -1262,11 +1262,11 @@ impl NodeCore { ) -> Result<(Transaction, Vec<(AccountAddress, [u8; 32])>), ExecutionFailureKind> { let acc_map_read_guard = self.storage.read().await; - let accout = acc_map_read_guard.acc_map.get(&utxo.owner).unwrap(); + let account = acc_map_read_guard.acc_map.get(&utxo.owner).unwrap(); let nullifier = generate_nullifiers( &utxo, - &accout + &account .key_holder .utxo_secret_key_holder .nullifier_secret_key @@ -1285,7 +1285,7 @@ impl NodeCore { .map(|(utxo, _)| utxo.clone()) .collect(); - let ephm_key_holder = &accout.produce_ephemeral_key_holder(); + let ephm_key_holder = &account.produce_ephemeral_key_holder(); ephm_key_holder.log(); let eph_pub_key = @@ -1324,6 +1324,27 @@ impl NodeCore { .collect(), }); + // TODO: fix address when correspoding method will be added + let sc_addr = ""; + let mut rng = rand::thread_rng(); + let secret_r: [u8; 32] = rng.gen(); + + let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; + + let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| Self::vec_u8_to_vec_u64(slice.to_vec())).collect(); + + let context = acc_map_read_guard.produce_context(account.address); + + let serialized_context = serde_json::to_vec(&context).unwrap(); + + let serialized_context_u64 = Self::vec_u8_to_vec_u64(serialized_context); + + vec_values_u64.push(serialized_context_u64); + + let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); + + let (tweak, secret_r, commitment) = new_commitment_vec(vec_public_info, &secret_r); + Ok(( TransactionPayload { tx_kind: TxKind::Shielded, @@ -1342,6 +1363,9 @@ impl NodeCore { .unwrap(), encoded_data, ephemeral_pub_key: eph_pub_key.to_vec(), + commitment, + tweak, + secret_r: secret_r.try_into().unwrap(), } .into(), utxo_hashes, From 2779e2e18ca5445f076b2971d7ff295c134b2e45 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:38:02 -0400 Subject: [PATCH 24/31] style --- node_core/src/lib.rs | 67 +++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index cdad2cfa..d5833924 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -5,11 +5,12 @@ use std::sync::{ use common::ExecutionFailureKind; +use rand::Rng; use ::storage::transaction::{Transaction, TransactionPayload, TxKind}; use accounts::account_core::{Account, AccountAddress}; use anyhow::Result; use config::NodeConfig; -use executions::private_exec::{generate_commitments, generate_nullifiers}; +use executions::{de::new_commitment_vec, private_exec::{generate_commitments, generate_nullifiers}}; use log::info; use sequencer_client::{json::SendTxResponse, SequencerClient}; use serde::{Deserialize, Serialize}; @@ -29,6 +30,23 @@ pub mod executions; pub mod sequencer_client; pub mod storage; +fn vec_u8_to_vec_u64(bytes: Vec) -> Vec { + // Pad with zeros to make sure it's a multiple of 8 + let mut padded = bytes.clone(); + while padded.len() % 8 != 0 { + padded.push(0); + } + + padded + .chunks(8) + .map(|chunk| { + let mut array = [0u8; 8]; + array.copy_from_slice(chunk); + u64::from_le_bytes(array) + }) + .collect() +} + #[derive(Debug, Serialize, Deserialize)] pub struct MintMoneyPublicTx { pub acc: AccountAddress, @@ -200,13 +218,13 @@ impl NodeCore { let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; - let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| Self::vec_u8_to_vec_u64(slice.to_vec())).collect(); + let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| vec_u8_to_vec_u64(slice.to_vec())).collect(); let context = acc_map_read_guard.produce_context(account.address); let serialized_context = serde_json::to_vec(&context).unwrap(); - let serialized_context_u64 = Self::vec_u8_to_vec_u64(serialized_context); + let serialized_context_u64 = vec_u8_to_vec_u64(serialized_context); vec_values_u64.push(serialized_context_u64); @@ -240,24 +258,9 @@ impl NodeCore { )) } - fn vec_u8_to_vec_u64(bytes: Vec) -> Vec { - // Pad with zeros to make sure it's a multiple of 8 - let mut padded = bytes.clone(); - while padded.len() % 8 != 0 { - padded.push(0); - } + + - padded - .chunks(8) - .map(|chunk| { - let mut array = [0u8; 8]; - array.copy_from_slice(chunk); - u64::from_le_bytes(array) - }) - .collect() - } - - pub async fn mint_utxo_multiple_assets_private( &self, acc: AccountAddress, @@ -301,13 +304,13 @@ impl NodeCore { let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; - let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| Self::vec_u8_to_vec_u64(slice.to_vec())).collect(); + let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| vec_u8_to_vec_u64(slice.to_vec())).collect(); let context = acc_map_read_guard.produce_context(account.address); let serialized_context = serde_json::to_vec(&context).unwrap(); - let serialized_context_u64 = Self::vec_u8_to_vec_u64(serialized_context); + let serialized_context_u64 = vec_u8_to_vec_u64(serialized_context); vec_values_u64.push(serialized_context_u64); @@ -404,13 +407,13 @@ impl NodeCore { let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; - let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| Self::vec_u8_to_vec_u64(slice.to_vec())).collect(); + let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| vec_u8_to_vec_u64(slice.to_vec())).collect(); let context = acc_map_read_guard.produce_context(account.address); let serialized_context = serde_json::to_vec(&context).unwrap(); - let serialized_context_u64 = Self::vec_u8_to_vec_u64(serialized_context); + let serialized_context_u64 = vec_u8_to_vec_u64(serialized_context); vec_values_u64.push(serialized_context_u64); @@ -535,13 +538,13 @@ impl NodeCore { let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; - let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| Self::vec_u8_to_vec_u64(slice.to_vec())).collect(); + let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| vec_u8_to_vec_u64(slice.to_vec())).collect(); let context = acc_map_read_guard.produce_context(account.address); let serialized_context = serde_json::to_vec(&context).unwrap(); - let serialized_context_u64 = Self::vec_u8_to_vec_u64(serialized_context); + let serialized_context_u64 = vec_u8_to_vec_u64(serialized_context); vec_values_u64.push(serialized_context_u64); @@ -646,9 +649,9 @@ impl NodeCore { let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; - let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| Self::vec_u8_to_vec_u64(slice.to_vec())).collect(); + let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| vec_u8_to_vec_u64(slice.to_vec())).collect(); - let serialized_context_u64 = Self::vec_u8_to_vec_u64(serde_json::to_vec(&acc_map_read_guard.produce_context(account.address)).unwrap()); + let serialized_context_u64 = vec_u8_to_vec_u64(serde_json::to_vec(&acc_map_read_guard.produce_context(account.address)).unwrap()); vec_values_u64.push(serialized_context_u64); @@ -723,13 +726,13 @@ impl NodeCore { let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; - let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| Self::vec_u8_to_vec_u64(slice.to_vec())).collect(); + let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| vec_u8_to_vec_u64(slice.to_vec())).collect(); let context = acc_map_read_guard.produce_context(account.address); let serialized_context = serde_json::to_vec(&context).unwrap(); - let serialized_context_u64 = Self::vec_u8_to_vec_u64(serialized_context); + let serialized_context_u64 = vec_u8_to_vec_u64(serialized_context); vec_values_u64.push(serialized_context_u64); @@ -1331,13 +1334,13 @@ impl NodeCore { let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; - let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| Self::vec_u8_to_vec_u64(slice.to_vec())).collect(); + let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| vec_u8_to_vec_u64(slice.to_vec())).collect(); let context = acc_map_read_guard.produce_context(account.address); let serialized_context = serde_json::to_vec(&context).unwrap(); - let serialized_context_u64 = Self::vec_u8_to_vec_u64(serialized_context); + let serialized_context_u64 = vec_u8_to_vec_u64(serialized_context); vec_values_u64.push(serialized_context_u64); From bc990265213dea40b67059f58019dbbb7e08a8a1 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:38:22 -0400 Subject: [PATCH 25/31] fmt --- core_primitives/src/transaction.rs | 2 +- node_core/src/executions/de.rs | 24 +++---- node_core/src/lib.rs | 86 +++++++++++++++++------ node_core/src/storage/block_store.rs | 2 +- node_core/src/storage/public_context.rs | 2 +- sc_core/src/transaction_payloads_tools.rs | 8 ++- storage/src/transaction.rs | 2 +- 7 files changed, 87 insertions(+), 39 deletions(-) diff --git a/core_primitives/src/transaction.rs b/core_primitives/src/transaction.rs index 2ffd65ac..5dbf226c 100644 --- a/core_primitives/src/transaction.rs +++ b/core_primitives/src/transaction.rs @@ -6,8 +6,8 @@ use elliptic_curve::{ consts::{B0, B1}, generic_array::GenericArray, }; -use sha2::digest::typenum::{UInt, UTerm}; use secp256k1_zkp::PedersenCommitment; +use sha2::digest::typenum::{UInt, UTerm}; pub type CipherText = Vec; pub type Nonce = GenericArray, B1>, B0>, B0>>; diff --git a/node_core/src/executions/de.rs b/node_core/src/executions/de.rs index 8e8ba60b..a4ee490d 100644 --- a/node_core/src/executions/de.rs +++ b/node_core/src/executions/de.rs @@ -155,10 +155,7 @@ pub fn verify_commitment( } // new_commitment -pub fn new_commitment( - public_info: u64, - secret_r: &[u8], -) -> (Tweak, &[u8], PedersenCommitment) { +pub fn new_commitment(public_info: u64, secret_r: &[u8]) -> (Tweak, &[u8], PedersenCommitment) { let generator_blinding_factor = Tweak::new(&mut thread_rng()); let commitment_secrets = CommitmentSecrets { value: public_info, @@ -180,15 +177,18 @@ pub fn new_commitment_vec( let generator_blinding_factor = Tweak::new(&mut thread_rng()); let tag = tag_random(); - let vec_commitments = public_info_vec.into_iter().map(|public_info| { - let commitment_secrets = CommitmentSecrets { - value: public_info, - value_blinding_factor: Tweak::from_slice(secret_r).unwrap(), - generator_blinding_factor, - }; + let vec_commitments = public_info_vec + .into_iter() + .map(|public_info| { + let commitment_secrets = CommitmentSecrets { + value: public_info, + value_blinding_factor: Tweak::from_slice(secret_r).unwrap(), + generator_blinding_factor, + }; - commit(&commitment_secrets, tag) - }).collect(); + commit(&commitment_secrets, tag) + }) + .collect(); (generator_blinding_factor, secret_r, vec_commitments) } diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index d5833924..371360d3 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -5,13 +5,16 @@ use std::sync::{ use common::ExecutionFailureKind; -use rand::Rng; use ::storage::transaction::{Transaction, TransactionPayload, TxKind}; use accounts::account_core::{Account, AccountAddress}; use anyhow::Result; use config::NodeConfig; -use executions::{de::new_commitment_vec, private_exec::{generate_commitments, generate_nullifiers}}; +use executions::{ + de::new_commitment_vec, + private_exec::{generate_commitments, generate_nullifiers}, +}; use log::info; +use rand::Rng; use sequencer_client::{json::SendTxResponse, SequencerClient}; use serde::{Deserialize, Serialize}; use storage::NodeChainStore; @@ -216,9 +219,15 @@ impl NodeCore { let mut rng = rand::thread_rng(); let secret_r: [u8; 32] = rng.gen(); - let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; + let sc_state = acc_map_read_guard + .block_store + .get_sc_sc_state(sc_addr) + .map_err(ExecutionFailureKind::db_error)?; - let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| vec_u8_to_vec_u64(slice.to_vec())).collect(); + let mut vec_values_u64: Vec> = sc_state + .into_iter() + .map(|slice| vec_u8_to_vec_u64(slice.to_vec())) + .collect(); let context = acc_map_read_guard.produce_context(account.address); @@ -258,9 +267,6 @@ impl NodeCore { )) } - - - pub async fn mint_utxo_multiple_assets_private( &self, acc: AccountAddress, @@ -302,9 +308,15 @@ impl NodeCore { let mut rng = rand::thread_rng(); let secret_r: [u8; 32] = rng.gen(); - let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; + let sc_state = acc_map_read_guard + .block_store + .get_sc_sc_state(sc_addr) + .map_err(ExecutionFailureKind::db_error)?; - let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| vec_u8_to_vec_u64(slice.to_vec())).collect(); + let mut vec_values_u64: Vec> = sc_state + .into_iter() + .map(|slice| vec_u8_to_vec_u64(slice.to_vec())) + .collect(); let context = acc_map_read_guard.produce_context(account.address); @@ -399,15 +411,21 @@ impl NodeCore { .collect(); let commitments = generate_commitments(&utxos); - + // TODO: fix address when correspoding method will be added let sc_addr = ""; let mut rng = rand::thread_rng(); let secret_r: [u8; 32] = rng.gen(); - let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; + let sc_state = acc_map_read_guard + .block_store + .get_sc_sc_state(sc_addr) + .map_err(ExecutionFailureKind::db_error)?; - let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| vec_u8_to_vec_u64(slice.to_vec())).collect(); + let mut vec_values_u64: Vec> = sc_state + .into_iter() + .map(|slice| vec_u8_to_vec_u64(slice.to_vec())) + .collect(); let context = acc_map_read_guard.produce_context(account.address); @@ -536,9 +554,15 @@ impl NodeCore { let mut rng = rand::thread_rng(); let secret_r: [u8; 32] = rng.gen(); - let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; + let sc_state = acc_map_read_guard + .block_store + .get_sc_sc_state(sc_addr) + .map_err(ExecutionFailureKind::db_error)?; - let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| vec_u8_to_vec_u64(slice.to_vec())).collect(); + let mut vec_values_u64: Vec> = sc_state + .into_iter() + .map(|slice| vec_u8_to_vec_u64(slice.to_vec())) + .collect(); let context = acc_map_read_guard.produce_context(account.address); @@ -647,11 +671,19 @@ impl NodeCore { let mut rng = rand::thread_rng(); let secret_r: [u8; 32] = rng.gen(); - let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; + let sc_state = acc_map_read_guard + .block_store + .get_sc_sc_state(sc_addr) + .map_err(ExecutionFailureKind::db_error)?; - let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| vec_u8_to_vec_u64(slice.to_vec())).collect(); + let mut vec_values_u64: Vec> = sc_state + .into_iter() + .map(|slice| vec_u8_to_vec_u64(slice.to_vec())) + .collect(); - let serialized_context_u64 = vec_u8_to_vec_u64(serde_json::to_vec(&acc_map_read_guard.produce_context(account.address)).unwrap()); + let serialized_context_u64 = vec_u8_to_vec_u64( + serde_json::to_vec(&acc_map_read_guard.produce_context(account.address)).unwrap(), + ); vec_values_u64.push(serialized_context_u64); @@ -724,9 +756,15 @@ impl NodeCore { let mut rng = rand::thread_rng(); let secret_r: [u8; 32] = rng.gen(); - let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; + let sc_state = acc_map_read_guard + .block_store + .get_sc_sc_state(sc_addr) + .map_err(ExecutionFailureKind::db_error)?; - let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| vec_u8_to_vec_u64(slice.to_vec())).collect(); + let mut vec_values_u64: Vec> = sc_state + .into_iter() + .map(|slice| vec_u8_to_vec_u64(slice.to_vec())) + .collect(); let context = acc_map_read_guard.produce_context(account.address); @@ -1332,9 +1370,15 @@ impl NodeCore { let mut rng = rand::thread_rng(); let secret_r: [u8; 32] = rng.gen(); - let sc_state = acc_map_read_guard.block_store.get_sc_sc_state(sc_addr).map_err(ExecutionFailureKind::db_error)?; + let sc_state = acc_map_read_guard + .block_store + .get_sc_sc_state(sc_addr) + .map_err(ExecutionFailureKind::db_error)?; - let mut vec_values_u64: Vec> = sc_state.into_iter().map(|slice| vec_u8_to_vec_u64(slice.to_vec())).collect(); + let mut vec_values_u64: Vec> = sc_state + .into_iter() + .map(|slice| vec_u8_to_vec_u64(slice.to_vec())) + .collect(); let context = acc_map_read_guard.produce_context(account.address); diff --git a/node_core/src/storage/block_store.rs b/node_core/src/storage/block_store.rs index 828d8acd..33aa8ab0 100644 --- a/node_core/src/storage/block_store.rs +++ b/node_core/src/storage/block_store.rs @@ -1,8 +1,8 @@ use std::path::Path; use anyhow::{anyhow, Result}; -use storage::{block::Block, RocksDBIO}; use storage::sc_db_utils::DataBlob; +use storage::{block::Block, RocksDBIO}; pub struct NodeBlockStore { dbio: RocksDBIO, diff --git a/node_core/src/storage/public_context.rs b/node_core/src/storage/public_context.rs index f4c406cc..560bf011 100644 --- a/node_core/src/storage/public_context.rs +++ b/node_core/src/storage/public_context.rs @@ -1,7 +1,7 @@ use std::collections::BTreeMap; use accounts::account_core::{AccountAddress, AccountPublicMask}; -use serde::{Serialize}; +use serde::Serialize; use storage::merkle_tree_public::TreeHashType; ///Strucutre, representing context, given to a smart contract on a call diff --git a/sc_core/src/transaction_payloads_tools.rs b/sc_core/src/transaction_payloads_tools.rs index 2541bc6e..9cc97584 100644 --- a/sc_core/src/transaction_payloads_tools.rs +++ b/sc_core/src/transaction_payloads_tools.rs @@ -13,7 +13,7 @@ pub fn create_public_transaction_payload(execution_input: Vec) -> Transactio let unblinded_gen = Generator::new_unblinded(SECP256K1, tag); let mut rng = rand::thread_rng(); - + TransactionPayload { tx_kind: TxKind::Public, execution_input, @@ -24,7 +24,11 @@ pub fn create_public_transaction_payload(execution_input: Vec) -> Transactio execution_proof_private: "".to_string(), encoded_data: vec![], ephemeral_pub_key: vec![], - commitment: vec![PedersenCommitment::new_unblinded(SECP256K1, 0, unblinded_gen)], + commitment: vec![PedersenCommitment::new_unblinded( + SECP256K1, + 0, + unblinded_gen, + )], tweak: Tweak::new(&mut rng), secret_r: [0; 32], } diff --git a/storage/src/transaction.rs b/storage/src/transaction.rs index 32cb1f06..0b7d26e8 100644 --- a/storage/src/transaction.rs +++ b/storage/src/transaction.rs @@ -1,7 +1,7 @@ use log::info; +use secp256k1_zkp::{rand, PedersenCommitment, Tweak}; use serde::{Deserialize, Serialize}; use sha2::{digest::FixedOutput, Digest}; -use secp256k1_zkp::{rand, PedersenCommitment, Tweak}; use crate::merkle_tree_public::TreeHashType; From 0db4a60399d462a67577f60fe86ce0037801dc46 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 01:38:57 -0400 Subject: [PATCH 26/31] lint --- sc_core/src/transaction_payloads_tools.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sc_core/src/transaction_payloads_tools.rs b/sc_core/src/transaction_payloads_tools.rs index 9cc97584..5c7d4806 100644 --- a/sc_core/src/transaction_payloads_tools.rs +++ b/sc_core/src/transaction_payloads_tools.rs @@ -2,7 +2,7 @@ use accounts::account_core::Account; use anyhow::Result; use rand::thread_rng; use risc0_zkvm::Receipt; -use secp256k1_zkp::{CommitmentSecrets, Generator, PedersenCommitment, Tag, Tweak, SECP256K1}; +use secp256k1_zkp::{CommitmentSecrets, Generator, PedersenCommitment, Tweak, SECP256K1}; use storage::transaction::{TransactionPayload, TxKind}; use utxo::utxo_core::UTXO; From b3d96d8b53067d2959edd8474b1066936c51558d Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 02:01:18 -0400 Subject: [PATCH 27/31] taplo --- sequencer_core/Cargo.toml | 2 +- storage/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sequencer_core/Cargo.toml b/sequencer_core/Cargo.toml index 992992a6..730684ab 100644 --- a/sequencer_core/Cargo.toml +++ b/sequencer_core/Cargo.toml @@ -24,4 +24,4 @@ path = "../accounts" [dependencies.secp256k1-zkp] workspace = true -features = ["std", "rand-std", "rand", "serde", "global-context"] \ No newline at end of file +features = ["std", "rand-std", "rand", "serde", "global-context"] diff --git a/storage/Cargo.toml b/storage/Cargo.toml index 6e27eda0..4455cbf1 100644 --- a/storage/Cargo.toml +++ b/storage/Cargo.toml @@ -21,4 +21,4 @@ monotree.workspace = true [dependencies.secp256k1-zkp] workspace = true -features = ["std", "rand-std", "rand", "serde", "global-context"] \ No newline at end of file +features = ["std", "rand-std", "rand", "serde", "global-context"] From e75db3b73da97bf97e06b2d0c946895c6c7ea604 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 02:03:01 -0400 Subject: [PATCH 28/31] fix tests --- sequencer_core/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index 265bcfe1..e8d74e05 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -262,6 +262,7 @@ mod tests { use super::*; use std::{fmt::format, path::PathBuf}; + use secp256k1_zkp::Tweak; use rand::Rng; use storage::transaction::{Transaction, TxKind}; use transaction_mempool::TransactionMempool; @@ -289,6 +290,8 @@ mod tests { utxo_commitments_spent_hashes: Vec<[u8; 32]>, utxo_commitments_created_hashes: Vec<[u8; 32]>, ) -> Transaction { + let mut rng = rand::thread_rng(); + Transaction { hash, tx_kind: TxKind::Private, From 7b82c5b00cf788821d25742b3af7a04a78329229 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Wed, 9 Apr 2025 02:20:27 -0400 Subject: [PATCH 29/31] fmt --- sequencer_core/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index e8d74e05..01b0dd9f 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -262,8 +262,8 @@ mod tests { use super::*; use std::{fmt::format, path::PathBuf}; - use secp256k1_zkp::Tweak; use rand::Rng; + use secp256k1_zkp::Tweak; use storage::transaction::{Transaction, TxKind}; use transaction_mempool::TransactionMempool; From 80192ea42a1d3057b5799f279ccbec7741470404 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 10 Apr 2025 15:57:33 +0300 Subject: [PATCH 30/31] fix: PublicSCContext stable serialization --- accounts/src/account_core/mod.rs | 2 +- node_core/src/lib.rs | 120 ++++++++++------------ node_core/src/storage/public_context.rs | 115 ++++++++++++++++++++- sc_core/src/proofs_circuits.rs | 28 ++++- sc_core/src/transaction_payloads_tools.rs | 24 ++--- storage/src/transaction.rs | 8 +- 6 files changed, 206 insertions(+), 91 deletions(-) diff --git a/accounts/src/account_core/mod.rs b/accounts/src/account_core/mod.rs index 3f6ac0dd..1bedd55e 100644 --- a/accounts/src/account_core/mod.rs +++ b/accounts/src/account_core/mod.rs @@ -29,7 +29,7 @@ pub struct Account { ///A strucure, which represents all the visible(public) information /// /// known to each node about account `address` -#[derive(Serialize)] +#[derive(Serialize, Clone)] pub struct AccountPublicMask { pub nullifier_public_key: AffinePoint, pub viewing_public_key: AffinePoint, diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index 371360d3..c0084698 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -9,12 +9,9 @@ use ::storage::transaction::{Transaction, TransactionPayload, TxKind}; use accounts::account_core::{Account, AccountAddress}; use anyhow::Result; use config::NodeConfig; -use executions::{ - de::new_commitment_vec, - private_exec::{generate_commitments, generate_nullifiers}, -}; +use executions::private_exec::{generate_commitments, generate_nullifiers}; use log::info; -use rand::Rng; +use sc_core::proofs_circuits::pedersen_commitment_vec; use sequencer_client::{json::SendTxResponse, SequencerClient}; use serde::{Deserialize, Serialize}; use storage::NodeChainStore; @@ -216,8 +213,6 @@ impl NodeCore { // TODO: fix address when correspoding method will be added let sc_addr = ""; - let mut rng = rand::thread_rng(); - let secret_r: [u8; 32] = rng.gen(); let sc_state = acc_map_read_guard .block_store @@ -231,15 +226,13 @@ impl NodeCore { let context = acc_map_read_guard.produce_context(account.address); - let serialized_context = serde_json::to_vec(&context).unwrap(); - - let serialized_context_u64 = vec_u8_to_vec_u64(serialized_context); - - vec_values_u64.push(serialized_context_u64); + //Will not panic, as PublicScContext is serializable + let context_public_info: Vec = context.produce_u64_list_from_context().unwrap(); + vec_values_u64.push(context_public_info); let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); - let (tweak, secret_r, commitment) = new_commitment_vec(vec_public_info, &secret_r); + let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); Ok(( TransactionPayload { @@ -260,7 +253,7 @@ impl NodeCore { ephemeral_pub_key: eph_pub_key.to_vec(), commitment, tweak, - secret_r: secret_r.try_into().unwrap(), + secret_r, } .into(), result_hash, @@ -305,8 +298,6 @@ impl NodeCore { // TODO: fix address when correspoding method will be added let sc_addr = ""; - let mut rng = rand::thread_rng(); - let secret_r: [u8; 32] = rng.gen(); let sc_state = acc_map_read_guard .block_store @@ -320,15 +311,13 @@ impl NodeCore { let context = acc_map_read_guard.produce_context(account.address); - let serialized_context = serde_json::to_vec(&context).unwrap(); - - let serialized_context_u64 = vec_u8_to_vec_u64(serialized_context); - - vec_values_u64.push(serialized_context_u64); + //Will not panic, as PublicScContext is serializable + let context_public_info: Vec = context.produce_u64_list_from_context().unwrap(); + vec_values_u64.push(context_public_info); let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); - let (tweak, secret_r, commitment) = new_commitment_vec(vec_public_info, &secret_r); + let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); Ok(( TransactionPayload { @@ -349,7 +338,7 @@ impl NodeCore { ephemeral_pub_key: eph_pub_key.to_vec(), commitment, tweak, - secret_r: secret_r.try_into().unwrap(), + secret_r, } .into(), result_hashes, @@ -414,8 +403,6 @@ impl NodeCore { // TODO: fix address when correspoding method will be added let sc_addr = ""; - let mut rng = rand::thread_rng(); - let secret_r: [u8; 32] = rng.gen(); let sc_state = acc_map_read_guard .block_store @@ -429,15 +416,13 @@ impl NodeCore { let context = acc_map_read_guard.produce_context(account.address); - let serialized_context = serde_json::to_vec(&context).unwrap(); - - let serialized_context_u64 = vec_u8_to_vec_u64(serialized_context); - - vec_values_u64.push(serialized_context_u64); + //Will not panic, as PublicScContext is serializable + let context_public_info: Vec = context.produce_u64_list_from_context().unwrap(); + vec_values_u64.push(context_public_info); let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); - let (tweak, secret_r, commitment) = new_commitment_vec(vec_public_info, &secret_r); + let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); Ok(( TransactionPayload { @@ -458,7 +443,7 @@ impl NodeCore { ephemeral_pub_key: eph_pub_key.to_vec(), commitment, tweak, - secret_r: secret_r.try_into().unwrap(), + secret_r, } .into(), utxo_hashes, @@ -551,8 +536,6 @@ impl NodeCore { // TODO: fix address when correspoding method will be added let sc_addr = ""; - let mut rng = rand::thread_rng(); - let secret_r: [u8; 32] = rng.gen(); let sc_state = acc_map_read_guard .block_store @@ -566,15 +549,13 @@ impl NodeCore { let context = acc_map_read_guard.produce_context(account.address); - let serialized_context = serde_json::to_vec(&context).unwrap(); - - let serialized_context_u64 = vec_u8_to_vec_u64(serialized_context); - - vec_values_u64.push(serialized_context_u64); + //Will not panic, as PublicScContext is serializable + let context_public_info: Vec = context.produce_u64_list_from_context().unwrap(); + vec_values_u64.push(context_public_info); let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); - let (tweak, secret_r, commitment) = new_commitment_vec(vec_public_info, &secret_r); + let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); Ok(( TransactionPayload { @@ -595,7 +576,7 @@ impl NodeCore { ephemeral_pub_key: eph_pub_key.to_vec(), commitment, tweak, - secret_r: secret_r.try_into().unwrap(), + secret_r, } .into(), utxo_hashes_receiver, @@ -668,9 +649,6 @@ impl NodeCore { // TODO: fix address when correspoding method will be added let sc_addr = ""; - let mut rng = rand::thread_rng(); - let secret_r: [u8; 32] = rng.gen(); - let sc_state = acc_map_read_guard .block_store .get_sc_sc_state(sc_addr) @@ -681,15 +659,15 @@ impl NodeCore { .map(|slice| vec_u8_to_vec_u64(slice.to_vec())) .collect(); - let serialized_context_u64 = vec_u8_to_vec_u64( - serde_json::to_vec(&acc_map_read_guard.produce_context(account.address)).unwrap(), - ); + let context = acc_map_read_guard.produce_context(account.address); - vec_values_u64.push(serialized_context_u64); + //Will not panic, as PublicScContext is serializable + let context_public_info: Vec = context.produce_u64_list_from_context().unwrap(); + vec_values_u64.push(context_public_info); let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); - let (tweak, secret_r, commitment) = new_commitment_vec(vec_public_info, &secret_r); + let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); Ok(( TransactionPayload { @@ -716,7 +694,7 @@ impl NodeCore { ephemeral_pub_key: eph_pub_key.to_vec(), commitment, tweak, - secret_r: secret_r.try_into().unwrap(), + secret_r, } .into(), utxo_hashes, @@ -753,8 +731,6 @@ impl NodeCore { // TODO: fix address when correspoding method will be added let sc_addr = ""; - let mut rng = rand::thread_rng(); - let secret_r: [u8; 32] = rng.gen(); let sc_state = acc_map_read_guard .block_store @@ -768,15 +744,13 @@ impl NodeCore { let context = acc_map_read_guard.produce_context(account.address); - let serialized_context = serde_json::to_vec(&context).unwrap(); - - let serialized_context_u64 = vec_u8_to_vec_u64(serialized_context); - - vec_values_u64.push(serialized_context_u64); + //Will not panic, as PublicScContext is serializable + let context_public_info: Vec = context.produce_u64_list_from_context().unwrap(); + vec_values_u64.push(context_public_info); let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); - let (tweak, secret_r, commitment) = new_commitment_vec(vec_public_info, &secret_r); + let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); Ok(TransactionPayload { tx_kind: TxKind::Deshielded, @@ -796,7 +770,7 @@ impl NodeCore { ephemeral_pub_key: vec![], commitment, tweak, - secret_r: secret_r.try_into().unwrap(), + secret_r, } .into()) } @@ -862,6 +836,17 @@ impl NodeCore { //Considering proof time, needs to be done before proof let tx_roots = self.get_roots().await; + let public_context = { + let read_guard = self.storage.read().await; + + read_guard.produce_context(acc) + }; + + let (tweak, secret_r, commitment) = pedersen_commitment_vec( + //Will not panic, as public context is serializable + public_context.produce_u64_list_from_context().unwrap(), + ); + let tx: Transaction = sc_core::transaction_payloads_tools::create_public_transaction_payload( serde_json::to_vec(&ActionData::MintMoneyPublicTx(MintMoneyPublicTx { @@ -869,6 +854,9 @@ impl NodeCore { amount, })) .unwrap(), + commitment, + tweak, + secret_r, ) .into(); tx.log(); @@ -1367,8 +1355,6 @@ impl NodeCore { // TODO: fix address when correspoding method will be added let sc_addr = ""; - let mut rng = rand::thread_rng(); - let secret_r: [u8; 32] = rng.gen(); let sc_state = acc_map_read_guard .block_store @@ -1382,15 +1368,13 @@ impl NodeCore { let context = acc_map_read_guard.produce_context(account.address); - let serialized_context = serde_json::to_vec(&context).unwrap(); - - let serialized_context_u64 = vec_u8_to_vec_u64(serialized_context); - - vec_values_u64.push(serialized_context_u64); + //Will not panic, as PublicScContext is serializable + let context_public_info: Vec = context.produce_u64_list_from_context().unwrap(); + vec_values_u64.push(context_public_info); let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); - let (tweak, secret_r, commitment) = new_commitment_vec(vec_public_info, &secret_r); + let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); Ok(( TransactionPayload { @@ -1412,7 +1396,7 @@ impl NodeCore { ephemeral_pub_key: eph_pub_key.to_vec(), commitment, tweak, - secret_r: secret_r.try_into().unwrap(), + secret_r, } .into(), utxo_hashes, diff --git a/node_core/src/storage/public_context.rs b/node_core/src/storage/public_context.rs index 560bf011..e21d261e 100644 --- a/node_core/src/storage/public_context.rs +++ b/node_core/src/storage/public_context.rs @@ -1,11 +1,10 @@ use std::collections::BTreeMap; use accounts::account_core::{AccountAddress, AccountPublicMask}; -use serde::Serialize; +use serde::{ser::SerializeStruct, Serialize}; use storage::merkle_tree_public::TreeHashType; ///Strucutre, representing context, given to a smart contract on a call -#[derive(Serialize)] pub struct PublicSCContext { pub caller_address: AccountAddress, pub caller_balance: u64, @@ -14,3 +13,115 @@ pub struct PublicSCContext { 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("PublicSCContext", 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("nullifier_store_root", &self.nullifier_store_root)?; + 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 nullifier_store_root = [2; 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, + nullifier_store_root, + 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); + } +} diff --git a/sc_core/src/proofs_circuits.rs b/sc_core/src/proofs_circuits.rs index 7c646c22..6b2b3675 100644 --- a/sc_core/src/proofs_circuits.rs +++ b/sc_core/src/proofs_circuits.rs @@ -2,7 +2,7 @@ use bincode; use k256::Scalar; use monotree::hasher::Blake3; use monotree::{Hasher, Monotree}; -use rand::thread_rng; +use rand::{thread_rng, RngCore}; use secp256k1_zkp::{CommitmentSecrets, Generator, PedersenCommitment, Tag, Tweak, SECP256K1}; use sha2::{Digest, Sha256}; use storage::{ @@ -168,6 +168,32 @@ pub fn check_balances(public_info: u128, output_utxos: &[UTXO]) -> bool { public_info == total_output } +// new_commitment for a Vec of values +pub fn pedersen_commitment_vec( + public_info_vec: Vec, +) -> (Tweak, [u8; 32], Vec) { + let mut random_val: [u8; 32] = [0; 32]; + thread_rng().fill_bytes(&mut random_val); + + let generator_blinding_factor = Tweak::new(&mut thread_rng()); + let tag = tag_random(); + + let vec_commitments = public_info_vec + .into_iter() + .map(|public_info| { + let commitment_secrets = CommitmentSecrets { + value: public_info, + value_blinding_factor: Tweak::from_slice(&random_val).unwrap(), + generator_blinding_factor, + }; + + commit(&commitment_secrets, tag) + }) + .collect(); + + (generator_blinding_factor, random_val, vec_commitments) +} + // Verify Pedersen commitment // takes the public_info, secret_r and pedersen_commitment and diff --git a/sc_core/src/transaction_payloads_tools.rs b/sc_core/src/transaction_payloads_tools.rs index 5c7d4806..c84cc6fe 100644 --- a/sc_core/src/transaction_payloads_tools.rs +++ b/sc_core/src/transaction_payloads_tools.rs @@ -2,18 +2,18 @@ use accounts::account_core::Account; use anyhow::Result; use rand::thread_rng; use risc0_zkvm::Receipt; -use secp256k1_zkp::{CommitmentSecrets, Generator, PedersenCommitment, Tweak, SECP256K1}; +use secp256k1_zkp::{CommitmentSecrets, PedersenCommitment, Tweak}; use storage::transaction::{TransactionPayload, TxKind}; use utxo::utxo_core::UTXO; use crate::proofs_circuits::{commit, generate_nullifiers, tag_random}; -pub fn create_public_transaction_payload(execution_input: Vec) -> TransactionPayload { - let tag = tag_random(); - let unblinded_gen = Generator::new_unblinded(SECP256K1, tag); - - let mut rng = rand::thread_rng(); - +pub fn create_public_transaction_payload( + execution_input: Vec, + commitment: Vec, + tweak: Tweak, + secret_r: [u8; 32], +) -> TransactionPayload { TransactionPayload { tx_kind: TxKind::Public, execution_input, @@ -24,13 +24,9 @@ pub fn create_public_transaction_payload(execution_input: Vec) -> Transactio execution_proof_private: "".to_string(), encoded_data: vec![], ephemeral_pub_key: vec![], - commitment: vec![PedersenCommitment::new_unblinded( - SECP256K1, - 0, - unblinded_gen, - )], - tweak: Tweak::new(&mut rng), - secret_r: [0; 32], + commitment, + tweak, + secret_r, } } diff --git a/storage/src/transaction.rs b/storage/src/transaction.rs index 0b7d26e8..149ddc0d 100644 --- a/storage/src/transaction.rs +++ b/storage/src/transaction.rs @@ -1,5 +1,5 @@ use log::info; -use secp256k1_zkp::{rand, PedersenCommitment, Tweak}; +use secp256k1_zkp::{PedersenCommitment, Tweak}; use serde::{Deserialize, Serialize}; use sha2::{digest::FixedOutput, Digest}; @@ -90,8 +90,6 @@ impl From for Transaction { let hash = ::from(hasher.finalize_fixed()); - let mut rng = rand::thread_rng(); - Self { hash, tx_kind: value.tx_kind, @@ -104,8 +102,8 @@ impl From for Transaction { encoded_data: value.encoded_data, ephemeral_pub_key: value.ephemeral_pub_key, commitment: value.commitment, - tweak: Tweak::new(&mut rng), - secret_r: [0; 32], + tweak: value.tweak, + secret_r: value.secret_r, } } } From 46361868edaa79d3bbd4fe123d7e33ae340085f3 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Mon, 14 Apr 2025 01:50:44 +0300 Subject: [PATCH 31/31] fix: additional tests for context serialization --- node_core/src/storage/public_context.rs | 49 +++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/node_core/src/storage/public_context.rs b/node_core/src/storage/public_context.rs index e21d261e..957241f1 100644 --- a/node_core/src/storage/public_context.rs +++ b/node_core/src/storage/public_context.rs @@ -124,4 +124,53 @@ mod tests { 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()); + } }