TZE consensus context and program sets
Co-authored-by: Kris Nuttycombe <kris.nuttycombe@gmail.com>
This commit is contained in:
parent
ce9a695ded
commit
bf7f95b0e9
|
@ -1,8 +1,10 @@
|
||||||
//! Consensus parameters.
|
//! Consensus logic and parameters.
|
||||||
|
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
pub mod extensions;
|
||||||
|
|
||||||
/// Zcash consensus parameters.
|
/// Zcash consensus parameters.
|
||||||
pub trait Parameters {
|
pub trait Parameters {
|
||||||
fn activation_height(nu: NetworkUpgrade) -> Option<u32>;
|
fn activation_height(nu: NetworkUpgrade) -> Option<u32>;
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
//! Consensus logic for Zcash extensions.
|
||||||
|
|
||||||
|
pub mod transparent;
|
|
@ -0,0 +1,109 @@
|
||||||
|
//! Consensus logic for Transparent Zcash Extensions.
|
||||||
|
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
use zcash_extensions_api::transparent::{Error, Extension, Precondition, Witness};
|
||||||
|
|
||||||
|
use crate::extensions::transparent::demo;
|
||||||
|
use crate::transaction::components::TzeOut;
|
||||||
|
use crate::transaction::Transaction;
|
||||||
|
|
||||||
|
/// The set of programs that have assigned type IDs within the Zcash consensus rules.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum ExtensionId {
|
||||||
|
Demo,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct InvalidExtId(usize);
|
||||||
|
|
||||||
|
impl TryFrom<usize> for ExtensionId {
|
||||||
|
type Error = InvalidExtId;
|
||||||
|
|
||||||
|
fn try_from(t: usize) -> Result<Self, Self::Error> {
|
||||||
|
match t {
|
||||||
|
0 => Ok(ExtensionId::Demo),
|
||||||
|
n => Err(InvalidExtId(n)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ExtensionId> for usize {
|
||||||
|
fn from(type_id: ExtensionId) -> usize {
|
||||||
|
match type_id {
|
||||||
|
ExtensionId::Demo => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The complete set of context data that is available to any extension having
|
||||||
|
/// an assigned extension type ID.
|
||||||
|
pub struct Context<'a> {
|
||||||
|
pub height: i32,
|
||||||
|
pub tx: &'a Transaction,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Context<'a> {
|
||||||
|
pub fn new(height: i32, tx: &'a Transaction) -> Self {
|
||||||
|
Context { height, tx }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Epoch {
|
||||||
|
type Error;
|
||||||
|
|
||||||
|
fn verify<'a>(
|
||||||
|
&self,
|
||||||
|
precondition: &Precondition,
|
||||||
|
witness: &Witness,
|
||||||
|
ctx: &Context<'a>,
|
||||||
|
) -> Result<(), Error<Self::Error>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Implementation of required operations for the demo extension, as satisfied
|
||||||
|
/// by the context.
|
||||||
|
impl<'a> demo::Context for Context<'a> {
|
||||||
|
fn is_tze_only(&self) -> bool {
|
||||||
|
self.tx.vin.is_empty()
|
||||||
|
&& self.tx.vout.is_empty()
|
||||||
|
&& self.tx.shielded_spends.is_empty()
|
||||||
|
&& self.tx.shielded_outputs.is_empty()
|
||||||
|
&& self.tx.joinsplits.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tx_tze_outputs(&self) -> &[TzeOut] {
|
||||||
|
&self.tx.tze_outputs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Wire identifier for the dummy network upgrade epoch.
|
||||||
|
pub const V1_EPOCH_ID: u32 = 0x7473_6554;
|
||||||
|
|
||||||
|
/// A set of demo TZEs associated with the dummy network upgrade.
|
||||||
|
struct EpochV1;
|
||||||
|
|
||||||
|
impl Epoch for EpochV1 {
|
||||||
|
type Error = String;
|
||||||
|
|
||||||
|
fn verify<'a>(
|
||||||
|
&self,
|
||||||
|
precondition: &Precondition,
|
||||||
|
witness: &Witness,
|
||||||
|
ctx: &Context<'a>,
|
||||||
|
) -> Result<(), Error<Self::Error>> {
|
||||||
|
// This epoch contains the following set of programs:
|
||||||
|
let ext_id = ExtensionId::try_from(precondition.extension_id)
|
||||||
|
.map_err(|InvalidExtId(id)| Error::InvalidExtensionId(id))?;
|
||||||
|
match ext_id {
|
||||||
|
ExtensionId::Demo => demo::Program
|
||||||
|
.verify(precondition, witness, ctx)
|
||||||
|
.map_err(|e| Error::ProgramError(format!("Epoch v1 program error: {}", e))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn epoch_for_branch(consensus_branch_id: u32) -> Option<Box<dyn Epoch<Error = String>>> {
|
||||||
|
// Map from consensus branch IDs to epochs.
|
||||||
|
match consensus_branch_id {
|
||||||
|
V1_EPOCH_ID => Some(Box::new(EpochV1)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue