rename structs. Implement serde for AuthenticatedTransaction

This commit is contained in:
Sergio Chouhy 2025-07-14 08:45:38 -03:00
parent a174eb4b85
commit f02c97e622
13 changed files with 99 additions and 66 deletions

View File

@ -1,7 +1,7 @@
use rs_merkle::Hasher;
use serde::{Deserialize, Serialize};
use crate::{merkle_tree_public::hasher::OwnHasher, transaction::Transaction};
use crate::{merkle_tree_public::hasher::OwnHasher, transaction::TransactionBody};
pub type BlockHash = [u8; 32];
pub type Data = Vec<u8>;
@ -13,7 +13,7 @@ pub struct Block {
pub prev_block_id: BlockId,
pub prev_block_hash: BlockHash,
pub hash: BlockHash,
pub transactions: Vec<Transaction>,
pub transactions: Vec<TransactionBody>,
pub data: Data,
}
@ -22,7 +22,7 @@ pub struct HashableBlockData {
pub block_id: BlockId,
pub prev_block_id: BlockId,
pub prev_block_hash: BlockHash,
pub transactions: Vec<Transaction>,
pub transactions: Vec<TransactionBody>,
pub data: Data,
}

View File

@ -7,7 +7,7 @@ use serde::{
Deserialize, Deserializer, Serialize,
};
use crate::{transaction::Transaction, utxo_commitment::UTXOCommitment};
use crate::{transaction::TransactionBody, utxo_commitment::UTXOCommitment};
use super::{hasher::OwnHasher, tree_leav_item::TreeLeavItem, TreeHashType};
@ -81,7 +81,7 @@ impl<'de, Leav: TreeLeavItem + Clone + Deserialize<'de>> serde::Deserialize<'de>
}
}
pub type PublicTransactionMerkleTree = HashStorageMerkleTree<Transaction>;
pub type PublicTransactionMerkleTree = HashStorageMerkleTree<TransactionBody>;
pub type UTXOCommitmentsMerkleTree = HashStorageMerkleTree<UTXOCommitment>;

View File

