Skip to content

Commit

Permalink
Ren sighash flags vars to sflags to avoid confusion with fork flags.
Browse files Browse the repository at this point in the history
  • Loading branch information
evoskuil committed Mar 28, 2024
1 parent b740bcf commit 77f8f03
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 55 deletions.
19 changes: 10 additions & 9 deletions include/bitcoin/system/chain/transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,17 +126,18 @@ class BC_API transaction

// signature_hash exposed for op_check_multisig caching.
hash_digest signature_hash(const input_iterator& input, const script& sub,
uint64_t value, uint8_t flags, script_version version,
uint64_t value, uint8_t sighash_flags, script_version version,
bool bip143) const NOEXCEPT;

bool check_signature(const ec_signature& signature,
const data_slice& public_key, const script& sub, uint32_t index,
uint64_t value, uint8_t flags, script_version version,
uint64_t value, uint8_t sighash_flags, script_version version,
bool bip143) const NOEXCEPT;

bool create_endorsement(endorsement& out, const ec_secret& secret,
const script& sub, uint32_t index, uint64_t value, uint8_t flags,
script_version version, bool bip143) const NOEXCEPT;
const script& sub, uint32_t index, uint64_t value,
uint8_t sighash_flags, script_version version,
bool bip143) const NOEXCEPT;

/// Guards (for tx pool without compact blocks).
/// -----------------------------------------------------------------------
Expand Down Expand Up @@ -226,15 +227,15 @@ class BC_API transaction
input_iterator input_at(uint32_t index) const NOEXCEPT;
uint32_t input_index(const input_iterator& input) const NOEXCEPT;
void signature_hash_single(writer& sink, const input_iterator& input,
const script& sub, uint8_t flags) const NOEXCEPT;
const script& sub, uint8_t sighash_flags) const NOEXCEPT;
void signature_hash_none(writer& sink, const input_iterator& input,
const script& sub, uint8_t flags) const NOEXCEPT;
const script& sub, uint8_t sighash_flags) const NOEXCEPT;
void signature_hash_all(writer& sink, const input_iterator& input,
const script& sub, uint8_t flags) const NOEXCEPT;
const script& sub, uint8_t sighash_flags) const NOEXCEPT;
hash_digest unversioned_signature_hash(const input_iterator& input,
const script& sub, uint8_t flags) const NOEXCEPT;
const script& sub, uint8_t sighash_flags) const NOEXCEPT;
hash_digest version_0_signature_hash(const input_iterator& input,
const script& sub, uint64_t value, uint8_t flags,
const script& sub, uint64_t value, uint8_t sighash_flags,
bool bip143) const NOEXCEPT;

// Transaction should be stored as shared (adds 16 bytes).
Expand Down
7 changes: 4 additions & 3 deletions include/bitcoin/system/impl/machine/interpreter.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -1109,8 +1109,8 @@ op_check_multisig_verify() NOEXCEPT
if (state::pop_strict_bool_() && bip147)
return error::op_check_multisig_verify9;

uint8_t flags;
ec_signature sig;
uint8_t sighash_flags;
typename state::hash_cache cache;

