fix: block interfix

This commit is contained in:
Oleksandr Pravdyvyi 2025-09-02 11:06:41 +03:00
parent 211b6f9115
commit 6efac43210
No known key found for this signature in database
GPG Key ID: 9F8955C63C443871
7 changed files with 168 additions and 33 deletions

View File

@ -4,7 +4,6 @@ use k256::ecdsa::Signature;
use rs_merkle::Hasher;
use crate::{merkle_tree_public::hasher::OwnHasher, transaction::AuthenticatedTransaction};
use nssa;
pub type BlockHash = [u8; 32];
pub type BlockId = u64;
@ -101,11 +100,18 @@ impl HashableBlockData {
let mut prev_block_hash = [0u8; 32];
cursor.read_exact(&mut prev_block_hash).unwrap();
let timestamp = u64_from_cursor(&mut cursor);
let signature_bytes_len = u32_from_cursor(&mut cursor) as usize;
let mut signature_bytes = Vec::with_capacity(signature_bytes_len);
cursor.read_exact(&mut signature_bytes).unwrap();
let signature = Signature::from_bytes(signature_bytes.as_slice().try_into().unwrap()).unwrap();
let num_transactions = u32_from_cursor(&mut cursor) as usize;
let mut transactions = Vec::with_capacity(num_transactions);
for _ in 0..num_transactions {
let tx = nssa::PublicTransaction::from_cursor(&mut cursor).unwrap();
let tx = AuthenticatedTransaction::from_cursor(&mut cursor);
transactions.push(tx);
}
@ -113,6 +119,8 @@ impl HashableBlockData {
block_id,
prev_block_id,
prev_block_hash,
timestamp,
signature,
transactions,
}
}

View File

@ -1,6 +1,8 @@
use nssa;
use k256::{ecdsa::{signature::SignerMut, SigningKey}, FieldBytes};
use nssa::{self, NSSATransaction};
use rand::rngs::OsRng;
use crate::block::{Block, HashableBlockData};
use crate::{block::{Block, HashableBlockData}, transaction::{Transaction, TransactionBody}};
//Dummy producers
@ -16,10 +18,25 @@ pub fn produce_dummy_block(
prev_hash: Option<[u8; 32]>,
transactions: Vec<nssa::PublicTransaction>,
) -> Block {
let transactions = transactions.into_iter().map(
|tx| {
let tx_body = TransactionBody::from(NSSATransaction::Public(tx));
//ToDo: Fix signing key
let transaction = Transaction::new(tx_body, SigningKey::random(&mut OsRng));
transaction.into_authenticated().unwrap()
}).collect();
//ToDo: Fix signature
let key_bytes = FieldBytes::from_slice(&[37; 32]);
let mut private_key: SigningKey = SigningKey::from_bytes(key_bytes).unwrap();
let signature = private_key.sign(&[1; 32]);
let block_data = HashableBlockData {
block_id: id,
prev_block_id: id.saturating_sub(1),
prev_block_hash: prev_hash.unwrap_or_default(),
timestamp: 0,
signature,
transactions,
};

View File

@ -1,16 +1,15 @@
use std::io::Cursor;
use std::io::{Cursor, Read};
use k256::ecdsa::{
signature::{Signer, Verifier},
Signature, SigningKey, VerifyingKey,
};
use log::info;
use secp256k1_zkp::{PedersenCommitment, Tweak};
use serde::{Deserialize, Serialize};
use sha2::{digest::FixedOutput, Digest};
use crate::merkle_tree_public::TreeHashType;
use crate::{block::u32_from_cursor, merkle_tree_public::TreeHashType};
use elliptic_curve::{
consts::{B0, B1},
@ -181,16 +180,13 @@ impl TransactionBody {
serde_json::to_vec(&self).unwrap()
}
fn from_bytes(bytes: Vec<u8>) -> Self {
serde_json::from_slice(&bytes).unwrap()
}
pub fn log(&self) {
info!("Transaction hash is {:?}", hex::encode(self.hash()));
info!("Transaction tx_kind is {:?}", self.tx_kind);
info!(
"Transaction encoded_data is {:?}",
self.encoded_data
.iter()
.map(|val| (hex::encode(val.0.clone()), hex::encode(val.1.clone())))
.collect::<Vec<_>>()
);
}
}
@ -257,26 +253,33 @@ impl Transaction {
bytes.extend_from_slice(&signature_bytes_len.to_le_bytes());
bytes.extend_from_slice(&public_key_bytes_len.to_le_bytes());
bytes.extend_from_slice(&self.body.to_bytes());
bytes.extend_from_slice(&self.signature.to_bytes());
bytes.extend_from_slice(&self.public_key.to_sec1_bytes());
bytes.extend_from_slice(&body_bytes);
bytes.extend_from_slice(&signature_bytes);
bytes.extend_from_slice(&public_key_bytes);
bytes
}
// TODO: Improve error handling. Remove unwraps.
pub fn from_bytes(data: &[u8]) -> Self {
let mut cursor = Cursor::new(data);
pub fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Self {
let body_bytes_len = u32_from_cursor(cursor) as usize;
let signature_bytes_len = u32_from_cursor(cursor) as usize;
let public_key_bytes_len = u32_from_cursor(cursor) as usize;
let body_bytes_len = u32_from_cursor(&mut cursor) as usize;
let signature_bytes_len = u32_from_cursor(&mut cursor) as usize;
let public_key_bytes_len = u32_from_cursor(&mut cursor) as usize;
let mut body_bytes = Vec::with_capacity(body_bytes_len);
let mut signature_bytes = Vec::with_capacity(signature_bytes_len);
let mut public_key_bytes = Vec::with_capacity(public_key_bytes_len);
let body_bytes = Vec::with_capacity(body_bytes_len);
let signature_bytes = Vec::with_capacity(signature_bytes_len);
let public_key_bytes = Vec::with_capacity(public_key_bytes_len);
cursor.read_exact(&mut body_bytes).unwrap();
let body = TransactionBody::from_bytes(body_bytes);
cursor.read_exact(&mut signature_bytes).unwrap();
let signature = Signature::from_bytes(signature_bytes.as_slice().try_into().unwrap()).unwrap();
cursor.read_exact(&mut public_key_bytes).unwrap();
let public_key = VerifyingKey::from_sec1_bytes(&public_key_bytes).unwrap();
Self { body, signature, public_key }
}
}
@ -312,13 +315,20 @@ impl AuthenticatedTransaction {
bytes.extend_from_slice(&self.transaction.to_bytes());
bytes
}
// TODO: Improve error handling. Remove unwraps.
pub fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Self {
let mut hash: [u8; 32] = [0; 32];
cursor.read_exact(&mut hash).unwrap();
let transaction = Transaction::from_cursor(cursor);
Self { hash, transaction }
}
}
#[cfg(test)]
mod tests {
use super::*;
use k256::{ecdsa::signature::Signer, FieldBytes};
use secp256k1_zkp::{constants::SECRET_KEY_SIZE, Tweak};
use sha2::{digest::FixedOutput, Digest};
use crate::{

View File

@ -1,5 +1,7 @@
use std::{fmt::Display, str::FromStr};
use serde::{Deserialize, Serialize};
use crate::signature::PublicKey;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
@ -57,6 +59,28 @@ impl Display for Address {
}
}
impl Serialize for Address {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let hex_string = self.to_string();
hex_string.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Address {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let hex_string = String::deserialize(deserializer)?;
Address::from_str(&hex_string).map_err(serde::de::Error::custom)
}
}
#[cfg(test)]
mod tests {
use crate::{Address, address::AddressError};

View File

@ -1,3 +1,5 @@
use std::io::{Cursor, Read};
use nssa_core::{
MembershipProof, NullifierPublicKey, NullifierSecretKey, PrivacyPreservingCircuitInput,
PrivacyPreservingCircuitOutput, SharedSecretKey,
@ -20,6 +22,28 @@ impl Proof {
let receipt = Receipt::new(inner, circuit_output.to_bytes());
receipt.verify(PRIVACY_PRESERVING_CIRCUIT_ID).is_ok()
}
pub fn to_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
let proof_len = self.0.len() as u32;
bytes.extend_from_slice(&proof_len.to_le_bytes());
bytes.extend_from_slice(&self.0);
bytes
}
pub fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result<Self, NssaError> {
let proof_len = u32_from_cursor(cursor) as usize;
let mut proof = Vec::with_capacity(proof_len);
cursor.read_exact(&mut proof)?;
Ok(Self(proof))
}
}
// TODO: Improve error handling. Remove unwraps.
pub fn u32_from_cursor(cursor: &mut Cursor<&[u8]>) -> u32 {
let mut word_buf = [0u8; 4];
cursor.read_exact(&mut word_buf).unwrap();
u32::from_le_bytes(word_buf)
}
/// Generates a proof of the execution of a NSSA program inside the privacy preserving execution

View File

@ -7,7 +7,7 @@ use nssa_core::{
};
use crate::{
Address, error::NssaError, privacy_preserving_transaction::message::EncryptedAccountData,
error::NssaError, privacy_preserving_transaction::{circuit::Proof, message::EncryptedAccountData, witness_set::WitnessSet}, Address, PrivacyPreservingTransaction, PublicKey, Signature
};
use super::message::Message;
@ -168,3 +168,55 @@ impl Message {
})
}
}
impl WitnessSet {
pub(crate) fn to_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
let size = self.signatures_and_public_keys().len() as u32;
bytes.extend_from_slice(&size.to_le_bytes());
for (signature, public_key) in self.signatures_and_public_keys() {
bytes.extend_from_slice(signature.to_bytes());
bytes.extend_from_slice(public_key.to_bytes());
}
bytes.extend_from_slice(&self.proof.to_bytes());
bytes
}
pub(crate) fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result<Self, NssaError> {
let num_signatures: u32 = {
let mut buf = [0u8; 4];
cursor.read_exact(&mut buf)?;
u32::from_le_bytes(buf)
};
let mut signatures_and_public_keys = Vec::with_capacity(num_signatures as usize);
for _i in 0..num_signatures {
let signature = Signature::from_cursor(cursor)?;
let public_key = PublicKey::from_cursor(cursor)?;
signatures_and_public_keys.push((signature, public_key))
}
let proof = Proof::from_cursor(cursor)?;
Ok(Self {
signatures_and_public_keys,
proof,
})
}
}
impl PrivacyPreservingTransaction {
pub fn to_bytes(&self) -> Vec<u8> {
let mut bytes = self.message().to_bytes();
bytes.extend_from_slice(&self.witness_set().to_bytes());
bytes
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, NssaError> {
let mut cursor = Cursor::new(bytes);
Self::from_cursor(&mut cursor)
}
pub fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result<Self, NssaError> {
let message = Message::from_cursor(cursor)?;
let witness_set = WitnessSet::from_cursor(cursor)?;
Ok(PrivacyPreservingTransaction::new(message, witness_set))
}
}

View File

@ -92,7 +92,7 @@ impl RocksDBIO {
if is_start_set {
Ok(dbio)
} else if let Some(block) = start_block {
let block_id = block.block_id;
let block_id = block.header.block_id;
dbio.put_meta_first_block_in_db(block)?;
dbio.put_meta_is_first_block_set()?;
@ -186,7 +186,7 @@ impl RocksDBIO {
.put_cf(
&cf_meta,
DB_META_FIRST_BLOCK_IN_DB_KEY.as_bytes(),
block.block_id.to_be_bytes(),
block.header.block_id.to_be_bytes(),
)
.map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?;
@ -233,15 +233,15 @@ impl RocksDBIO {
if !first {
let last_curr_block = self.get_meta_last_block_in_db()?;
if block.block_id > last_curr_block {
self.put_meta_last_block_in_db(block.block_id)?;
if block.header.block_id > last_curr_block {
self.put_meta_last_block_in_db(block.header.block_id)?;
}
}
self.db
.put_cf(
&cf_block,
block.block_id.to_be_bytes(),
block.header.block_id.to_be_bytes(),
HashableBlockData::from(block).to_bytes(),
)
.map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?;