Merge branch 'main' into schouhy/add-clippy-to-ci

This commit is contained in:
Oleksandr Pravdyvyi 2025-07-23 15:41:53 +03:00
commit 0f82c0ec05
No known key found for this signature in database
GPG Key ID: 9F8955C63C443871
6 changed files with 66 additions and 80 deletions

View File

@ -8,7 +8,7 @@ pub trait TreeLeavItem {
impl TreeLeavItem for Transaction {
fn hash(&self) -> TreeHashType {
self.hash
self.hash()
}
}

View File

@ -26,7 +26,6 @@ pub enum TxKind {
#[derive(Debug, Serialize, Deserialize, Clone)]
///General transaction object
pub struct Transaction {
pub hash: TreeHashType,
pub tx_kind: TxKind,
///Tx input data (public part)
pub execution_input: Vec<u8>,
@ -58,70 +57,6 @@ pub struct Transaction {
pub state_changes: (serde_json::Value, usize),
}
#[derive(Debug, Serialize, Deserialize, Clone)]
///General transaction object
pub struct TransactionPayload {
pub tx_kind: TxKind,
///Tx input data (public part)
pub execution_input: Vec<u8>,
///Tx output data (public_part)
pub execution_output: Vec<u8>,
///Tx input utxo commitments
pub utxo_commitments_spent_hashes: Vec<TreeHashType>,
///Tx output utxo commitments
pub utxo_commitments_created_hashes: Vec<TreeHashType>,
///Tx output nullifiers
pub nullifier_created_hashes: Vec<TreeHashType>,
///Execution proof (private part)
pub execution_proof_private: String,
///Encoded blobs of data
pub encoded_data: Vec<(CipherText, Vec<u8>, Tag)>,
///Transaction senders ephemeral pub key
pub ephemeral_pub_key: Vec<u8>,
///Public (Pedersen) commitment
pub commitment: Vec<PedersenCommitment>,
///tweak
pub tweak: Tweak,
///secret_r
pub secret_r: [u8; 32],
///Hex-encoded address of a smart contract account called
pub sc_addr: String,
///Recorded changes in state of smart contract
///
/// First value represents vector of changes, second is new length of a state
pub state_changes: (serde_json::Value, usize),
}
impl From<TransactionPayload> for Transaction {
fn from(value: TransactionPayload) -> Self {
let raw_data = serde_json::to_vec(&value).unwrap();
let mut hasher = sha2::Sha256::new();
hasher.update(&raw_data);
let hash = <TreeHashType>::from(hasher.finalize_fixed());
Self {
hash,
tx_kind: value.tx_kind,
execution_input: value.execution_input,
execution_output: value.execution_output,
utxo_commitments_spent_hashes: value.utxo_commitments_spent_hashes,
utxo_commitments_created_hashes: value.utxo_commitments_created_hashes,
nullifier_created_hashes: value.nullifier_created_hashes,
execution_proof_private: value.execution_proof_private,
encoded_data: value.encoded_data,
ephemeral_pub_key: value.ephemeral_pub_key,
commitment: value.commitment,
tweak: value.tweak,
secret_r: value.secret_r,
sc_addr: value.sc_addr,
state_changes: value.state_changes,
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct MintMoneyPublicTx {
pub acc: [u8; 32],
@ -216,8 +151,19 @@ impl ActionData {
}
impl Transaction {
/// Computes and returns the SHA-256 hash of the JSON-serialized representation of `self`.
pub fn hash(&self) -> TreeHashType {
// TODO: Remove `unwrap` by implementing a `to_bytes` method
// that deterministically encodes all transaction fields to bytes
// and guarantees serialization will succeed.
let raw_data = serde_json::to_vec(&self).unwrap();
let mut hasher = sha2::Sha256::new();
hasher.update(&raw_data);
TreeHashType::from(hasher.finalize_fixed())
}
pub fn log(&self) {
info!("Transaction hash is {:?}", hex::encode(self.hash));
info!("Transaction hash is {:?}", hex::encode(self.hash()));
info!("Transaction tx_kind is {:?}", self.tx_kind);
info!("Transaction execution_input is {:?}", {
if let Ok(action) = serde_json::from_slice::<ActionData>(&self.execution_input) {
@ -267,3 +213,44 @@ impl Transaction {
);
}
}
#[cfg(test)]
mod tests {
use secp256k1_zkp::{constants::SECRET_KEY_SIZE, Tweak};
use sha2::{digest::FixedOutput, Digest};
use crate::{
merkle_tree_public::TreeHashType,
transaction::{Transaction, TxKind},
};
#[test]
fn test_transaction_hash_is_sha256_of_json_bytes() {
let tx = Transaction {
tx_kind: TxKind::Public,
execution_input: vec![1, 2, 3, 4],
execution_output: vec![5, 6, 7, 8],
utxo_commitments_spent_hashes: vec![[9; 32], [10; 32], [11; 32], [12; 32]],
utxo_commitments_created_hashes: vec![[13; 32]],
nullifier_created_hashes: vec![[0; 32], [1; 32], [2; 32], [3; 32]],
execution_proof_private: "loremipsum".to_string(),
encoded_data: vec![(vec![255, 255, 255], vec![254, 254, 254], 1)],
ephemeral_pub_key: vec![5; 32],
commitment: vec![],
tweak: Tweak::from_slice(&[7; SECRET_KEY_SIZE]).unwrap(),
secret_r: [8; 32],
sc_addr: "someAddress".to_string(),
state_changes: (serde_json::Value::Null, 10),
};
let expected_hash = {
let data = serde_json::to_vec(&tx).unwrap();
let mut hasher = sha2::Sha256::new();
hasher.update(&data);
TreeHashType::from(hasher.finalize_fixed())
};
let hash = tx.hash();
assert_eq!(expected_hash, hash);
}
}

View File

@ -308,7 +308,6 @@ mod tests {
let mut rng = rand::thread_rng();
Transaction {
hash,
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: vec![],

View File

@ -11,7 +11,7 @@ use accounts::{
};
use anyhow::Result;
use chain_storage::NodeChainStore;
use common::transaction::{Transaction, TransactionPayload, TxKind};
use common::transaction::{Transaction, TxKind};
use config::NodeConfig;
use log::info;
use sc_core::proofs_circuits::{
@ -250,7 +250,7 @@ impl NodeCore {
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
Ok((
TransactionPayload {
Transaction {
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: vec![],
@ -346,7 +346,7 @@ impl NodeCore {
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
Ok((
TransactionPayload {
Transaction {
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: vec![],
@ -460,7 +460,7 @@ impl NodeCore {
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
Ok((
TransactionPayload {
Transaction {
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: vec![],
@ -604,7 +604,7 @@ impl NodeCore {
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
Ok((
TransactionPayload {
Transaction {
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: vec![],
@ -725,7 +725,7 @@ impl NodeCore {
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
Ok((
TransactionPayload {
Transaction {
tx_kind: TxKind::Shielded,
execution_input: serde_json::to_vec(&ActionData::SendMoneyShieldedTx(
SendMoneyShieldedTx {
@ -816,7 +816,7 @@ impl NodeCore {
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
Ok(TransactionPayload {
Ok(Transaction {
tx_kind: TxKind::Deshielded,
execution_input: serde_json::to_vec(&ActionData::SendMoneyDeshieldedTx(
SendMoneyDeshieldedTx {
@ -1453,7 +1453,7 @@ impl NodeCore {
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
Ok((
TransactionPayload {
Transaction {
tx_kind: TxKind::Shielded,
execution_input: vec![],
execution_output: serde_json::to_vec(&publication).unwrap(),

View File

@ -1,6 +1,6 @@
use accounts::{account_core::Account, key_management::ephemeral_key_holder::EphemeralKeyHolder};
use anyhow::Result;
use common::transaction::{TransactionPayload, TxKind};
use common::transaction::{Transaction, TxKind};
use rand::thread_rng;
use risc0_zkvm::Receipt;
use secp256k1_zkp::{CommitmentSecrets, PedersenCommitment, Tweak};
@ -15,8 +15,8 @@ pub fn create_public_transaction_payload(
secret_r: [u8; 32],
sc_addr: String,
state_changes: (serde_json::Value, usize),
) -> TransactionPayload {
TransactionPayload {
) -> Transaction {
Transaction {
tx_kind: TxKind::Public,
execution_input,
execution_output: vec![],

View File

@ -38,6 +38,6 @@ impl MemPoolItem for TransactionMempool {
type Identifier = TreeHashType;
fn identifier(&self) -> Self::Identifier {
self.tx.hash
self.tx.hash()
}
}