@ -1,4 +1,4 @@
use crate::{transaction::Transaction, utxo_commitment::UTXOCommitment};
use crate::{transaction::TransactionBody, utxo_commitment::UTXOCommitment};
use super::TreeHashType;
@ -6,7 +6,7 @@ pub trait TreeLeavItem {
fn hash(&self) -> TreeHashType;
}
impl TreeLeavItem for Transaction {
impl TreeLeavItem for TransactionBody {
fn hash(&self) -> TreeHashType {
self.hash()
}

View File

@ -1,6 +1,6 @@
use crate::block::Block;
use crate::parse_request;
use crate::transaction::Transaction;
use crate::transaction::TransactionBody;
use super::errors::RpcParseError;
use super::parser::parse_params;
@ -20,7 +20,7 @@ pub struct RegisterAccountRequest {
#[derive(Serialize, Deserialize, Debug)]
pub struct SendTxRequest {
pub transaction: Transaction,
pub transaction: TransactionBody,
///UTXO Commitment Root, Pub Tx Root
pub tx_roots: [[u8; 32]; 2],
}

View File

@ -25,7 +25,7 @@ pub enum TxKind {
#[derive(Debug, Serialize, Deserialize, Clone)]
///General transaction object
pub struct Transaction {
pub struct TransactionBody {
pub tx_kind: TxKind,
///Tx input data (public part)
pub execution_input: Vec<u8>,
@ -58,22 +58,25 @@ pub struct Transaction {
}
#[derive(Serialize, Deserialize)]
struct TransactionSignature {}
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 UnverifiedSignedTransaction {
transaction: Transaction,
signature: TransactionSignature
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 VerifiedSignedTransaction {
transaction: Transaction,
signature: TransactionSignature
pub struct AuthenticatedTransaction {
hash: TransactionHash,
signed_tx: SignedTransaction
}
#[derive(Debug, Serialize, Deserialize)]
@ -172,7 +175,7 @@ impl ActionData {
type SignaturePrivateKey = Scalar;
type SignaturePublicKey = PublicKey;
impl Transaction {
impl TransactionBody {
/// 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
@ -184,11 +187,14 @@ impl Transaction {
TreeHashType::from(hasher.finalize_fixed())
}
pub fn sign(self, _private_key: SignaturePrivateKey) -> UnverifiedSignedTransaction {
pub fn sign(self, _private_key: SignaturePrivateKey) -> SignedTransaction {
let _hash = self.hash();
// Implement actual signature over `hash`
let signature = TransactionSignature {};
UnverifiedSignedTransaction { transaction: self, signature }
SignedTransaction {
body: self,
signature,
}
}
pub fn log(&self) {
@ -243,11 +249,38 @@ impl Transaction {
}
}
impl UnverifiedSignedTransaction {
pub fn into_verified(self) -> VerifiedSignedTransaction {
let hash = self.transaction.hash();
impl SignedTransaction {
pub fn into_authenticated(self) -> AuthenticatedTransaction {
let hash = TransactionHash; // self.body.hash();
// Check signature over hash
todo!()
AuthenticatedTransaction {
hash,
signed_tx: self
}
}
}
impl AuthenticatedTransaction {
pub fn as_signed(&self) -> &SignedTransaction {
&self.signed_tx
}
}
impl Serialize for AuthenticatedTransaction {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.as_signed().serialize(serializer)
}
}
impl<'de> Deserialize<'de> for AuthenticatedTransaction {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
SignedTransaction::deserialize(deserializer).map(|signed_tx| signed_tx.into_authenticated())
}
}
@ -258,12 +291,12 @@ mod tests {
use crate::{
merkle_tree_public::TreeHashType,
transaction::{Transaction, TxKind},
transaction::{TransactionBody, TxKind},
};
#[test]
fn test_transaction_hash_is_sha256_of_json_bytes() {
let tx = Transaction {
let tx = TransactionBody {
tx_kind: TxKind::Public,
execution_input: vec![1, 2, 3, 4],
execution_output: vec![5, 6, 7, 8],

View File

@ -6,7 +6,7 @@ use anyhow::{anyhow, Result};
use common::block::Block;
use common::merkle_tree_public::merkle_tree::HashStorageMerkleTree;
use common::nullifier::UTXONullifier;
use common::transaction::Transaction;
use common::transaction::TransactionBody;
use common::utxo_commitment::UTXOCommitment;
use log::error;
use storage::sc_db_utils::{DataBlob, DataBlobChangeVariant};
@ -87,7 +87,7 @@ impl NodeBlockStore {
)?)
}
pub fn get_snapshot_transaction(&self) -> Result<HashStorageMerkleTree<Transaction>> {
pub fn get_snapshot_transaction(&self) -> Result<HashStorageMerkleTree<TransactionBody>> {
Ok(serde_json::from_slice(
&self.dbio.get_snapshot_transaction()?,
)?)

View File

@ -278,7 +278,7 @@ mod tests {
use accounts::account_core::Account;
use common::block::{Block, Data};
use common::merkle_tree_public::TreeHashType;
use common::transaction::{Transaction, TxKind};
use common::transaction::{TransactionBody, TxKind};
use secp256k1_zkp::Tweak;
use std::path::PathBuf;
use tempfile::tempdir;
@ -300,10 +300,10 @@ mod tests {
nullifier_created_hashes: Vec<[u8; 32]>,
utxo_commitments_spent_hashes: Vec<[u8; 32]>,
utxo_commitments_created_hashes: Vec<[u8; 32]>,
) -> Transaction {
) -> TransactionBody {
let mut rng = rand::thread_rng();
Transaction {
TransactionBody {
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: vec![],

View File

@ -8,7 +8,7 @@ use common::ExecutionFailureKind;
use accounts::account_core::{Account, AccountAddress};
use anyhow::Result;
use chain_storage::NodeChainStore;
use common::transaction::{Transaction, TxKind};
use common::transaction::{TransactionBody, TxKind};
use config::NodeConfig;
use log::info;
use sc_core::proofs_circuits::{
@ -189,7 +189,7 @@ impl NodeCore {
&self,
acc: AccountAddress,
amount: u128,
) -> Result<(Transaction, [u8; 32]), ExecutionFailureKind> {
) -> Result<(TransactionBody, [u8; 32]), ExecutionFailureKind> {
let (utxo, receipt) = prove_mint_utxo(amount, acc)?;
let result_hash = utxo.hash;
@ -246,7 +246,7 @@ impl NodeCore {
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
Ok((
Transaction {
TransactionBody {
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: vec![],
@ -278,7 +278,7 @@ impl NodeCore {
acc: AccountAddress,
amount: u128,
number_of_assets: usize,
) -> Result<(Transaction, Vec<[u8; 32]>), ExecutionFailureKind> {
) -> Result<(TransactionBody, 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();
@ -343,7 +343,7 @@ impl NodeCore {
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
Ok((
Transaction {
TransactionBody {
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: vec![],
@ -375,7 +375,7 @@ impl NodeCore {
utxo: UTXO,
commitment_in: [u8; 32],
receivers: Vec<(u128, AccountAddress)>,
) -> Result<(Transaction, Vec<(AccountAddress, [u8; 32])>), ExecutionFailureKind> {
) -> Result<(TransactionBody, 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();
@ -459,7 +459,7 @@ impl NodeCore {
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
Ok((
Transaction {
TransactionBody {
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: vec![],
@ -492,7 +492,7 @@ impl NodeCore {
commitments_in: Vec<[u8; 32]>,
number_to_send: usize,
receiver: AccountAddress,
) -> Result<(Transaction, Vec<[u8; 32]>, Vec<[u8; 32]>), ExecutionFailureKind> {
) -> Result<(TransactionBody, 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();
@ -604,7 +604,7 @@ impl NodeCore {
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
Ok((
Transaction {
TransactionBody {
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: vec![],
@ -637,7 +637,7 @@ impl NodeCore {
acc: AccountAddress,
balance: u64,
receivers: Vec<(u128, AccountAddress)>,
) -> Result<(Transaction, Vec<(AccountAddress, [u8; 32])>), ExecutionFailureKind> {
) -> Result<(TransactionBody, 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();
@ -727,7 +727,7 @@ impl NodeCore {
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
Ok((
Transaction {
TransactionBody {
tx_kind: TxKind::Shielded,
execution_input: serde_json::to_vec(&ActionData::SendMoneyShieldedTx(
SendMoneyShieldedTx {
@ -765,7 +765,7 @@ impl NodeCore {
utxo: UTXO,
comm_gen_hash: [u8; 32],
receivers: Vec<(u128, AccountAddress)>,
) -> Result<Transaction, ExecutionFailureKind> {
) -> Result<TransactionBody, ExecutionFailureKind> {
let acc_map_read_guard = self.storage.read().await;
let commitment_in = acc_map_read_guard
@ -820,7 +820,7 @@ impl NodeCore {
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
Ok(Transaction {
Ok(TransactionBody {
tx_kind: TxKind::Deshielded,
execution_input: serde_json::to_vec(&ActionData::SendMoneyDeshieldedTx(
SendMoneyDeshieldedTx {
@ -924,7 +924,7 @@ impl NodeCore {
let new_len = 0;
let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len);
let tx: Transaction =
let tx: TransactionBody =
sc_core::transaction_payloads_tools::create_public_transaction_payload(
serde_json::to_vec(&ActionData::MintMoneyPublicTx(MintMoneyPublicTx {
acc,
@ -1361,7 +1361,7 @@ impl NodeCore {
commitment_in: [u8; 32],
receivers: Vec<(u128, AccountAddress)>,
visibility_list: [bool; 3],
) -> Result<(Transaction, Vec<(AccountAddress, [u8; 32])>), ExecutionFailureKind> {
) -> Result<(TransactionBody, 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();
@ -1459,7 +1459,7 @@ impl NodeCore {
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
Ok((
Transaction {
TransactionBody {
tx_kind: TxKind::Shielded,
execution_input: vec![],
execution_output: serde_json::to_vec(&publication).unwrap(),

View File

@ -1,11 +1,11 @@
use common::transaction::Transaction;
use common::transaction::TransactionBody;
use serde::{Deserialize, Serialize};
//Requests
#[derive(Serialize, Deserialize, Debug)]
pub struct SendTxRequest {
pub transaction: Transaction,
pub transaction: TransactionBody,
///UTXO Commitment Root, Pub Tx Root
pub tx_roots: [[u8; 32]; 2],
}

View File

@ -4,7 +4,7 @@ use common::rpc_primitives::requests::{
GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse,
RegisterAccountRequest, RegisterAccountResponse,
};
use common::transaction::Transaction;
use common::transaction::TransactionBody;
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: Transaction,
transaction: TransactionBody,
tx_roots: [[u8; 32]; 2],
) -> Result<SendTxResponse, SequencerClientError> {
let tx_req = SendTxRequest {

View File

@ -1,6 +1,6 @@
use accounts::account_core::Account;
use anyhow::Result;
use common::transaction::{Transaction, TxKind};
use common::transaction::{TransactionBody, 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),
) -> Transaction {
Transaction {
) -> TransactionBody {
TransactionBody {
tx_kind: TxKind::Public,
execution_input,
execution_output: vec![],

View File

@ -5,7 +5,7 @@ use common::{
block::{Block, HashableBlockData},
merkle_tree_public::TreeHashType,
nullifier::UTXONullifier,
transaction::{Transaction, TxKind},
transaction::{TransactionBody, TxKind},
utxo_commitment::UTXOCommitment,
};
use config::SequencerConfig;
@ -71,10 +71,10 @@ impl SequencerCore {
pub fn transaction_pre_check(
&mut self,
tx: &Transaction,
tx: &TransactionBody,
tx_roots: [[u8; 32]; 2],
) -> Result<(), TransactionMalformationErrorKind> {
let Transaction {
let TransactionBody {
tx_kind,
ref execution_input,
ref execution_output,
@ -188,7 +188,7 @@ impl SequencerCore {
&mut self,
tx: TransactionMempool,
) -> Result<(), TransactionMalformationErrorKind> {
let Transaction {
let TransactionBody {
ref utxo_commitments_created_hashes,
ref nullifier_created_hashes,
..
@ -259,7 +259,7 @@ mod tests {
use super::*;
use std::path::PathBuf;
use common::transaction::{Transaction, TxKind};
use common::transaction::{TransactionBody, TxKind};
use rand::Rng;
use secp256k1_zkp::Tweak;
use transaction_mempool::TransactionMempool;
@ -285,10 +285,10 @@ mod tests {
nullifier_created_hashes: Vec<[u8; 32]>,
utxo_commitments_spent_hashes: Vec<[u8; 32]>,
utxo_commitments_created_hashes: Vec<[u8; 32]>,
) -> Transaction {
) -> TransactionBody {
let mut rng = rand::thread_rng();
Transaction {
TransactionBody {
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: vec![],

View File

@ -1,14 +1,14 @@
use common::{merkle_tree_public::TreeHashType, transaction::Transaction};
use common::{merkle_tree_public::TreeHashType, transaction::TransactionBody};
use mempool::mempoolitem::MemPoolItem;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone)]
pub struct TransactionMempool {
pub tx: Transaction,
pub tx: TransactionBody,
}
impl From<Transaction> for TransactionMempool {
fn from(value: Transaction) -> Self {
impl From<TransactionBody> for TransactionMempool {
fn from(value: TransactionBody) -> Self {
Self { tx: value }
}
}
@ -27,7 +27,7 @@ impl<'de> Deserialize<'de> for TransactionMempool {
where
D: serde::Deserializer<'de>,
{
match Transaction::deserialize(deserializer) {
match TransactionBody::deserialize(deserializer) {
Ok(tx) => Ok(TransactionMempool { tx }),
Err(err) => Err(err),
}