mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
return specific errors for VerifyFailed
This commit is contained in:
@@ -16,8 +16,33 @@ use sapvi::crypto::{
|
||||
};
|
||||
use sapvi::error::{Error, Result};
|
||||
use sapvi::serial::{Decodable, Encodable, VarInt};
|
||||
use sapvi::state::{state_transition, ProgramState, StateUpdates};
|
||||
use sapvi::tx;
|
||||
|
||||
struct MemoryState {
|
||||
mint_pvk: groth16::PreparedVerifyingKey<Bls12>,
|
||||
spend_pvk: groth16::PreparedVerifyingKey<Bls12>,
|
||||
cashier_public: jubjub::SubgroupPoint
|
||||
}
|
||||
|
||||
impl ProgramState for MemoryState {
|
||||
fn is_valid_cashier_public_key(&self, public: &jubjub::SubgroupPoint) -> bool {
|
||||
public == &self.cashier_public
|
||||
}
|
||||
|
||||
fn mint_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
|
||||
&self.mint_pvk
|
||||
}
|
||||
fn spend_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
|
||||
&self.spend_pvk
|
||||
}
|
||||
}
|
||||
|
||||
impl MemoryState {
|
||||
fn apply(updates: StateUpdates) {
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Auto create trusted ceremony parameters if they don't exist
|
||||
if !Path::new("mint.params").exists() {
|
||||
@@ -38,6 +63,12 @@ fn main() {
|
||||
// This is their public key
|
||||
let cashier_public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * cashier_secret;
|
||||
|
||||
let state = MemoryState {
|
||||
mint_pvk,
|
||||
spend_pvk,
|
||||
cashier_public
|
||||
};
|
||||
|
||||
// Wallet 1 creates a secret key
|
||||
let secret = jubjub::Fr::random(&mut OsRng);
|
||||
// This is their public key
|
||||
@@ -79,12 +110,13 @@ fn main() {
|
||||
}
|
||||
// Now we receive the tx data
|
||||
let note = {
|
||||
let txx = tx::Transaction::decode(&tx_data[..]).unwrap();
|
||||
let tx = tx::Transaction::decode(&tx_data[..]).unwrap();
|
||||
// Check the public key in the clear inputs
|
||||
// It should be a valid public key for the cashier
|
||||
assert_eq!(tx.clear_inputs[0].signature_public, cashier_public);
|
||||
|
||||
let update = state_transition(&state, txx).expect("step 2 state transition failed");
|
||||
|
||||
// Check the tx verifies correctly
|
||||
assert!(tx.verify(&mint_pvk, &spend_pvk));
|
||||
//assert!(tx.verify(&mint_pvk, &spend_pvk));
|
||||
// Add the new coins to the merkle tree
|
||||
tree.append(Coin::new(tx.outputs[0].revealed.coin))
|
||||
.expect("append merkle");
|
||||
@@ -172,6 +204,6 @@ fn main() {
|
||||
// Verify it's valid
|
||||
{
|
||||
let tx = tx::Transaction::decode(&tx_data[..]).unwrap();
|
||||
assert!(tx.verify(&mint_pvk, &spend_pvk));
|
||||
//assert!(tx.verify(&mint_pvk, &spend_pvk));
|
||||
}
|
||||
}
|
||||
|
||||
12
src/error.rs
12
src/error.rs
@@ -1,9 +1,10 @@
|
||||
use std::fmt;
|
||||
use rusqlite;
|
||||
|
||||
use crate::net::error::NetError;
|
||||
use crate::service::ServicesError;
|
||||
use crate::state;
|
||||
use crate::vm::ZKVMError;
|
||||
use rusqlite;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
@@ -46,6 +47,7 @@ pub enum Error {
|
||||
NoteDecryptionFailed,
|
||||
ServicesError(ServicesError),
|
||||
ZMQError(zeromq::ZmqError),
|
||||
VerifyFailed(state::VerifyFailed),
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {}
|
||||
@@ -92,6 +94,7 @@ impl fmt::Display for Error {
|
||||
Error::NoteDecryptionFailed => f.write_str("Unable to decrypt mint note"),
|
||||
Error::ServicesError(ref err) => write!(f, "Services error: {}", err),
|
||||
Error::ZMQError(ref err) => write!(f, "zmq error: {}", err),
|
||||
Error::VerifyFailed(ref err) => write!(f, "Verify failed: {}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,3 +177,10 @@ impl From<std::string::FromUtf8Error> for Error {
|
||||
Error::Utf8Error
|
||||
}
|
||||
}
|
||||
|
||||
impl From<state::VerifyFailed> for Error {
|
||||
fn from(err: state::VerifyFailed) -> Error {
|
||||
Error::VerifyFailed(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ pub mod net;
|
||||
pub mod rpc;
|
||||
pub mod serial;
|
||||
pub mod service;
|
||||
pub mod state;
|
||||
pub mod system;
|
||||
pub mod tx;
|
||||
pub mod vm;
|
||||
|
||||
26
src/tx.rs
26
src/tx.rs
@@ -17,6 +17,7 @@ use crate::crypto::{
|
||||
use crate::error::{Error, Result};
|
||||
use crate::impl_vec;
|
||||
use crate::serial::{Decodable, Encodable, VarInt};
|
||||
use crate::state;
|
||||
|
||||
pub struct TransactionBuilder {
|
||||
pub clear_inputs: Vec<TransactionBuilderClearInputInfo>,
|
||||
@@ -267,43 +268,46 @@ impl Transaction {
|
||||
&self,
|
||||
mint_pvk: &groth16::PreparedVerifyingKey<Bls12>,
|
||||
spend_pvk: &groth16::PreparedVerifyingKey<Bls12>,
|
||||
) -> bool {
|
||||
) -> std::result::Result<(), state::VerifyFailed> {
|
||||
let mut valcom_total = jubjub::SubgroupPoint::identity();
|
||||
for input in &self.clear_inputs {
|
||||
valcom_total += Self::compute_value_commit(input.value, &input.valcom_blind);
|
||||
}
|
||||
for input in &self.inputs {
|
||||
for (i, input) in self.inputs.iter().enumerate() {
|
||||
if !verify_spend_proof(spend_pvk, &input.spend_proof, &input.revealed) {
|
||||
return false;
|
||||
return Err(state::VerifyFailed::SpendProof(i));
|
||||
}
|
||||
valcom_total += &input.revealed.value_commit;
|
||||
}
|
||||
for output in &self.outputs {
|
||||
for (i, output) in self.outputs.iter().enumerate() {
|
||||
if !verify_mint_proof(mint_pvk, &output.mint_proof, &output.revealed) {
|
||||
println!("mint fail");
|
||||
return false;
|
||||
return Err(state::VerifyFailed::SpendProof(i));
|
||||
}
|
||||
valcom_total -= &output.revealed.value_commit;
|
||||
}
|
||||
|
||||
if valcom_total != jubjub::SubgroupPoint::identity() {
|
||||
return Err(state::VerifyFailed::MissingFunds);
|
||||
}
|
||||
|
||||
// Verify signatures
|
||||
let mut unsigned_tx_data = vec![];
|
||||
self.encode_without_signature(&mut unsigned_tx_data)
|
||||
.expect("TODO handle this");
|
||||
for input in &self.clear_inputs {
|
||||
for (i, input) in self.clear_inputs.iter().enumerate() {
|
||||
let public = schnorr::PublicKey(input.signature_public.clone());
|
||||
if !public.verify(&unsigned_tx_data[..], &input.signature) {
|
||||
return false;
|
||||
return Err(state::VerifyFailed::ClearInputSignature(i));
|
||||
}
|
||||
}
|
||||
for input in &self.inputs {
|
||||
for (i, input) in self.inputs.iter().enumerate() {
|
||||
let public = schnorr::PublicKey(input.revealed.signature_public.clone());
|
||||
if !public.verify(&unsigned_tx_data[..], &input.signature) {
|
||||
return false;
|
||||
return Err(state::VerifyFailed::InputSignature(i));
|
||||
}
|
||||
}
|
||||
|
||||
valcom_total == jubjub::SubgroupPoint::identity()
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user