mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-07-30 20:11:23 +00:00
Compute TxId for Transaction
This commit is contained in:
@@ -13,6 +13,7 @@ lazy_static = "1"
|
||||
pairing = { path = "../pairing" }
|
||||
rand = "0.4"
|
||||
sapling-crypto = { path = "../sapling-crypto" }
|
||||
sha2 = "0.8"
|
||||
|
||||
[dependencies.blake2-rfc]
|
||||
git = "https://github.com/gtank/blake2-rfc"
|
||||
|
@@ -8,6 +8,7 @@ extern crate hex;
|
||||
extern crate pairing;
|
||||
extern crate rand;
|
||||
extern crate sapling_crypto;
|
||||
extern crate sha2;
|
||||
|
||||
use sapling_crypto::jubjub::JubjubBls12;
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use hex;
|
||||
use sapling_crypto::redjubjub::Signature;
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::fmt;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::ops::Deref;
|
||||
@@ -35,7 +36,7 @@ impl fmt::Display for TxId {
|
||||
|
||||
/// A Zcash transaction.
|
||||
#[derive(Debug)]
|
||||
pub struct Transaction(TransactionData);
|
||||
pub struct Transaction(TransactionData, TxId);
|
||||
|
||||
impl Deref for Transaction {
|
||||
type Target = TransactionData;
|
||||
@@ -125,12 +126,26 @@ impl TransactionData {
|
||||
header
|
||||
}
|
||||
|
||||
pub fn freeze(self) -> Transaction {
|
||||
Transaction(self)
|
||||
pub fn freeze(self) -> io::Result<Transaction> {
|
||||
Transaction::from_data(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Transaction {
|
||||
fn from_data(data: TransactionData) -> io::Result<Self> {
|
||||
let mut tx = Transaction(data, TxId([0; 32]));
|
||||
let mut raw = vec![];
|
||||
tx.write(&mut raw)?;
|
||||
(tx.1)
|
||||
.0
|
||||
.copy_from_slice(&Sha256::digest(&Sha256::digest(&raw)));
|
||||
Ok(tx)
|
||||
}
|
||||
|
||||
pub fn txid(&self) -> TxId {
|
||||
self.1
|
||||
}
|
||||
|
||||
pub fn read<R: Read>(mut reader: R) -> io::Result<Self> {
|
||||
let header = reader.read_u32::<LittleEndian>()?;
|
||||
let overwintered = (header >> 31) == 1;
|
||||
@@ -195,7 +210,7 @@ impl Transaction {
|
||||
false => None,
|
||||
};
|
||||
|
||||
Ok(Transaction(TransactionData {
|
||||
Transaction::from_data(TransactionData {
|
||||
overwintered,
|
||||
version,
|
||||
version_group_id,
|
||||
@@ -210,7 +225,7 @@ impl Transaction {
|
||||
joinsplit_pubkey,
|
||||
joinsplit_sig,
|
||||
binding_sig,
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn write<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
||||
|
@@ -159,51 +159,33 @@ fn tx_read_write() {
|
||||
#[test]
|
||||
fn tx_write_rejects_unexpected_joinsplit_pubkey() {
|
||||
// Succeeds without a JoinSplit pubkey
|
||||
{
|
||||
let tx = TransactionData::new().freeze();
|
||||
let mut encoded = Vec::new();
|
||||
assert!(tx.write(&mut encoded).is_ok());
|
||||
}
|
||||
assert!(TransactionData::new().freeze().is_ok());
|
||||
|
||||
// Fails with an unexpected JoinSplit pubkey
|
||||
{
|
||||
let mut tx = TransactionData::new();
|
||||
tx.joinsplit_pubkey = Some([0; 32]);
|
||||
let tx = tx.freeze();
|
||||
|
||||
let mut encoded = Vec::new();
|
||||
assert!(tx.write(&mut encoded).is_err());
|
||||
assert!(tx.freeze().is_err());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tx_write_rejects_unexpected_joinsplit_sig() {
|
||||
// Succeeds without a JoinSplit signature
|
||||
{
|
||||
let tx = TransactionData::new().freeze();
|
||||
let mut encoded = Vec::new();
|
||||
assert!(tx.write(&mut encoded).is_ok());
|
||||
}
|
||||
assert!(TransactionData::new().freeze().is_ok());
|
||||
|
||||
// Fails with an unexpected JoinSplit signature
|
||||
{
|
||||
let mut tx = TransactionData::new();
|
||||
tx.joinsplit_sig = Some([0; 64]);
|
||||
let tx = tx.freeze();
|
||||
|
||||
let mut encoded = Vec::new();
|
||||
assert!(tx.write(&mut encoded).is_err());
|
||||
assert!(tx.freeze().is_err());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tx_write_rejects_unexpected_binding_sig() {
|
||||
// Succeeds without a binding signature
|
||||
{
|
||||
let tx = TransactionData::new().freeze();
|
||||
let mut encoded = Vec::new();
|
||||
assert!(tx.write(&mut encoded).is_ok());
|
||||
}
|
||||
assert!(TransactionData::new().freeze().is_ok());
|
||||
|
||||
// Fails with an unexpected binding signature
|
||||
{
|
||||
@@ -218,10 +200,7 @@ fn tx_write_rejects_unexpected_binding_sig() {
|
||||
|
||||
let mut tx = TransactionData::new();
|
||||
tx.binding_sig = Some(sig);
|
||||
let tx = tx.freeze();
|
||||
|
||||
let mut encoded = Vec::new();
|
||||
assert!(tx.write(&mut encoded).is_err());
|
||||
assert!(tx.freeze().is_err());
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user