Skip to content

Commit e748f2f

Browse files
committed
Address Str4d’s comments on ZcashFoundation#171
Notably, `HashType` has changed incompatibly, so ZcashFoundation/zebra#8751 will need to be updated.
1 parent 9d16e79 commit e748f2f

File tree

3 files changed

+40
-21
lines changed

3 files changed

+40
-21
lines changed

src/interpreter.rs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,34 @@
1-
bitflags::bitflags! {
2-
/// The different SigHash types, as defined in <https://zips.z.cash/zip-0143>
3-
///
4-
/// TODO: This is currently defined as `i32` to match the `c_int` constants in this package, but
5-
/// should use librustzcash’s `u8` constants once we’ve removed the C++.
6-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
7-
pub struct HashType: i32 {
8-
/// Sign all the outputs
9-
const All = 1;
10-
/// Sign none of the outputs - anyone can spend
11-
const None = 2;
12-
/// Sign one of the outputs - anyone can spend the rest
13-
const Single = 3;
14-
/// Anyone can add inputs to this transaction
15-
const AnyoneCanPay = 0x80;
1+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2+
pub enum SignedOutputs {
3+
/// Sign all the outputs
4+
All,
5+
/// Sign one of the outputs - anyone can spend the rest
6+
Single,
7+
/// Sign none of the outputs - anyone can spend
8+
None,
9+
}
10+
11+
/// The different SigHash types, as defined in <https://zips.z.cash/zip-0143>
12+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
13+
pub struct HashType {
14+
pub signed_outputs: SignedOutputs,
15+
/// Anyone can add inputs to this transaction
16+
pub anyone_can_pay: bool,
17+
}
18+
19+
impl HashType {
20+
pub fn from_bits(bits: i32) -> Option<Self> {
21+
let msigned_outputs = match (bits & 2 != 0, bits & 1 != 0) {
22+
(false, false) => None,
23+
(false, true) => Some(SignedOutputs::All),
24+
(true, false) => Some(SignedOutputs::None),
25+
(true, true) => Some(SignedOutputs::Single),
26+
};
27+
28+
msigned_outputs.map(|signed_outputs| HashType {
29+
signed_outputs,
30+
anyone_can_pay: bits & 0x80 != 0,
31+
})
1632
}
1733
}
1834

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ extern "C" fn sighash_callback(
4747
let ctx = ctx as *const SighashCalculator;
4848
// SAFETY: `ctx` is a valid `SighashCalculator` passed to `verify_callback` which forwards it to
4949
// the `CallbackTransactionSignatureChecker`.
50-
if let Some(sighash) = unsafe { *ctx }(script_code_vec, HashType::from_bits_retain(hash_type)) {
50+
if let Some(sighash) =
51+
HashType::from_bits(hash_type).and_then(|ht| unsafe { *ctx }(script_code_vec, ht))
52+
{
5153
assert_eq!(sighash_out_len, sighash.len().try_into().unwrap());
5254
// SAFETY: `sighash_out` is a valid buffer created in
5355
// `CallbackTransactionSignatureChecker::CheckSig`.

src/zcash_script.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@ use super::interpreter::*;
66
/// replicates the still-used cases, and then an `Unknown` bucket for anything else that might
77
/// happen.
88
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
9-
#[repr(u32)]
109
pub enum Error {
1110
/// Any failure that results in the script being invalid.
12-
Ok = 0,
11+
Ok,
1312
/// An exception was caught.
14-
VerifyScript = 7,
13+
VerifyScript,
1514
/// The script size can’t fit in a `u32`, as required by the C++ code.
1615
InvalidScriptSize(TryFromIntError),
1716
/// Some other failure value recovered from C++.
@@ -21,7 +20,9 @@ pub enum Error {
2120
Unknown(i64),
2221
}
2322

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

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

0 commit comments

Comments
 (0)