Skip to content

Commit

Permalink
consensus: add NU plumbing to block,tx,script verifiers
Browse files Browse the repository at this point in the history
Closes #1367 by propagating the network upgrade through the service
requests.
  • Loading branch information
hdevalence committed Nov 24, 2020
1 parent 2e0ed94 commit ae2081d
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 24 deletions.
7 changes: 3 additions & 4 deletions zebra-consensus/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ use tracing::Instrument;
use zebra_chain::{
block::{self, Block},
parameters::Network,
parameters::NetworkUpgrade,
transparent,
work::equihash,
};
Expand Down Expand Up @@ -83,9 +82,8 @@ where
S::Future: Send + 'static,
{
pub fn new(network: Network, state_service: S) -> Self {
let branch = NetworkUpgrade::Sapling.branch_id().unwrap();
let script_verifier = script::Verifier::new(state_service.clone(), branch);
let transaction_verifier = transaction::Verifier::new(script_verifier);
let transaction_verifier =
transaction::Verifier::new(network, script::Verifier::new(state_service.clone()));

Self {
network,
Expand Down Expand Up @@ -176,6 +174,7 @@ where
.call(transaction::Request::Block {
transaction: transaction.clone(),
known_utxos: known_utxos.clone(),
height,
});
async_checks.push(rsp);
}
Expand Down
32 changes: 21 additions & 11 deletions zebra-consensus/src/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{collections::HashMap, future::Future, pin::Pin, sync::Arc};

use tracing::Instrument;

use zebra_chain::{parameters::ConsensusBranchId, transaction::Transaction, transparent};
use zebra_chain::{parameters::NetworkUpgrade, transaction::Transaction, transparent};
use zebra_state::Utxo;

use crate::BoxError;
Expand All @@ -21,27 +21,34 @@ use crate::BoxError;
#[derive(Debug, Clone)]
pub struct Verifier<ZS> {
state: ZS,
branch: ConsensusBranchId,
}

impl<ZS> Verifier<ZS> {
pub fn new(state: ZS, branch: ConsensusBranchId) -> Self {
Self { state, branch }
pub fn new(state: ZS) -> Self {
Self { state }
}
}

/// A script verification request.
///
/// Ideally, this would supply only an `Outpoint` and the unlock script,
/// rather than the entire `Transaction`, but we call a C++
/// implementation, and its FFI requires the entire transaction.
/// At some future point, we could investigate reducing the size of the
/// request.
#[derive(Debug)]
pub struct Request {
/// Ideally, this would supply only an `Outpoint` and the unlock script,
/// rather than the entire `Transaction`, but we call a C++
/// implementation, and its FFI requires the entire transaction.
///
/// This causes quadratic script verification behavior, so
/// at some future point, we need to reform this data.
pub transaction: Arc<Transaction>,
pub input_index: usize,
/// A set of additional UTXOs known in the context of this verification request.
///
/// This allows specifying additional UTXOs that are not already known to the chain state.
pub known_utxos: Arc<HashMap<transparent::OutPoint, Utxo>>,
/// The network upgrade active in the context of this verification request.
///
/// Because the consensus branch ID changes with each network upgrade,
/// it has to be specified on a per-request basis.
pub upgrade: NetworkUpgrade,
}

impl<ZS> tower::Service<Request> for Verifier<ZS>
Expand All @@ -68,13 +75,16 @@ where
transaction,
input_index,
known_utxos,
upgrade,
} = req;
let input = &transaction.inputs()[input_index];
let branch_id = upgrade
.branch_id()
.expect("post-Sapling NUs have a consensus branch ID");

match input {
transparent::Input::PrevOut { outpoint, .. } => {
let outpoint = *outpoint;
let branch_id = self.branch;

let span = tracing::trace_span!("script", ?outpoint);
let query =
Expand Down
37 changes: 28 additions & 9 deletions zebra-consensus/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ use tower::{Service, ServiceExt};
use tracing::Instrument;

use zebra_chain::{
parameters::NetworkUpgrade,
block,
parameters::{Network, NetworkUpgrade},
transaction::{self, HashType, Transaction},
transparent,
};
Expand All @@ -28,6 +29,7 @@ mod check;
/// Asynchronous transaction verification.
#[derive(Debug, Clone)]
pub struct Verifier<ZS> {
network: Network,
script_verifier: script::Verifier<ZS>,
// spend_verifier: groth16::Verifier,
// output_verifier: groth16::Verifier,
Expand All @@ -40,8 +42,11 @@ where
ZS::Future: Send + 'static,
{
// XXX: how should this struct be constructed?
pub fn new(script_verifier: script::Verifier<ZS>) -> Self {
Self { script_verifier }
pub fn new(network: Network, script_verifier: script::Verifier<ZS>) -> Self {
Self {
network,
script_verifier,
}
}
}

Expand All @@ -54,15 +59,22 @@ where
pub enum Request {
/// Verify the supplied transaction as part of a block.
Block {
/// The transaction itself.
transaction: Arc<Transaction>,
/// Additional UTXOs which are known at the time of verification.
known_utxos: Arc<HashMap<transparent::OutPoint, zs::Utxo>>,
/// The height of the block containing this transaction, used to
/// determine the applicable network upgrade.
height: block::Height,
},
/// Verify the supplied transaction as part of the mempool.
Mempool {
/// The transaction itself.
transaction: Arc<Transaction>,
/// Additional UTXOs which are known at the time of verification.
known_utxos: Arc<HashMap<transparent::OutPoint, zs::Utxo>>,
/// The active NU in the context of this verification.
upgrade: NetworkUpgrade,
},
}

Expand Down Expand Up @@ -91,15 +103,20 @@ where
unimplemented!();
}

let (tx, known_utxos) = match req {
let (tx, known_utxos, upgrade) = match req {
Request::Block {
transaction,
known_utxos,
} => (transaction, known_utxos),
height,
} => {
let upgrade = NetworkUpgrade::current(self.network, height);
(transaction, known_utxos, upgrade)
}
Request::Mempool {
transaction,
known_utxos,
} => (transaction, known_utxos),
upgrade,
} => (transaction, known_utxos, upgrade),
};

let mut redjubjub_verifier = crate::primitives::redjubjub::VERIFIER.clone();
Expand Down Expand Up @@ -135,6 +152,7 @@ where
// feed all of the inputs to the script verifier
for input_index in 0..inputs.len() {
let rsp = script_verifier.ready_and().await?.call(script::Request {
upgrade,
known_utxos: known_utxos.clone(),
transaction: tx.clone(),
input_index,
Expand All @@ -146,10 +164,11 @@ where

check::has_inputs_and_outputs(&tx)?;

// TODO: rework this code
let sighash = tx.sighash(
NetworkUpgrade::Sapling, // TODO: pass this in
HashType::ALL, // TODO: check these
None, // TODO: check these
upgrade,
HashType::ALL, // TODO: check these
None, // TODO: check these
);

if let Some(joinsplit_data) = joinsplit_data {
Expand Down

0 comments on commit ae2081d

Please sign in to comment.