Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Address Str4d’s comments on #171 #175

Merged
merged 3 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 31 additions & 15 deletions src/interpreter.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
bitflags::bitflags! {
/// The different SigHash types, as defined in <https://zips.z.cash/zip-0143>
///
/// TODO: This is currently defined as `i32` to match the `c_int` constants in this package, but
/// should use librustzcash’s `u8` constants once we’ve removed the C++.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct HashType: i32 {
/// Sign all the outputs
const All = 1;
/// Sign none of the outputs - anyone can spend
const None = 2;
/// Sign one of the outputs - anyone can spend the rest
const Single = 3;
/// Anyone can add inputs to this transaction
const AnyoneCanPay = 0x80;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum SignedOutputs {
/// Sign all the outputs
sellout marked this conversation as resolved.
Show resolved Hide resolved
All,
sellout marked this conversation as resolved.
Show resolved Hide resolved
/// Sign one of the outputs - anyone can spend the rest
Single,
sellout marked this conversation as resolved.
Show resolved Hide resolved
/// Sign none of the outputs - anyone can spend
None,
sellout marked this conversation as resolved.
Show resolved Hide resolved
}

/// The different SigHash types, as defined in <https://zips.z.cash/zip-0143>
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
sellout marked this conversation as resolved.
Show resolved Hide resolved
pub struct HashType {
pub signed_outputs: SignedOutputs,
/// Anyone can add inputs to this transaction
pub anyone_can_pay: bool,
sellout marked this conversation as resolved.
Show resolved Hide resolved
}

impl HashType {
pub fn from_bits(bits: i32) -> Option<Self> {
let msigned_outputs = match (bits & 2 != 0, bits & 1 != 0) {
(false, false) => None,
(false, true) => Some(SignedOutputs::All),
(true, false) => Some(SignedOutputs::None),
(true, true) => Some(SignedOutputs::Single),
};

msigned_outputs.map(|signed_outputs| HashType {
signed_outputs,
anyone_can_pay: bits & 0x80 != 0,
})
}
}
conradoplg marked this conversation as resolved.
Show resolved Hide resolved

Expand Down
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ extern "C" fn sighash_callback(
let ctx = ctx as *const SighashCalculator;
// SAFETY: `ctx` is a valid `SighashCalculator` passed to `verify_callback` which forwards it to
// the `CallbackTransactionSignatureChecker`.
if let Some(sighash) = unsafe { *ctx }(script_code_vec, HashType::from_bits_retain(hash_type)) {
if let Some(sighash) =
HashType::from_bits(hash_type).and_then(|ht| unsafe { *ctx }(script_code_vec, ht))
{
assert_eq!(sighash_out_len, sighash.len().try_into().unwrap());
// SAFETY: `sighash_out` is a valid buffer created in
// `CallbackTransactionSignatureChecker::CheckSig`.
Expand Down
11 changes: 6 additions & 5 deletions src/zcash_script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ use super::interpreter::*;
/// replicates the still-used cases, and then an `Unknown` bucket for anything else that might
/// happen.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum Error {
/// Any failure that results in the script being invalid.
Ok = 0,
Ok,
/// An exception was caught.
VerifyScript = 7,
VerifyScript,
/// The script size can’t fit in a `u32`, as required by the C++ code.
InvalidScriptSize(TryFromIntError),
/// Some other failure value recovered from C++.
Expand All @@ -21,7 +20,9 @@ pub enum Error {
Unknown(i64),
}

/// All signature hashes are 32 bits, since they are necessarily produced by SHA256.
/// All signature hashes are 32 bytes, since they are either:
/// - a SHA-256 output (for v1 or v2 transactions).
/// - a BLAKE2b-256 output (for v3 and above transactions).
pub const SIGHASH_SIZE: usize = 32;

/// A function which is called to obtain the sighash.
Expand All @@ -44,7 +45,7 @@ pub trait ZcashScript {
/// the transaction itself. In particular, the sighash for the spend
/// is obtained using a callback function.
///
/// - sighash_callback: a callback function which is called to obtain the sighash.
/// - sighash: a callback function which is called to obtain the sighash.
/// - n_lock_time: the lock time of the transaction being validated.
/// - is_final: a boolean indicating whether the input being validated is final
/// (i.e. its sequence number is 0xFFFFFFFF).
Expand Down
Loading