use std::sync::Arc;
use zcash_protocol::value::ZatBalance;
use zcash_transparent::sighash::SighashType;
use super::Transaction;
use crate::parameters::NetworkUpgrade;
use crate::{transparent, Error};
use crate::primitives::zcash_primitives::{sighash, sighash_v4_raw, PrecomputedTxData};
bitflags::bitflags! {
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct HashType: u32 {
const ALL = 0b0000_0001;
const NONE = 0b0000_0010;
const SINGLE = Self::ALL.bits() | Self::NONE.bits();
const ANYONECANPAY = 0b1000_0000;
const ALL_ANYONECANPAY = Self::ALL.bits() | Self::ANYONECANPAY.bits();
const NONE_ANYONECANPAY = Self::NONE.bits() | Self::ANYONECANPAY.bits();
const SINGLE_ANYONECANPAY = Self::SINGLE.bits() | Self::ANYONECANPAY.bits();
}
}
impl TryFrom<HashType> for SighashType {
type Error = ();
fn try_from(hash_type: HashType) -> Result<Self, Self::Error> {
Ok(match hash_type {
HashType::ALL => Self::ALL,
HashType::NONE => Self::NONE,
HashType::SINGLE => Self::SINGLE,
HashType::ALL_ANYONECANPAY => Self::ALL_ANYONECANPAY,
HashType::NONE_ANYONECANPAY => Self::NONE_ANYONECANPAY,
HashType::SINGLE_ANYONECANPAY => Self::SINGLE_ANYONECANPAY,
_other => return Err(()),
})
}
}
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct SigHash(pub [u8; 32]);
impl AsRef<[u8; 32]> for SigHash {
fn as_ref(&self) -> &[u8; 32] {
&self.0
}
}
impl AsRef<[u8]> for SigHash {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl From<SigHash> for [u8; 32] {
fn from(sighash: SigHash) -> Self {
sighash.0
}
}
#[derive(Debug)]
pub struct SigHasher {
precomputed_tx_data: PrecomputedTxData,
}
impl SigHasher {
pub fn new(
trans: &Transaction,
nu: NetworkUpgrade,
all_previous_outputs: Arc<Vec<transparent::Output>>,
) -> Result<Self, Error> {
Ok(SigHasher {
precomputed_tx_data: PrecomputedTxData::new(trans, nu, all_previous_outputs)?,
})
}
pub fn sighash(
&self,
hash_type: HashType,
input_index_script_code: Option<(usize, Vec<u8>)>,
) -> SigHash {
sighash(
&self.precomputed_tx_data,
hash_type,
input_index_script_code,
)
}
pub fn sighash_v4_raw(
&self,
raw_hash_type: u8,
input_index_script_code: Option<(usize, Vec<u8>)>,
) -> SigHash {
sighash_v4_raw(
&self.precomputed_tx_data,
raw_hash_type,
input_index_script_code,
)
}
pub fn orchard_bundle(
&self,
) -> Option<::orchard::bundle::Bundle<::orchard::bundle::Authorized, ZatBalance>> {
self.precomputed_tx_data.orchard_bundle()
}
pub fn ironwood_bundle(
&self,
) -> Option<::orchard::bundle::Bundle<::orchard::bundle::Authorized, ZatBalance>> {
self.precomputed_tx_data.ironwood_bundle()
}
pub fn sapling_bundle(
&self,
) -> Option<sapling_crypto::Bundle<sapling_crypto::bundle::Authorized, ZatBalance>> {
self.precomputed_tx_data.sapling_bundle()
}
}