mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
split mega tx.rs file into subfiles inside tx module
This commit is contained in:
10
src/crypto/nullifier.rs
Normal file
10
src/crypto/nullifier.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
pub struct Nullifier {
|
||||
pub repr: [u8; 32],
|
||||
}
|
||||
|
||||
impl Nullifier {
|
||||
pub fn new(repr: [u8; 32]) -> Self {
|
||||
Self { repr }
|
||||
}
|
||||
}
|
||||
|
||||
194
src/tx/builder.rs
Normal file
194
src/tx/builder.rs
Normal file
@@ -0,0 +1,194 @@
|
||||
use bellman::groth16;
|
||||
use bls12_381::Bls12;
|
||||
use rand::rngs::OsRng;
|
||||
use std::collections::HashMap;
|
||||
use std::io;
|
||||
use ff::Field;
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use crate::serial::{Decodable, Encodable, VarInt};
|
||||
use super::{TransactionClearInput, TransactionInput, TransactionOutput, Transaction, partial::{PartialTransactionClearInput, PartialTransactionInput, PartialTransaction}};
|
||||
use crate::crypto::{
|
||||
coin::Coin,
|
||||
create_mint_proof, create_spend_proof, load_params,
|
||||
merkle::CommitmentTree,
|
||||
note::{EncryptedNote, Note},
|
||||
save_params, schnorr, setup_mint_prover, setup_spend_prover, verify_mint_proof,
|
||||
verify_spend_proof, MintRevealedValues, SpendRevealedValues,
|
||||
};
|
||||
|
||||
pub struct TransactionBuilder {
|
||||
pub clear_inputs: Vec<TransactionBuilderClearInputInfo>,
|
||||
pub inputs: Vec<TransactionBuilderInputInfo>,
|
||||
pub outputs: Vec<TransactionBuilderOutputInfo>,
|
||||
}
|
||||
|
||||
pub struct TransactionBuilderClearInputInfo {
|
||||
pub value: u64,
|
||||
pub signature_secret: jubjub::Fr,
|
||||
}
|
||||
|
||||
pub struct TransactionBuilderInputInfo {
|
||||
pub merkle_path: Vec<(bls12_381::Scalar, bool)>,
|
||||
pub secret: jubjub::Fr,
|
||||
pub note: Note,
|
||||
}
|
||||
|
||||
pub struct TransactionBuilderOutputInfo {
|
||||
pub value: u64,
|
||||
pub public: jubjub::SubgroupPoint,
|
||||
}
|
||||
|
||||
impl TransactionBuilder {
|
||||
fn compute_remainder_blind(
|
||||
clear_inputs: &Vec<PartialTransactionClearInput>,
|
||||
input_blinds: &Vec<jubjub::Fr>,
|
||||
output_blinds: &Vec<jubjub::Fr>,
|
||||
) -> jubjub::Fr {
|
||||
let mut total = jubjub::Fr::zero();
|
||||
|
||||
for input in clear_inputs {
|
||||
total += input.valcom_blind;
|
||||
}
|
||||
|
||||
for input_blind in input_blinds {
|
||||
total += input_blind;
|
||||
}
|
||||
|
||||
for output_blind in output_blinds {
|
||||
total -= output_blind;
|
||||
}
|
||||
|
||||
total
|
||||
}
|
||||
|
||||
pub fn build(
|
||||
self,
|
||||
mint_params: &groth16::Parameters<Bls12>,
|
||||
spend_params: &groth16::Parameters<Bls12>,
|
||||
) -> Transaction {
|
||||
let mut clear_inputs = vec![];
|
||||
for input in &self.clear_inputs {
|
||||
let signature_public =
|
||||
zcash_primitives::constants::SPENDING_KEY_GENERATOR * input.signature_secret;
|
||||
|
||||
let valcom_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
||||
let clear_input = PartialTransactionClearInput {
|
||||
value: input.value,
|
||||
valcom_blind,
|
||||
signature_public,
|
||||
};
|
||||
clear_inputs.push(clear_input);
|
||||
}
|
||||
|
||||
let mut inputs = vec![];
|
||||
let mut input_blinds = vec![];
|
||||
let mut signature_secrets = vec![];
|
||||
for input in &self.inputs {
|
||||
input_blinds.push(input.note.valcom_blind.clone());
|
||||
|
||||
let signature_secret: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
||||
|
||||
// make proof
|
||||
|
||||
let (proof, revealed) = create_spend_proof(
|
||||
&spend_params,
|
||||
input.note.value,
|
||||
input.note.valcom_blind,
|
||||
input.note.serial,
|
||||
input.note.coin_blind,
|
||||
input.secret,
|
||||
input.merkle_path.clone(),
|
||||
signature_secret.clone(),
|
||||
);
|
||||
|
||||
// First we make the tx then sign after
|
||||
let signature_secret = schnorr::SecretKey(signature_secret);
|
||||
signature_secrets.push(signature_secret);
|
||||
|
||||
let input = PartialTransactionInput {
|
||||
spend_proof: proof,
|
||||
revealed,
|
||||
};
|
||||
inputs.push(input);
|
||||
}
|
||||
|
||||
let mut outputs = vec![];
|
||||
let mut output_blinds = vec![];
|
||||
for (i, output) in self.outputs.iter().enumerate() {
|
||||
let valcom_blind = if i == self.outputs.len() - 1 {
|
||||
Self::compute_remainder_blind(&clear_inputs, &input_blinds, &output_blinds)
|
||||
} else {
|
||||
jubjub::Fr::random(&mut OsRng)
|
||||
};
|
||||
output_blinds.push(valcom_blind);
|
||||
|
||||
let serial: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
||||
let coin_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
||||
|
||||
let (mint_proof, revealed) = create_mint_proof(
|
||||
mint_params,
|
||||
output.value,
|
||||
valcom_blind.clone(),
|
||||
serial.clone(),
|
||||
coin_blind.clone(),
|
||||
output.public.clone(),
|
||||
);
|
||||
|
||||
// Encrypted note
|
||||
|
||||
let note = Note {
|
||||
serial,
|
||||
value: output.value,
|
||||
coin_blind,
|
||||
valcom_blind,
|
||||
};
|
||||
|
||||
let encrypted_note = note.encrypt(&output.public).unwrap();
|
||||
|
||||
let output = TransactionOutput {
|
||||
mint_proof,
|
||||
revealed,
|
||||
enc_note: encrypted_note,
|
||||
};
|
||||
outputs.push(output);
|
||||
}
|
||||
|
||||
let partial_tx = PartialTransaction {
|
||||
clear_inputs,
|
||||
inputs,
|
||||
outputs,
|
||||
};
|
||||
|
||||
let mut unsigned_tx_data = vec![];
|
||||
partial_tx
|
||||
.encode(&mut unsigned_tx_data)
|
||||
.expect("TODO handle this");
|
||||
|
||||
let mut clear_inputs = vec![];
|
||||
for (input, info) in partial_tx.clear_inputs.into_iter().zip(self.clear_inputs) {
|
||||
let secret = schnorr::SecretKey(info.signature_secret.clone());
|
||||
let signature = secret.sign(&unsigned_tx_data[..]);
|
||||
let input = TransactionClearInput::from_partial(input, signature);
|
||||
clear_inputs.push(input);
|
||||
}
|
||||
|
||||
let mut inputs = vec![];
|
||||
for (input, signature_secret) in partial_tx
|
||||
.inputs
|
||||
.into_iter()
|
||||
.zip(signature_secrets.into_iter())
|
||||
{
|
||||
let signature = signature_secret.sign(&unsigned_tx_data[..]);
|
||||
let input = TransactionInput::from_partial(input, signature);
|
||||
inputs.push(input);
|
||||
}
|
||||
|
||||
Transaction {
|
||||
clear_inputs,
|
||||
inputs,
|
||||
outputs: partial_tx.outputs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
pub mod builder;
|
||||
pub mod partial;
|
||||
|
||||
use bellman::groth16;
|
||||
use bls12_381::Bls12;
|
||||
use ff::Field;
|
||||
@@ -18,212 +21,9 @@ use crate::error::{Error, Result};
|
||||
use crate::impl_vec;
|
||||
use crate::serial::{Decodable, Encodable, VarInt};
|
||||
use crate::state;
|
||||
use self::partial::{PartialTransactionClearInput, PartialTransactionInput};
|
||||
|
||||
pub struct TransactionBuilder {
|
||||
pub clear_inputs: Vec<TransactionBuilderClearInputInfo>,
|
||||
pub inputs: Vec<TransactionBuilderInputInfo>,
|
||||
pub outputs: Vec<TransactionBuilderOutputInfo>,
|
||||
}
|
||||
|
||||
impl TransactionBuilder {
|
||||
fn compute_remainder_blind(
|
||||
clear_inputs: &Vec<PartialTransactionClearInput>,
|
||||
input_blinds: &Vec<jubjub::Fr>,
|
||||
output_blinds: &Vec<jubjub::Fr>,
|
||||
) -> jubjub::Fr {
|
||||
let mut total = jubjub::Fr::zero();
|
||||
|
||||
for input in clear_inputs {
|
||||
total += input.valcom_blind;
|
||||
}
|
||||
|
||||
for input_blind in input_blinds {
|
||||
total += input_blind;
|
||||
}
|
||||
|
||||
for output_blind in output_blinds {
|
||||
total -= output_blind;
|
||||
}
|
||||
|
||||
total
|
||||
}
|
||||
|
||||
pub fn build(
|
||||
self,
|
||||
mint_params: &groth16::Parameters<Bls12>,
|
||||
spend_params: &groth16::Parameters<Bls12>,
|
||||
) -> Transaction {
|
||||
let mut clear_inputs = vec![];
|
||||
for input in &self.clear_inputs {
|
||||
let signature_public =
|
||||
zcash_primitives::constants::SPENDING_KEY_GENERATOR * input.signature_secret;
|
||||
|
||||
let valcom_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
||||
let clear_input = PartialTransactionClearInput {
|
||||
value: input.value,
|
||||
valcom_blind,
|
||||
signature_public,
|
||||
};
|
||||
clear_inputs.push(clear_input);
|
||||
}
|
||||
|
||||
let mut inputs = vec![];
|
||||
let mut input_blinds = vec![];
|
||||
let mut signature_secrets = vec![];
|
||||
for input in &self.inputs {
|
||||
input_blinds.push(input.note.valcom_blind.clone());
|
||||
|
||||
let signature_secret: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
||||
|
||||
// make proof
|
||||
|
||||
let (proof, revealed) = create_spend_proof(
|
||||
&spend_params,
|
||||
input.note.value,
|
||||
input.note.valcom_blind,
|
||||
input.note.serial,
|
||||
input.note.coin_blind,
|
||||
input.secret,
|
||||
input.merkle_path.clone(),
|
||||
signature_secret.clone(),
|
||||
);
|
||||
|
||||
// First we make the tx then sign after
|
||||
let signature_secret = schnorr::SecretKey(signature_secret);
|
||||
signature_secrets.push(signature_secret);
|
||||
|
||||
let input = PartialTransactionInput {
|
||||
spend_proof: proof,
|
||||
revealed,
|
||||
};
|
||||
inputs.push(input);
|
||||
}
|
||||
|
||||
let mut outputs = vec![];
|
||||
let mut output_blinds = vec![];
|
||||
for (i, output) in self.outputs.iter().enumerate() {
|
||||
let valcom_blind = if i == self.outputs.len() - 1 {
|
||||
Self::compute_remainder_blind(&clear_inputs, &input_blinds, &output_blinds)
|
||||
} else {
|
||||
jubjub::Fr::random(&mut OsRng)
|
||||
};
|
||||
output_blinds.push(valcom_blind);
|
||||
|
||||
let serial: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
||||
let coin_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
||||
|
||||
let (mint_proof, revealed) = create_mint_proof(
|
||||
mint_params,
|
||||
output.value,
|
||||
valcom_blind.clone(),
|
||||
serial.clone(),
|
||||
coin_blind.clone(),
|
||||
output.public.clone(),
|
||||
);
|
||||
|
||||
// Encrypted note
|
||||
|
||||
let note = Note {
|
||||
serial,
|
||||
value: output.value,
|
||||
coin_blind,
|
||||
valcom_blind,
|
||||
};
|
||||
|
||||
let encrypted_note = note.encrypt(&output.public).unwrap();
|
||||
|
||||
let output = TransactionOutput {
|
||||
mint_proof,
|
||||
revealed,
|
||||
enc_note: encrypted_note,
|
||||
};
|
||||
outputs.push(output);
|
||||
}
|
||||
|
||||
let partial_tx = PartialTransaction {
|
||||
clear_inputs,
|
||||
inputs,
|
||||
outputs,
|
||||
};
|
||||
|
||||
let mut unsigned_tx_data = vec![];
|
||||
partial_tx
|
||||
.encode(&mut unsigned_tx_data)
|
||||
.expect("TODO handle this");
|
||||
|
||||
let mut clear_inputs = vec![];
|
||||
for (input, info) in partial_tx.clear_inputs.into_iter().zip(self.clear_inputs) {
|
||||
let secret = schnorr::SecretKey(info.signature_secret.clone());
|
||||
let signature = secret.sign(&unsigned_tx_data[..]);
|
||||
let input = TransactionClearInput::from_partial(input, signature);
|
||||
clear_inputs.push(input);
|
||||
}
|
||||
|
||||
let mut inputs = vec![];
|
||||
for (input, signature_secret) in partial_tx
|
||||
.inputs
|
||||
.into_iter()
|
||||
.zip(signature_secrets.into_iter())
|
||||
{
|
||||
let signature = signature_secret.sign(&unsigned_tx_data[..]);
|
||||
let input = TransactionInput::from_partial(input, signature);
|
||||
inputs.push(input);
|
||||
}
|
||||
|
||||
Transaction {
|
||||
clear_inputs,
|
||||
inputs,
|
||||
outputs: partial_tx.outputs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TransactionBuilderClearOutputInfo {
|
||||
pub value: u64,
|
||||
pub instructions: String,
|
||||
}
|
||||
|
||||
pub struct TransactionBuilderClearInputInfo {
|
||||
pub value: u64,
|
||||
pub signature_secret: jubjub::Fr,
|
||||
}
|
||||
|
||||
pub struct TransactionBuilderInputInfo {
|
||||
pub merkle_path: Vec<(bls12_381::Scalar, bool)>,
|
||||
pub secret: jubjub::Fr,
|
||||
pub note: Note,
|
||||
}
|
||||
|
||||
pub struct TransactionBuilderOutputInfo {
|
||||
pub value: u64,
|
||||
pub public: jubjub::SubgroupPoint,
|
||||
}
|
||||
|
||||
pub struct PartialTransaction {
|
||||
pub clear_inputs: Vec<PartialTransactionClearInput>,
|
||||
pub inputs: Vec<PartialTransactionInput>,
|
||||
pub outputs: Vec<TransactionOutput>,
|
||||
}
|
||||
|
||||
impl Encodable for PartialTransaction {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += self.clear_inputs.encode(&mut s)?;
|
||||
len += self.inputs.encode(&mut s)?;
|
||||
len += self.outputs.encode(s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for PartialTransaction {
|
||||
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
||||
Ok(Self {
|
||||
clear_inputs: Decodable::decode(&mut d)?,
|
||||
inputs: Decodable::decode(&mut d)?,
|
||||
outputs: Decodable::decode(d)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
pub use self::builder::{TransactionBuilder, TransactionBuilderClearInputInfo, TransactionBuilderInputInfo, TransactionBuilderOutputInfo};
|
||||
|
||||
pub struct Transaction {
|
||||
pub clear_inputs: Vec<TransactionClearInput>,
|
||||
@@ -231,24 +31,23 @@ pub struct Transaction {
|
||||
pub outputs: Vec<TransactionOutput>,
|
||||
}
|
||||
|
||||
impl Encodable for Transaction {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += self.clear_inputs.encode(&mut s)?;
|
||||
len += self.inputs.encode(&mut s)?;
|
||||
len += self.outputs.encode(s)?;
|
||||
Ok(len)
|
||||
}
|
||||
pub struct TransactionClearInput {
|
||||
pub value: u64,
|
||||
pub valcom_blind: jubjub::Fr,
|
||||
pub signature_public: jubjub::SubgroupPoint,
|
||||
pub signature: schnorr::Signature,
|
||||
}
|
||||
|
||||
impl Decodable for Transaction {
|
||||
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
||||
Ok(Self {
|
||||
clear_inputs: Decodable::decode(&mut d)?,
|
||||
inputs: Decodable::decode(&mut d)?,
|
||||
outputs: Decodable::decode(d)?,
|
||||
})
|
||||
}
|
||||
pub struct TransactionInput {
|
||||
pub spend_proof: groth16::Proof<Bls12>,
|
||||
pub revealed: SpendRevealedValues,
|
||||
pub signature: schnorr::Signature,
|
||||
}
|
||||
|
||||
pub struct TransactionOutput {
|
||||
pub mint_proof: groth16::Proof<Bls12>,
|
||||
pub revealed: MintRevealedValues,
|
||||
pub enc_note: EncryptedNote,
|
||||
}
|
||||
|
||||
impl Transaction {
|
||||
@@ -314,13 +113,6 @@ impl Transaction {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TransactionClearInput {
|
||||
pub value: u64,
|
||||
pub valcom_blind: jubjub::Fr,
|
||||
pub signature_public: jubjub::SubgroupPoint,
|
||||
pub signature: schnorr::Signature,
|
||||
}
|
||||
|
||||
impl TransactionClearInput {
|
||||
fn from_partial(partial: PartialTransactionClearInput, signature: schnorr::Signature) -> Self {
|
||||
Self {
|
||||
@@ -340,25 +132,42 @@ impl TransactionClearInput {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_vec_without_signature {
|
||||
($type: ty) => {
|
||||
impl EncodableWithoutSignature for Vec<$type> {
|
||||
#[inline]
|
||||
fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += VarInt(self.len() as u64).encode(&mut s)?;
|
||||
for c in self.iter() {
|
||||
len += c.encode_without_signature(&mut s)?;
|
||||
}
|
||||
Ok(len)
|
||||
}
|
||||
impl TransactionInput {
|
||||
fn from_partial(partial: PartialTransactionInput, signature: schnorr::Signature) -> Self {
|
||||
Self {
|
||||
spend_proof: partial.spend_proof,
|
||||
revealed: partial.revealed,
|
||||
signature,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += self.spend_proof.encode(&mut s)?;
|
||||
len += self.revealed.encode(&mut s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl_vec_without_signature!(TransactionClearInput);
|
||||
impl Encodable for Transaction {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += self.clear_inputs.encode(&mut s)?;
|
||||
len += self.inputs.encode(&mut s)?;
|
||||
len += self.outputs.encode(s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl_vec!(TransactionClearInput);
|
||||
impl Decodable for Transaction {
|
||||
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
||||
Ok(Self {
|
||||
clear_inputs: Decodable::decode(&mut d)?,
|
||||
inputs: Decodable::decode(&mut d)?,
|
||||
outputs: Decodable::decode(d)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for TransactionClearInput {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
@@ -382,88 +191,6 @@ impl Decodable for TransactionClearInput {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PartialTransactionClearInput {
|
||||
pub value: u64,
|
||||
pub valcom_blind: jubjub::Fr,
|
||||
pub signature_public: jubjub::SubgroupPoint,
|
||||
}
|
||||
|
||||
impl_vec!(PartialTransactionClearInput);
|
||||
|
||||
impl Encodable for PartialTransactionClearInput {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += self.value.encode(&mut s)?;
|
||||
len += self.valcom_blind.encode(&mut s)?;
|
||||
len += self.signature_public.encode(&mut s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for PartialTransactionClearInput {
|
||||
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
||||
Ok(Self {
|
||||
value: Decodable::decode(&mut d)?,
|
||||
valcom_blind: Decodable::decode(&mut d)?,
|
||||
signature_public: Decodable::decode(&mut d)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PartialTransactionInput {
|
||||
pub spend_proof: groth16::Proof<Bls12>,
|
||||
pub revealed: SpendRevealedValues,
|
||||
}
|
||||
|
||||
impl Encodable for PartialTransactionInput {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += self.spend_proof.encode(&mut s)?;
|
||||
len += self.revealed.encode(s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for PartialTransactionInput {
|
||||
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
||||
Ok(Self {
|
||||
spend_proof: Decodable::decode(&mut d)?,
|
||||
revealed: Decodable::decode(d)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl_vec!(PartialTransactionInput);
|
||||
|
||||
pub struct TransactionInput {
|
||||
pub spend_proof: groth16::Proof<Bls12>,
|
||||
pub revealed: SpendRevealedValues,
|
||||
pub signature: schnorr::Signature,
|
||||
}
|
||||
|
||||
impl TransactionInput {
|
||||
fn from_partial(partial: PartialTransactionInput, signature: schnorr::Signature) -> Self {
|
||||
Self {
|
||||
spend_proof: partial.spend_proof,
|
||||
revealed: partial.revealed,
|
||||
signature,
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += self.spend_proof.encode(&mut s)?;
|
||||
len += self.revealed.encode(&mut s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
trait EncodableWithoutSignature {
|
||||
fn encode_without_signature<S: io::Write>(&self, s: S) -> Result<usize>;
|
||||
}
|
||||
|
||||
impl_vec_without_signature!(TransactionInput);
|
||||
|
||||
impl Encodable for TransactionInput {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
@@ -484,16 +211,6 @@ impl Decodable for TransactionInput {
|
||||
}
|
||||
}
|
||||
|
||||
impl_vec!(TransactionInput);
|
||||
|
||||
pub struct TransactionOutput {
|
||||
pub mint_proof: groth16::Proof<Bls12>,
|
||||
pub revealed: MintRevealedValues,
|
||||
pub enc_note: EncryptedNote,
|
||||
}
|
||||
|
||||
impl_vec!(TransactionOutput);
|
||||
|
||||
impl Encodable for TransactionOutput {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
@@ -513,3 +230,30 @@ impl Decodable for TransactionOutput {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
trait EncodableWithoutSignature {
|
||||
fn encode_without_signature<S: io::Write>(&self, s: S) -> Result<usize>;
|
||||
}
|
||||
|
||||
macro_rules! impl_vec_without_signature {
|
||||
($type: ty) => {
|
||||
impl EncodableWithoutSignature for Vec<$type> {
|
||||
#[inline]
|
||||
fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += VarInt(self.len() as u64).encode(&mut s)?;
|
||||
for c in self.iter() {
|
||||
len += c.encode_without_signature(&mut s)?;
|
||||
}
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_vec_without_signature!(TransactionClearInput);
|
||||
impl_vec_without_signature!(TransactionInput);
|
||||
impl_vec!(TransactionClearInput);
|
||||
impl_vec!(TransactionInput);
|
||||
impl_vec!(TransactionOutput);
|
||||
|
||||
99
src/tx/partial.rs
Normal file
99
src/tx/partial.rs
Normal file
@@ -0,0 +1,99 @@
|
||||
use bellman::groth16;
|
||||
use bls12_381::Bls12;
|
||||
use rand::rngs::OsRng;
|
||||
use std::collections::HashMap;
|
||||
use std::io;
|
||||
use ff::Field;
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use crate::impl_vec;
|
||||
use crate::serial::{Decodable, Encodable, VarInt};
|
||||
use super::{TransactionClearInput, TransactionInput, TransactionOutput, Transaction};
|
||||
use crate::crypto::{
|
||||
coin::Coin,
|
||||
create_mint_proof, create_spend_proof, load_params,
|
||||
merkle::CommitmentTree,
|
||||
note::{EncryptedNote, Note},
|
||||
save_params, schnorr, setup_mint_prover, setup_spend_prover, verify_mint_proof,
|
||||
verify_spend_proof, MintRevealedValues, SpendRevealedValues,
|
||||
};
|
||||
|
||||
pub struct PartialTransaction {
|
||||
pub clear_inputs: Vec<PartialTransactionClearInput>,
|
||||
pub inputs: Vec<PartialTransactionInput>,
|
||||
pub outputs: Vec<TransactionOutput>,
|
||||
}
|
||||
|
||||
pub struct PartialTransactionClearInput {
|
||||
pub value: u64,
|
||||
pub valcom_blind: jubjub::Fr,
|
||||
pub signature_public: jubjub::SubgroupPoint,
|
||||
}
|
||||
|
||||
pub struct PartialTransactionInput {
|
||||
pub spend_proof: groth16::Proof<Bls12>,
|
||||
pub revealed: SpendRevealedValues,
|
||||
}
|
||||
|
||||
impl Encodable for PartialTransaction {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += self.clear_inputs.encode(&mut s)?;
|
||||
len += self.inputs.encode(&mut s)?;
|
||||
len += self.outputs.encode(s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for PartialTransaction {
|
||||
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
||||
Ok(Self {
|
||||
clear_inputs: Decodable::decode(&mut d)?,
|
||||
inputs: Decodable::decode(&mut d)?,
|
||||
outputs: Decodable::decode(d)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for PartialTransactionClearInput {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += self.value.encode(&mut s)?;
|
||||
len += self.valcom_blind.encode(&mut s)?;
|
||||
len += self.signature_public.encode(&mut s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for PartialTransactionClearInput {
|
||||
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
||||
Ok(Self {
|
||||
value: Decodable::decode(&mut d)?,
|
||||
valcom_blind: Decodable::decode(&mut d)?,
|
||||
signature_public: Decodable::decode(&mut d)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Encodable for PartialTransactionInput {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += self.spend_proof.encode(&mut s)?;
|
||||
len += self.revealed.encode(s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for PartialTransactionInput {
|
||||
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
||||
Ok(Self {
|
||||
spend_proof: Decodable::decode(&mut d)?,
|
||||
revealed: Decodable::decode(d)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl_vec!(PartialTransactionClearInput);
|
||||
impl_vec!(PartialTransactionInput);
|
||||
|
||||
Reference in New Issue
Block a user