From 6e48bcfd9e58b1d4eb5bb99e2305b7ed84ef2f91 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Mon, 14 Jul 2025 09:37:00 -0300 Subject: [PATCH] sign transactions from node's end --- Cargo.lock | 1 + common/Cargo.toml | 1 + common/src/lib.rs | 6 + common/src/transaction.rs | 106 +++-- node_core/src/lib.rs | 582 +++++++++++++------------ node_core/src/sequencer_client/json.rs | 4 +- node_core/src/sequencer_client/mod.rs | 4 +- node_rpc/src/process.rs | 82 ++-- 8 files changed, 411 insertions(+), 375 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0200d46..c19ab6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -996,6 +996,7 @@ dependencies = [ "anyhow", "elliptic-curve", "hex", + "k256", "log", "reqwest 0.11.27", "risc0-zkvm", diff --git a/common/Cargo.toml b/common/Cargo.toml index b1988ad..e00bf4d 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -10,6 +10,7 @@ serde_json.workspace = true serde.workspace = true reqwest.workspace = true risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.2" } +k256.workspace = true rs_merkle.workspace = true sha2.workspace = true diff --git a/common/src/lib.rs b/common/src/lib.rs index 46868d9..96a7b55 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -88,3 +88,9 @@ impl ExecutionFailureKind { Self::DBError(err) } } + +#[derive(Debug, thiserror::Error)] +pub enum TransactionSignatureError { + #[error("invalid signature for transaction body")] + InvalidSignature, +} diff --git a/common/src/transaction.rs b/common/src/transaction.rs index fd0b4c3..6e6f651 100644 --- a/common/src/transaction.rs +++ b/common/src/transaction.rs @@ -1,5 +1,6 @@ +use k256::Scalar; use log::info; -use secp256k1_zkp::{PedersenCommitment, PublicKey, Scalar, Tweak}; +use secp256k1_zkp::{PedersenCommitment, Tweak}; use serde::{Deserialize, Serialize}; use sha2::{digest::FixedOutput, Digest}; @@ -11,6 +12,8 @@ use elliptic_curve::{ }; use sha2::digest::typenum::{UInt, UTerm}; +use crate::TransactionSignatureError; + pub type CipherText = Vec; pub type Nonce = GenericArray, B1>, B0>, B0>>; pub type Tag = u8; @@ -57,28 +60,6 @@ pub struct TransactionBody { pub state_changes: (serde_json::Value, usize), } -#[derive(Serialize, Deserialize)] -struct TransactionSignature; - -#[derive(Serialize, Deserialize)] -struct TransactionHash; - -/// A transaction with a signature. -/// Meant to be sent through the network to the sequencer -#[derive(Serialize, Deserialize)] -pub struct SignedTransaction { - body: TransactionBody, - signature: TransactionSignature, -} - -/// A transaction with a valid signature over its hash. -/// Can only be constructed from an `UnverifiedSignedTransaction` -/// if the signature is valid -pub struct AuthenticatedTransaction { - hash: TransactionHash, - signed_tx: SignedTransaction -} - #[derive(Debug, Serialize, Deserialize)] pub struct MintMoneyPublicTx { pub acc: [u8; 32], @@ -172,9 +153,6 @@ impl ActionData { } } -type SignaturePrivateKey = Scalar; -type SignaturePublicKey = PublicKey; - impl TransactionBody { /// Computes and returns the SHA-256 hash of the JSON-serialized representation of `self`. pub fn hash(&self) -> TreeHashType { @@ -187,16 +165,6 @@ impl TransactionBody { TreeHashType::from(hasher.finalize_fixed()) } - pub fn sign(self, _private_key: SignaturePrivateKey) -> SignedTransaction { - let _hash = self.hash(); - // Implement actual signature over `hash` - let signature = TransactionSignature {}; - SignedTransaction { - body: self, - signature, - } - } - pub fn log(&self) { info!("Transaction hash is {:?}", hex::encode(self.hash())); info!("Transaction tx_kind is {:?}", self.tx_kind); @@ -249,38 +217,62 @@ impl TransactionBody { } } +type SignaturePrivateKey = Scalar; + +#[derive(Debug, Serialize, Deserialize)] +struct TransactionSignature; + +type TransactionHash = TreeHashType; + +/// A transaction with a signature. +/// Meant to be sent through the network to the sequencer +#[derive(Debug, Serialize, Deserialize)] +pub struct SignedTransaction { + pub body: TransactionBody, + signature: TransactionSignature, +} + impl SignedTransaction { - pub fn into_authenticated(self) -> AuthenticatedTransaction { - let hash = TransactionHash; // self.body.hash(); - // Check signature over hash - AuthenticatedTransaction { - hash, - signed_tx: self - } + pub fn from_transaction_body( + body: TransactionBody, + _private_key: SignaturePrivateKey, + ) -> SignedTransaction { + let _hash = body.hash(); + // TODO: Implement actual signature over `hash` + let signature = TransactionSignature {}; + Self { body, signature } } + + pub fn into_authenticated(self) -> Result { + let hash = self.body.hash(); + // TODO: Check signature over hash + Err(TransactionSignatureError::InvalidSignature) + } +} + +/// A transaction with a valid signature over the hash of its body. +/// Can only be constructed from an `SignedTransaction` +/// if the signature is valid +pub struct AuthenticatedTransaction { + hash: TransactionHash, + signed_tx: SignedTransaction, } impl AuthenticatedTransaction { pub fn as_signed(&self) -> &SignedTransaction { &self.signed_tx } -} -impl Serialize for AuthenticatedTransaction { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - self.as_signed().serialize(serializer) + pub fn body(&self) -> &TransactionBody { + &self.signed_tx.body } -} -impl<'de> Deserialize<'de> for AuthenticatedTransaction { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - SignedTransaction::deserialize(deserializer).map(|signed_tx| signed_tx.into_authenticated()) + pub fn signature(&self) -> &TransactionSignature { + &self.signed_tx.signature + } + + pub fn hash(&self) -> &TransactionHash { + &self.hash } } diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index fa49001..04aa467 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -3,7 +3,7 @@ use std::sync::{ Arc, }; -use common::ExecutionFailureKind; +use common::{transaction::SignedTransaction, ExecutionFailureKind}; use accounts::account_core::{Account, AccountAddress}; use anyhow::Result; @@ -189,7 +189,7 @@ impl NodeCore { &self, acc: AccountAddress, amount: u128, - ) -> Result<(TransactionBody, [u8; 32]), ExecutionFailureKind> { + ) -> Result<(SignedTransaction, [u8; 32]), ExecutionFailureKind> { let (utxo, receipt) = prove_mint_utxo(amount, acc)?; let result_hash = utxo.hash; @@ -244,31 +244,34 @@ impl NodeCore { let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); + let transaction_body = TransactionBody { + tx_kind: TxKind::Private, + execution_input: vec![], + execution_output: vec![], + utxo_commitments_spent_hashes: vec![], + utxo_commitments_created_hashes: comm + .into_iter() + .map(|hash_data| hash_data.try_into().unwrap()) + .collect(), + nullifier_created_hashes: vec![], + execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt) + .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, + sc_addr, + state_changes, + }; + // TODO: Change to the correct key once established. + let key_to_sign_transaction = account + .key_holder + .utxo_secret_key_holder + .nullifier_secret_key; Ok(( - TransactionBody { - tx_kind: TxKind::Private, - execution_input: vec![], - execution_output: vec![], - utxo_commitments_spent_hashes: vec![], - utxo_commitments_created_hashes: comm - .into_iter() - .map(|hash_data| hash_data.try_into().unwrap()) - .collect(), - nullifier_created_hashes: vec![], - execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt( - receipt, - ) - .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, - sc_addr, - state_changes, - } - .into(), + SignedTransaction::from_transaction_body(transaction_body, key_to_sign_transaction), result_hash, )) } @@ -278,7 +281,7 @@ impl NodeCore { acc: AccountAddress, amount: u128, number_of_assets: usize, - ) -> Result<(TransactionBody, Vec<[u8; 32]>), ExecutionFailureKind> { + ) -> Result<(SignedTransaction, Vec<[u8; 32]>), ExecutionFailureKind> { let (utxos, receipt) = prove_mint_utxo_multiple_assets(amount, number_of_assets, acc)?; let result_hashes = utxos.iter().map(|utxo| utxo.hash).collect(); @@ -342,30 +345,34 @@ impl NodeCore { let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); - Ok(( - TransactionBody { - tx_kind: TxKind::Private, - execution_input: vec![], - execution_output: vec![], - utxo_commitments_spent_hashes: vec![], - utxo_commitments_created_hashes: comm - .into_iter() - .map(|hash_data| hash_data.try_into().unwrap()) - .collect(), - nullifier_created_hashes: vec![], - execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt( - receipt, - ) + let transaction_body = TransactionBody { + tx_kind: TxKind::Private, + execution_input: vec![], + execution_output: vec![], + utxo_commitments_spent_hashes: vec![], + utxo_commitments_created_hashes: comm + .into_iter() + .map(|hash_data| hash_data.try_into().unwrap()) + .collect(), + nullifier_created_hashes: vec![], + execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt) .unwrap(), - encoded_data, - ephemeral_pub_key: eph_pub_key.to_vec(), - commitment, - tweak, - secret_r, - sc_addr, - state_changes, - } - .into(), + encoded_data, + ephemeral_pub_key: eph_pub_key.to_vec(), + commitment, + tweak, + secret_r, + sc_addr, + state_changes, + }; + // TODO: Change to the correct key once established. + let key_to_sign_transaction = account + .key_holder + .utxo_secret_key_holder + .nullifier_secret_key; + + Ok(( + SignedTransaction::from_transaction_body(transaction_body, key_to_sign_transaction), result_hashes, )) } @@ -375,7 +382,7 @@ impl NodeCore { utxo: UTXO, commitment_in: [u8; 32], receivers: Vec<(u128, AccountAddress)>, - ) -> Result<(TransactionBody, Vec<(AccountAddress, [u8; 32])>), ExecutionFailureKind> { + ) -> Result<(SignedTransaction, Vec<(AccountAddress, [u8; 32])>), ExecutionFailureKind> { let acc_map_read_guard = self.storage.read().await; let account = acc_map_read_guard.acc_map.get(&utxo.owner).unwrap(); @@ -458,30 +465,35 @@ impl NodeCore { let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); - Ok(( - TransactionBody { - tx_kind: TxKind::Private, - execution_input: vec![], - execution_output: vec![], - utxo_commitments_spent_hashes: vec![commitment_in], - utxo_commitments_created_hashes: commitments - .into_iter() - .map(|hash_data| hash_data.try_into().unwrap()) - .collect(), - nullifier_created_hashes: vec![nullifier.try_into().unwrap()], - execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt( - receipt, - ) + let transaction_body = TransactionBody { + tx_kind: TxKind::Private, + execution_input: vec![], + execution_output: vec![], + utxo_commitments_spent_hashes: vec![commitment_in], + utxo_commitments_created_hashes: commitments + .into_iter() + .map(|hash_data| hash_data.try_into().unwrap()) + .collect(), + nullifier_created_hashes: vec![nullifier.try_into().unwrap()], + execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt) .unwrap(), - encoded_data, - ephemeral_pub_key: eph_pub_key.to_vec(), - commitment, - tweak, - secret_r, - sc_addr, - state_changes, - } - .into(), + encoded_data, + ephemeral_pub_key: eph_pub_key.to_vec(), + commitment, + tweak, + secret_r, + sc_addr, + state_changes, + }; + + // TODO: Change to the correct key once established. + let key_to_sign_transaction = account + .key_holder + .utxo_secret_key_holder + .nullifier_secret_key; + + Ok(( + SignedTransaction::from_transaction_body(transaction_body, key_to_sign_transaction), utxo_hashes, )) } @@ -492,7 +504,7 @@ impl NodeCore { commitments_in: Vec<[u8; 32]>, number_to_send: usize, receiver: AccountAddress, - ) -> Result<(TransactionBody, Vec<[u8; 32]>, Vec<[u8; 32]>), ExecutionFailureKind> { + ) -> Result<(SignedTransaction, Vec<[u8; 32]>, Vec<[u8; 32]>), ExecutionFailureKind> { let acc_map_read_guard = self.storage.read().await; let account = acc_map_read_guard.acc_map.get(&utxos[0].owner).unwrap(); @@ -603,30 +615,35 @@ impl NodeCore { let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); - Ok(( - TransactionBody { - tx_kind: TxKind::Private, - execution_input: vec![], - execution_output: vec![], - utxo_commitments_spent_hashes: commitments_in, - utxo_commitments_created_hashes: commitments - .into_iter() - .map(|hash_data| hash_data.try_into().unwrap()) - .collect(), - nullifier_created_hashes: nullifiers, - execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt( - receipt, - ) + let transaction_body = TransactionBody { + tx_kind: TxKind::Private, + execution_input: vec![], + execution_output: vec![], + utxo_commitments_spent_hashes: commitments_in, + utxo_commitments_created_hashes: commitments + .into_iter() + .map(|hash_data| hash_data.try_into().unwrap()) + .collect(), + nullifier_created_hashes: nullifiers, + execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt) .unwrap(), - encoded_data, - ephemeral_pub_key: eph_pub_key.to_vec(), - commitment, - tweak, - secret_r, - sc_addr, - state_changes, - } - .into(), + encoded_data, + ephemeral_pub_key: eph_pub_key.to_vec(), + commitment, + tweak, + secret_r, + sc_addr, + state_changes, + }; + + // TODO: Change to the correct key once established. + let key_to_sign_transaction = account + .key_holder + .utxo_secret_key_holder + .nullifier_secret_key; + + Ok(( + SignedTransaction::from_transaction_body(transaction_body, key_to_sign_transaction), utxo_hashes_receiver, utxo_hashes_not_spent, )) @@ -637,7 +654,7 @@ impl NodeCore { acc: AccountAddress, balance: u64, receivers: Vec<(u128, AccountAddress)>, - ) -> Result<(TransactionBody, Vec<(AccountAddress, [u8; 32])>), ExecutionFailureKind> { + ) -> Result<(SignedTransaction, Vec<(AccountAddress, [u8; 32])>), ExecutionFailureKind> { let acc_map_read_guard = self.storage.read().await; let account = acc_map_read_guard.acc_map.get(&acc).unwrap(); @@ -726,36 +743,41 @@ impl NodeCore { let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); + let transaction_body = TransactionBody { + tx_kind: TxKind::Shielded, + execution_input: serde_json::to_vec(&ActionData::SendMoneyShieldedTx( + SendMoneyShieldedTx { + acc_sender: acc, + amount: balance as u128, + }, + )) + .unwrap(), + execution_output: vec![], + utxo_commitments_spent_hashes: vec![], + utxo_commitments_created_hashes: commitments + .into_iter() + .map(|hash_data| hash_data.try_into().unwrap()) + .collect(), + nullifier_created_hashes: vec![nullifier.try_into().unwrap()], + execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt) + .unwrap(), + encoded_data, + ephemeral_pub_key: eph_pub_key.to_vec(), + commitment, + tweak, + secret_r, + sc_addr, + state_changes, + }; + + // TODO: Change to the correct key once established. + let key_to_sign_transaction = account + .key_holder + .utxo_secret_key_holder + .nullifier_secret_key; + Ok(( - TransactionBody { - tx_kind: TxKind::Shielded, - execution_input: serde_json::to_vec(&ActionData::SendMoneyShieldedTx( - SendMoneyShieldedTx { - acc_sender: acc, - amount: balance as u128, - }, - )) - .unwrap(), - execution_output: vec![], - utxo_commitments_spent_hashes: vec![], - utxo_commitments_created_hashes: commitments - .into_iter() - .map(|hash_data| hash_data.try_into().unwrap()) - .collect(), - nullifier_created_hashes: vec![nullifier.try_into().unwrap()], - execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt( - receipt, - ) - .unwrap(), - encoded_data, - ephemeral_pub_key: eph_pub_key.to_vec(), - commitment, - tweak, - secret_r, - sc_addr, - state_changes, - } - .into(), + SignedTransaction::from_transaction_body(transaction_body, key_to_sign_transaction), utxo_hashes, )) } @@ -765,7 +787,7 @@ impl NodeCore { utxo: UTXO, comm_gen_hash: [u8; 32], receivers: Vec<(u128, AccountAddress)>, - ) -> Result { + ) -> Result { let acc_map_read_guard = self.storage.read().await; let commitment_in = acc_map_read_guard @@ -820,7 +842,7 @@ impl NodeCore { let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); - Ok(TransactionBody { + let transaction_body = TransactionBody { tx_kind: TxKind::Deshielded, execution_input: serde_json::to_vec(&ActionData::SendMoneyDeshieldedTx( SendMoneyDeshieldedTx { @@ -841,8 +863,18 @@ impl NodeCore { secret_r, sc_addr, state_changes, - } - .into()) + }; + + // TODO: Change to the correct key once established. + let key_to_sign_transaction = account + .key_holder + .utxo_secret_key_holder + .nullifier_secret_key; + + Ok(SignedTransaction::from_transaction_body( + transaction_body, + key_to_sign_transaction, + )) } pub async fn send_private_mint_tx( @@ -855,10 +887,10 @@ impl NodeCore { let point_before_prove = std::time::Instant::now(); let (tx, utxo_hash) = self.mint_utxo_private(acc, amount).await?; - tx.log(); + tx.body.log(); let point_after_prove = std::time::Instant::now(); - let commitment_generated_hash = tx.utxo_commitments_created_hashes[0]; + let commitment_generated_hash = tx.body.utxo_commitments_created_hashes[0]; let timedelta = (point_after_prove - point_before_prove).as_millis(); info!("Mint utxo proof spent {timedelta:?} milliseconds"); @@ -883,10 +915,10 @@ impl NodeCore { let (tx, utxo_hashes) = self .mint_utxo_multiple_assets_private(acc, amount, number_of_assets) .await?; - tx.log(); + tx.body.log(); let point_after_prove = std::time::Instant::now(); - let commitment_generated_hashes = tx.utxo_commitments_created_hashes.clone(); + let commitment_generated_hashes = tx.body.utxo_commitments_created_hashes.clone(); let timedelta = (point_after_prove - point_before_prove).as_millis(); info!("Mint utxo proof spent {timedelta:?} milliseconds"); @@ -898,50 +930,50 @@ impl NodeCore { )) } - pub async fn send_public_deposit( - &self, - acc: AccountAddress, - amount: u128, - ) -> Result { - //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 sc_addr = hex::encode([0; 32]); - - //Sc does not change its state - let state_changes: Vec = vec![]; - let new_len = 0; - let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len); - - let tx: TransactionBody = - sc_core::transaction_payloads_tools::create_public_transaction_payload( - serde_json::to_vec(&ActionData::MintMoneyPublicTx(MintMoneyPublicTx { - acc, - amount, - })) - .unwrap(), - commitment, - tweak, - secret_r, - sc_addr, - state_changes, - ) - .into(); - tx.log(); - - Ok(self.sequencer_client.send_tx(tx, tx_roots).await?) - } + // pub async fn send_public_deposit( + // &self, + // acc: AccountAddress, + // amount: u128, + // ) -> Result { + // //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 sc_addr = hex::encode([0; 32]); + // + // //Sc does not change its state + // let state_changes: Vec = vec![]; + // let new_len = 0; + // let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len); + // + // let tx: TransactionBody = + // sc_core::transaction_payloads_tools::create_public_transaction_payload( + // serde_json::to_vec(&ActionData::MintMoneyPublicTx(MintMoneyPublicTx { + // acc, + // amount, + // })) + // .unwrap(), + // commitment, + // tweak, + // secret_r, + // sc_addr, + // state_changes, + // ) + // .into(); + // tx.log(); + // + // Ok(self.sequencer_client.send_tx(tx, tx_roots).await?) + // } pub async fn send_private_send_tx( &self, @@ -956,7 +988,7 @@ impl NodeCore { let (tx, utxo_hashes) = self .transfer_utxo_private(utxo, comm_hash, receivers) .await?; - tx.log(); + tx.body.log(); let point_after_prove = std::time::Instant::now(); let timedelta = (point_after_prove - point_before_prove).as_millis(); @@ -982,7 +1014,7 @@ impl NodeCore { let (tx, utxo_hashes_received, utxo_hashes_not_spent) = self .transfer_utxo_multiple_assets_private(utxos, comm_hashes, number_to_send, receiver) .await?; - tx.log(); + tx.body.log(); let point_after_prove = std::time::Instant::now(); let timedelta = (point_after_prove - point_before_prove).as_millis(); @@ -1008,7 +1040,7 @@ impl NodeCore { let (tx, utxo_hashes) = self .transfer_balance_shielded(acc, amount, receivers) .await?; - tx.log(); + tx.body.log(); let point_after_prove = std::time::Instant::now(); let timedelta = (point_after_prove - point_before_prove).as_millis(); @@ -1033,7 +1065,7 @@ impl NodeCore { let tx = self .transfer_utxo_deshielded(utxo, comm_gen_hash, receivers) .await?; - tx.log(); + tx.body.log(); let point_after_prove = std::time::Instant::now(); let timedelta = (point_after_prove - point_before_prove).as_millis(); @@ -1167,46 +1199,46 @@ impl NodeCore { Ok(()) } - pub async fn operate_account_deposit_public( - &mut self, - acc_addr: AccountAddress, - amount: u128, - ) -> Result<(), ExecutionFailureKind> { - let old_balance = { - let acc_map_read_guard = self.storage.read().await; - - let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap(); - - acc.balance - }; - - info!( - "Balance of {:?} now is {old_balance:?}", - hex::encode(acc_addr) - ); - - let resp = self.send_public_deposit(acc_addr, amount).await?; - info!("Response for public deposit is {resp:?}"); - - info!("Awaiting new blocks"); - tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await; - - let new_balance = { - let acc_map_read_guard = self.storage.read().await; - - let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap(); - - acc.balance - }; - - info!( - "Balance of {:?} now is {new_balance:?}, delta is {:?}", - hex::encode(acc_addr), - new_balance - old_balance - ); - - Ok(()) - } + // pub async fn operate_account_deposit_public( + // &mut self, + // acc_addr: AccountAddress, + // amount: u128, + // ) -> Result<(), ExecutionFailureKind> { + // let old_balance = { + // let acc_map_read_guard = self.storage.read().await; + // + // let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap(); + // + // acc.balance + // }; + // + // info!( + // "Balance of {:?} now is {old_balance:?}", + // hex::encode(acc_addr) + // ); + // + // let resp = self.send_public_deposit(acc_addr, amount).await?; + // info!("Response for public deposit is {resp:?}"); + // + // info!("Awaiting new blocks"); + // tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await; + // + // let new_balance = { + // let acc_map_read_guard = self.storage.read().await; + // + // let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap(); + // + // acc.balance + // }; + // + // info!( + // "Balance of {:?} now is {new_balance:?}, delta is {:?}", + // hex::encode(acc_addr), + // new_balance - old_balance + // ); + // + // Ok(()) + // } pub async fn operate_account_send_shielded_one_receiver( &mut self, @@ -1361,7 +1393,7 @@ impl NodeCore { commitment_in: [u8; 32], receivers: Vec<(u128, AccountAddress)>, visibility_list: [bool; 3], - ) -> Result<(TransactionBody, Vec<(AccountAddress, [u8; 32])>), ExecutionFailureKind> { + ) -> Result<(SignedTransaction, Vec<(AccountAddress, [u8; 32])>), ExecutionFailureKind> { let acc_map_read_guard = self.storage.read().await; let account = acc_map_read_guard.acc_map.get(&utxo.owner).unwrap(); @@ -1458,31 +1490,35 @@ impl NodeCore { let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); - Ok(( - TransactionBody { - tx_kind: TxKind::Shielded, - execution_input: vec![], - execution_output: serde_json::to_vec(&publication).unwrap(), - utxo_commitments_spent_hashes: vec![commitment_in], - utxo_commitments_created_hashes: commitments - .clone() - .into_iter() - .map(|hash_data| hash_data.try_into().unwrap()) - .collect(), - nullifier_created_hashes: vec![nullifier.try_into().unwrap()], - execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt( - receipt, - ) + let transaction_body = TransactionBody { + tx_kind: TxKind::Shielded, + execution_input: vec![], + execution_output: serde_json::to_vec(&publication).unwrap(), + utxo_commitments_spent_hashes: vec![commitment_in], + utxo_commitments_created_hashes: commitments + .clone() + .into_iter() + .map(|hash_data| hash_data.try_into().unwrap()) + .collect(), + nullifier_created_hashes: vec![nullifier.try_into().unwrap()], + execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt) .unwrap(), - encoded_data, - ephemeral_pub_key: eph_pub_key.to_vec(), - commitment, - tweak, - secret_r, - sc_addr, - state_changes, - } - .into(), + encoded_data, + ephemeral_pub_key: eph_pub_key.to_vec(), + commitment, + tweak, + secret_r, + sc_addr, + state_changes, + }; + // TODO: Change to the correct key once established. + let key_to_sign_transaction = account + .key_holder + .utxo_secret_key_holder + .nullifier_secret_key; + + Ok(( + SignedTransaction::from_transaction_body(transaction_body, key_to_sign_transaction), utxo_hashes, )) } @@ -1502,13 +1538,13 @@ impl NodeCore { let (tx, utxo_hashes) = self .split_utxo(utxo, comm_hash, receivers, visibility_list) .await?; - tx.log(); + tx.body.log(); let point_after_prove = std::time::Instant::now(); let timedelta = (point_after_prove - point_before_prove).as_millis(); info!("Send private utxo proof spent {timedelta:?} milliseconds"); - let commitments = tx.utxo_commitments_created_hashes.clone(); + let commitments = tx.body.utxo_commitments_created_hashes.clone(); Ok(( self.sequencer_client.send_tx(tx, tx_roots).await?, @@ -1582,17 +1618,17 @@ impl NodeCore { Ok(()) } - ///Deposit balance, make it private - pub async fn subscenario_2(&mut self) -> Result<(), ExecutionFailureKind> { - let acc_addr = self.create_new_account().await; - - self.operate_account_deposit_public(acc_addr, 100).await?; - - self.operate_account_send_shielded_one_receiver(acc_addr, acc_addr, 100) - .await?; - - Ok(()) - } + // ///Deposit balance, make it private + // pub async fn subscenario_2(&mut self) -> Result<(), ExecutionFailureKind> { + // let acc_addr = self.create_new_account().await; + // + // self.operate_account_deposit_public(acc_addr, 100).await?; + // + // self.operate_account_send_shielded_one_receiver(acc_addr, acc_addr, 100) + // .await?; + // + // Ok(()) + // } ///Mint utxo, privately send it to another user pub async fn subscenario_3(&mut self) -> Result<(), ExecutionFailureKind> { @@ -1607,18 +1643,18 @@ impl NodeCore { Ok(()) } - ///Deposit balance, shielded send it to another user - pub async fn subscenario_4(&mut self) -> Result<(), ExecutionFailureKind> { - let acc_addr = self.create_new_account().await; - let acc_addr_rec = self.create_new_account().await; - - self.operate_account_deposit_public(acc_addr, 100).await?; - - self.operate_account_send_shielded_one_receiver(acc_addr, acc_addr_rec, 100) - .await?; - - Ok(()) - } + // ///Deposit balance, shielded send it to another user + // pub async fn subscenario_4(&mut self) -> Result<(), ExecutionFailureKind> { + // let acc_addr = self.create_new_account().await; + // let acc_addr_rec = self.create_new_account().await; + // + // self.operate_account_deposit_public(acc_addr, 100).await?; + // + // self.operate_account_send_shielded_one_receiver(acc_addr, acc_addr_rec, 100) + // .await?; + // + // Ok(()) + // } ///Mint utxo, deshielded send it to another user pub async fn subscenario_5(&mut self) -> Result<(), ExecutionFailureKind> { diff --git a/node_core/src/sequencer_client/json.rs b/node_core/src/sequencer_client/json.rs index b3ada03..9275ca5 100644 --- a/node_core/src/sequencer_client/json.rs +++ b/node_core/src/sequencer_client/json.rs @@ -1,11 +1,11 @@ -use common::transaction::TransactionBody; +use common::transaction::SignedTransaction; use serde::{Deserialize, Serialize}; //Requests #[derive(Serialize, Deserialize, Debug)] pub struct SendTxRequest { - pub transaction: TransactionBody, + pub transaction: SignedTransaction, ///UTXO Commitment Root, Pub Tx Root pub tx_roots: [[u8; 32]; 2], } diff --git a/node_core/src/sequencer_client/mod.rs b/node_core/src/sequencer_client/mod.rs index 3c96a85..95a3378 100644 --- a/node_core/src/sequencer_client/mod.rs +++ b/node_core/src/sequencer_client/mod.rs @@ -4,7 +4,7 @@ use common::rpc_primitives::requests::{ GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse, RegisterAccountRequest, RegisterAccountResponse, }; -use common::transaction::TransactionBody; +use common::transaction::SignedTransaction; use common::{SequencerClientError, SequencerRpcError}; use json::{SendTxRequest, SendTxResponse, SequencerRpcRequest, SequencerRpcResponse}; use k256::elliptic_curve::group::GroupEncoding; @@ -72,7 +72,7 @@ impl SequencerClient { pub async fn send_tx( &self, - transaction: TransactionBody, + transaction: SignedTransaction, tx_roots: [[u8; 32]; 2], ) -> Result { let tx_req = SendTxRequest { diff --git a/node_rpc/src/process.rs b/node_rpc/src/process.rs index f4937e9..a188ec8 100644 --- a/node_rpc/src/process.rs +++ b/node_rpc/src/process.rs @@ -42,7 +42,7 @@ pub const EXECUTE_SCENARIO_MULTIPLE_SEND: &str = "execute_scenario_multiple_send pub const SHOW_ACCOUNT_PUBLIC_BALANCE: &str = "show_account_public_balance"; pub const SHOW_ACCOUNT_UTXO: &str = "show_account_utxo"; pub const SHOW_TRANSACTION: &str = "show_transaction"; -pub const WRITE_DEPOSIT_PUBLIC_BALANCE: &str = "write_deposit_public_balance"; +// pub const WRITE_DEPOSIT_PUBLIC_BALANCE: &str = "write_deposit_public_balance"; pub const WRITE_MINT_UTXO: &str = "write_mint_utxo"; pub const WRITE_MINT_UTXO_MULTIPLE_ASSETS: &str = "write_mint_utxo_multiple_assets"; pub const WRITE_SEND_UTXO_PRIVATE: &str = "write_send_utxo_private"; @@ -84,18 +84,18 @@ impl JsonHandler { .subscenario_1() .await .map_err(cast_common_execution_error_into_rpc_error)?, - 2 => store - .subscenario_2() - .await - .map_err(cast_common_execution_error_into_rpc_error)?, + // 2 => store + // .subscenario_2() + // .await + // .map_err(cast_common_execution_error_into_rpc_error)?, 3 => store .subscenario_3() .await .map_err(cast_common_execution_error_into_rpc_error)?, - 4 => store - .subscenario_4() - .await - .map_err(cast_common_execution_error_into_rpc_error)?, + // 4 => store + // .subscenario_4() + // .await + // .map_err(cast_common_execution_error_into_rpc_error)?, 5 => store .subscenario_5() .await @@ -355,35 +355,35 @@ impl JsonHandler { respond(helperstruct) } - pub async fn process_write_deposit_public_balance( - &self, - request: Request, - ) -> Result { - let req = WriteDepositPublicBalanceRequest::parse(Some(request.params))?; - - let acc_addr_hex_dec = hex::decode(req.account_addr.clone()).map_err(|_| { - RpcError::parse_error("Failed to decode account address from hex string".to_string()) - })?; - - let acc_addr: [u8; 32] = acc_addr_hex_dec.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse account address from bytes".to_string()) - })?; - - { - let mut cover_guard = self.node_chain_store.lock().await; - - cover_guard - .operate_account_deposit_public(acc_addr, req.amount as u128) - .await - .map_err(cast_common_execution_error_into_rpc_error)?; - }; - - let helperstruct = WriteDepositPublicBalanceResponse { - status: SUCCESS.to_string(), - }; - - respond(helperstruct) - } + // pub async fn process_write_deposit_public_balance( + // &self, + // request: Request, + // ) -> Result { + // let req = WriteDepositPublicBalanceRequest::parse(Some(request.params))?; + // + // let acc_addr_hex_dec = hex::decode(req.account_addr.clone()).map_err(|_| { + // RpcError::parse_error("Failed to decode account address from hex string".to_string()) + // })?; + // + // let acc_addr: [u8; 32] = acc_addr_hex_dec.try_into().map_err(|_| { + // RpcError::parse_error("Failed to parse account address from bytes".to_string()) + // })?; + // + // { + // let mut cover_guard = self.node_chain_store.lock().await; + // + // cover_guard + // .operate_account_deposit_public(acc_addr, req.amount as u128) + // .await + // .map_err(cast_common_execution_error_into_rpc_error)?; + // }; + // + // let helperstruct = WriteDepositPublicBalanceResponse { + // status: SUCCESS.to_string(), + // }; + // + // respond(helperstruct) + // } pub async fn process_write_mint_utxo(&self, request: Request) -> Result { let req = WriteMintPrivateUTXORequest::parse(Some(request.params))?; @@ -777,9 +777,9 @@ impl JsonHandler { SHOW_ACCOUNT_PUBLIC_BALANCE => self.process_show_account_public_balance(request).await, SHOW_ACCOUNT_UTXO => self.process_show_account_utxo_request(request).await, SHOW_TRANSACTION => self.process_show_transaction(request).await, - WRITE_DEPOSIT_PUBLIC_BALANCE => { - self.process_write_deposit_public_balance(request).await - } + // WRITE_DEPOSIT_PUBLIC_BALANCE => { + // self.process_write_deposit_public_balance(request).await + // } WRITE_MINT_UTXO => self.process_write_mint_utxo(request).await, WRITE_MINT_UTXO_MULTIPLE_ASSETS => { self.process_write_mint_utxo_multiple_assets(request).await