// Subscript is the same for all signatures.
Expand All @@ -1131,11 +1131,12 @@ op_check_multisig_verify() NOEXCEPT
{
// Parse endorsement into DER signature into an EC signature.
// Also generates signature hash from endorsement sighash flags.
if (!state::prepare(sig, *key, cache, flags, **endorsement, *sub))
if (!state::prepare(sig, *key, cache, sighash_flags,
**endorsement, *sub))
return error::op_check_multisig_verify_parse;

BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
const auto& hash = cache.at(flags);
const auto& hash = cache.at(sighash_flags);
BC_POP_WARNING()

// TODO: for signing mode - make key mutable and return above.
Expand Down
19 changes: 10 additions & 9 deletions include/bitcoin/system/impl/machine/program.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -766,15 +766,15 @@ inline bool program<Stack>::
prepare(ec_signature& signature, const data_chunk&, hash_digest& hash,
const chunk_xptr& endorsement) const NOEXCEPT
{
uint8_t flags;
uint8_t sighash_flags;
data_slice distinguished;

// Parse Bitcoin endorsement into DER signature and sighash flags.
if (!parse_endorsement(flags, distinguished, *endorsement))
if (!parse_endorsement(sighash_flags, distinguished, *endorsement))
return false;

// Obtain the signature hash from subscript and sighash flags.
hash = signature_hash(*subscript({ endorsement }), flags);
hash = signature_hash(*subscript({ endorsement }), sighash_flags);

// Parse DER signature into an EC signature (bip66 sets strict).
const auto bip66 = is_enabled(flags::bip66_rule);
Expand All @@ -785,16 +785,17 @@ prepare(ec_signature& signature, const data_chunk&, hash_digest& hash,
template <typename Stack>
inline bool program<Stack>::
prepare(ec_signature& signature, const data_chunk&, hash_cache& cache,
uint8_t& flags, const data_chunk& endorsement, const script& sub) const NOEXCEPT
uint8_t& sighash_flags, const data_chunk& endorsement,
const script& sub) const NOEXCEPT
{
data_slice distinguished;

// Parse Bitcoin endorsement into DER signature and sighash flags.
if (!parse_endorsement(flags, distinguished, endorsement))
if (!parse_endorsement(sighash_flags, distinguished, endorsement))
return false;

// Obtain the signature hash from subscript and sighash flags.
signature_hash(cache, sub, flags);
signature_hash(cache, sub, sighash_flags);

// Parse DER signature into an EC signature (bip66 sets strict).
const auto bip66 = is_enabled(flags::bip66_rule);
Expand All @@ -821,11 +822,11 @@ signature_hash(const script& sub, uint8_t flags) const NOEXCEPT
template <typename Stack>
INLINE void program<Stack>::
signature_hash(hash_cache& cache, const script& sub,
uint8_t flags) const NOEXCEPT
uint8_t sighash_flags) const NOEXCEPT
{
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
if (cache.find(flags) == cache.end())
cache.emplace(flags, signature_hash(sub, flags));
if (cache.find(sighash_flags) == cache.end())
cache.emplace(sighash_flags, signature_hash(sub, sighash_flags));
BC_POP_WARNING()
}

Expand Down
2 changes: 1 addition & 1 deletion include/bitcoin/system/machine/program.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class program

/// Prepare signature, with caching for multisig with same sighash flags.
inline bool prepare(ec_signature& signature, const data_chunk& key,
hash_cache& cache, uint8_t& flags, const data_chunk& endorsement,
hash_cache& cache, uint8_t& sighash_flags, const data_chunk& endorsement,
const chain::script& sub) const NOEXCEPT;

private:
Expand Down
66 changes: 33 additions & 33 deletions src/chain/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,9 +570,9 @@ uint32_t transaction::input_index(const input_iterator& input) const NOEXCEPT
// there are 4 possible 7 bit values that can set "single" and 4 others that
// can set none, and yet all other values set "all".
//*****************************************************************************
inline coverage mask_sighash(uint8_t flags) NOEXCEPT
inline coverage mask_sighash(uint8_t sighash_flags) NOEXCEPT
{
switch (flags & coverage::mask)
switch (sighash_flags & coverage::mask)
{
case coverage::hash_single:
return coverage::hash_single;
Expand All @@ -586,13 +586,13 @@ inline coverage mask_sighash(uint8_t flags) NOEXCEPT
/// REQUIRES INDEX.
void transaction::signature_hash_single(writer& sink,
const input_iterator& input, const script& sub,
uint8_t flags) const NOEXCEPT
uint8_t sighash_flags) const NOEXCEPT
{
const auto write_inputs = [this, &input, &sub, flags](
const auto write_inputs = [this, &input, &sub, sighash_flags](
writer& sink) NOEXCEPT
{
const auto& self = **input;
const auto anyone = to_bool(flags & coverage::anyone_can_pay);
const auto anyone = to_bool(sighash_flags & coverage::anyone_can_pay);
input_cptrs::const_iterator in;

sink.write_variable(anyone ? one : inputs_->size());
Expand Down Expand Up @@ -634,18 +634,18 @@ void transaction::signature_hash_single(writer& sink,
write_inputs(sink);
write_outputs(sink);
sink.write_4_bytes_little_endian(locktime_);
sink.write_4_bytes_little_endian(flags);
sink.write_4_bytes_little_endian(sighash_flags);
}

void transaction::signature_hash_none(writer& sink,
const input_iterator& input, const script& sub,
uint8_t flags) const NOEXCEPT
uint8_t sighash_flags) const NOEXCEPT
{
const auto write_inputs = [this, &input, &sub, flags](
const auto write_inputs = [this, &input, &sub, sighash_flags](
writer& sink) NOEXCEPT
{
const auto& self = **input;
const auto anyone = to_bool(flags & coverage::anyone_can_pay);
const auto anyone = to_bool(sighash_flags & coverage::anyone_can_pay);
input_cptrs::const_iterator in;

sink.write_variable(anyone ? one : inputs_->size());
Expand Down Expand Up @@ -673,7 +673,7 @@ void transaction::signature_hash_none(writer& sink,
write_inputs(sink);
sink.write_variable(zero);
sink.write_4_bytes_little_endian(locktime_);
sink.write_4_bytes_little_endian(flags);
sink.write_4_bytes_little_endian(sighash_flags);
}

void transaction::signature_hash_all(writer& sink,
Expand Down Expand Up @@ -725,10 +725,10 @@ void transaction::signature_hash_all(writer& sink,
// private
hash_digest transaction::unversioned_signature_hash(
const input_iterator& input, const script& sub,
uint8_t flags) const NOEXCEPT
uint8_t sighash_flags) const NOEXCEPT
{
// Set options.
const auto flag = mask_sighash(flags);
const auto flag = mask_sighash(sighash_flags);

// Create hash writer.
BC_PUSH_WARNING(LOCAL_VARIABLE_NOT_INITIALIZED)
Expand All @@ -750,15 +750,15 @@ hash_digest transaction::unversioned_signature_hash(
if (input_index(input) >= outputs_->size())
return one_hash;

signature_hash_single(sink, input, sub, flags);
signature_hash_single(sink, input, sub, sighash_flags);
break;
}
case coverage::hash_none:
signature_hash_none(sink, input, sub, flags);
signature_hash_none(sink, input, sub, sighash_flags);
break;
default:
case coverage::hash_all:
signature_hash_all(sink, input, sub, flags);
signature_hash_all(sink, input, sub, sighash_flags);
}

sink.flush();
Expand Down Expand Up @@ -813,17 +813,17 @@ hash_digest transaction::output_hash(const input_iterator& input) const NOEXCEPT

// private
hash_digest transaction::version_0_signature_hash(const input_iterator& input,
const script& sub, uint64_t value, uint8_t flags,
const script& sub, uint64_t value, uint8_t sighash_flags,
bool bip143) const NOEXCEPT
{
// bip143/v0: the way of serialization is changed.
if (!bip143)
return unversioned_signature_hash(input, sub, flags);
return unversioned_signature_hash(input, sub, sighash_flags);

// Set options.
// C++14: switch in constexpr.
const auto anyone = to_bool(flags & coverage::anyone_can_pay);
const auto flag = mask_sighash(flags);
const auto anyone = to_bool(sighash_flags & coverage::anyone_can_pay);
const auto flag = mask_sighash(sighash_flags);
const auto all = (flag == coverage::hash_all);
const auto single = (flag == coverage::hash_single);
const auto& self = **input;
Expand Down Expand Up @@ -868,7 +868,7 @@ hash_digest transaction::version_0_signature_hash(const input_iterator& input,
sink.write_bytes(all ? outputs_hash() : null_hash);

sink.write_little_endian(locktime_);
sink.write_4_bytes_little_endian(flags);
sink.write_4_bytes_little_endian(sighash_flags);

sink.flush();
return digest;
Expand All @@ -883,18 +883,19 @@ hash_digest transaction::version_0_signature_hash(const input_iterator& input,
// ****************************************************************************

hash_digest transaction::signature_hash(const input_iterator& input,
const script& sub, uint64_t value, uint8_t flags, script_version version,
bool bip143) const NOEXCEPT
const script& sub, uint64_t value, uint8_t sighash_flags,
script_version version, bool bip143) const NOEXCEPT
{
// There is no rational interpretation of a signature hash for a coinbase.
BC_ASSERT(!is_coinbase());

switch (version)
{
case script_version::unversioned:
return unversioned_signature_hash(input, sub, flags);
return unversioned_signature_hash(input, sub, sighash_flags);
case script_version::zero:
return version_0_signature_hash(input, sub, value, flags, bip143);
return version_0_signature_hash(input, sub, value, sighash_flags,
bip143);
case script_version::reserved:
default:
return {};
Expand All @@ -904,39 +905,38 @@ hash_digest transaction::signature_hash(const input_iterator& input,
// This is not used internal to the library.
bool transaction::check_signature(const ec_signature& signature,
const data_slice& public_key, const script& sub, uint32_t index,
uint64_t value, uint8_t flags, script_version version,
uint64_t value, uint8_t sighash_flags, script_version version,
bool bip143) const NOEXCEPT
{
if ((index >= inputs_->size()) ||
signature.empty() || public_key.empty())
if ((index >= inputs_->size()) || signature.empty() || public_key.empty())
return false;

const auto sighash = signature_hash(input_at(index), sub, value, flags,
version, bip143);
const auto sighash = signature_hash(input_at(index), sub, value,
sighash_flags, version, bip143);

// Validate the EC signature.
return verify_signature(public_key, sighash, signature);
}

// This is not used internal to the library.
bool transaction::create_endorsement(endorsement& out, const ec_secret& secret,
const script& sub, uint32_t index, uint64_t value, uint8_t flags,
const script& sub, uint32_t index, uint64_t value, uint8_t sighash_flags,
script_version version, bool bip143) const NOEXCEPT
{
if (index >= inputs_->size())
return false;

out.reserve(max_endorsement_size);
const auto sighash = signature_hash(input_at(index), sub, value, flags,
version, bip143);
const auto sighash = signature_hash(input_at(index), sub, value,
sighash_flags, version, bip143);

// Create the EC signature and encode as DER.
ec_signature signature;
if (!sign(signature, secret, sighash) || !encode_signature(out, signature))
return false;

// Add the sighash type to the end of the DER signature -> endorsement.
out.push_back(flags);
out.push_back(sighash_flags);
out.shrink_to_fit();
return true;
}
Expand Down

0 comments on commit 77f8f03

Please sign in to comment.