mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-09 10:43:19 -05:00
Merge bitcoin/bitcoin#23413: Replace MakeSpan helper with Span deduction guide
11daf6ceb1
More Span simplifications (Pieter Wuille)568dd2f839
Replace MakeSpan helper with Span deduction guide (Pieter Wuille) Pull request description: C++17 supports [user-defined deduction guides](https://en.cppreference.com/w/cpp/language/class_template_argument_deduction), allowing class constructors to be invoked without specifying class template arguments. Instead, the code can contain rules to infer the template arguments from the constructor argument types. This alleviates the need for the `MakeSpan` helper. Convert the existing MakeSpan rules into deduction rules for `Span` itself, and replace all invocations of `MakeSpan` with just `Span` ones. ACKs for top commit: MarcoFalke: re-ACK11daf6ceb1
Only change is removing a hunk in the tests 🌕 Tree-SHA512: 10f3e82e4338f39d9b7b407cd11aac7ebe1e9191b58e3d7f4e5e338a4636c0e126b4a1d912127c7446f57ba356c8d6544482e47f97901efea6a54fffbfd7895f
This commit is contained in:
commit
8b1de78577
25 changed files with 125 additions and 124 deletions
|
@ -149,7 +149,7 @@ std::string EncodeBase58Check(Span<const unsigned char> input)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// re-calculate the checksum, ensure it matches the included 4-byte checksum
|
// re-calculate the checksum, ensure it matches the included 4-byte checksum
|
||||||
uint256 hash = Hash(MakeSpan(vchRet).first(vchRet.size() - 4));
|
uint256 hash = Hash(Span{vchRet}.first(vchRet.size() - 4));
|
||||||
if (memcmp(&hash, &vchRet[vchRet.size() - 4], 4) != 0) {
|
if (memcmp(&hash, &vchRet[vchRet.size() - 4], 4) != 0) {
|
||||||
vchRet.clear();
|
vchRet.clear();
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -65,12 +65,12 @@ struct ScriptCompression
|
||||||
void Ser(Stream &s, const CScript& script) {
|
void Ser(Stream &s, const CScript& script) {
|
||||||
CompressedScript compr;
|
CompressedScript compr;
|
||||||
if (CompressScript(script, compr)) {
|
if (CompressScript(script, compr)) {
|
||||||
s << MakeSpan(compr);
|
s << Span{compr};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned int nSize = script.size() + nSpecialScripts;
|
unsigned int nSize = script.size() + nSpecialScripts;
|
||||||
s << VARINT(nSize);
|
s << VARINT(nSize);
|
||||||
s << MakeSpan(script);
|
s << Span{script};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Stream>
|
template<typename Stream>
|
||||||
|
@ -79,7 +79,7 @@ struct ScriptCompression
|
||||||
s >> VARINT(nSize);
|
s >> VARINT(nSize);
|
||||||
if (nSize < nSpecialScripts) {
|
if (nSize < nSpecialScripts) {
|
||||||
CompressedScript vch(GetSpecialScriptSize(nSize), 0x00);
|
CompressedScript vch(GetSpecialScriptSize(nSize), 0x00);
|
||||||
s >> MakeSpan(vch);
|
s >> Span{vch};
|
||||||
DecompressScript(script, nSize, vch);
|
DecompressScript(script, nSize, vch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ struct ScriptCompression
|
||||||
s.ignore(nSize);
|
s.ignore(nSize);
|
||||||
} else {
|
} else {
|
||||||
script.resize(nSize);
|
script.resize(nSize);
|
||||||
s >> MakeSpan(script);
|
s >> Span{script};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -761,7 +761,7 @@ CNetMessage V1TransportDeserializer::GetMessage(const std::chrono::microseconds
|
||||||
if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0) {
|
if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0) {
|
||||||
LogPrint(BCLog::NET, "Header error: Wrong checksum (%s, %u bytes), expected %s was %s, peer=%d\n",
|
LogPrint(BCLog::NET, "Header error: Wrong checksum (%s, %u bytes), expected %s was %s, peer=%d\n",
|
||||||
SanitizeString(msg.m_command), msg.m_message_size,
|
SanitizeString(msg.m_command), msg.m_message_size,
|
||||||
HexStr(Span<uint8_t>(hash.begin(), hash.begin() + CMessageHeader::CHECKSUM_SIZE)),
|
HexStr(Span{hash}.first(CMessageHeader::CHECKSUM_SIZE)),
|
||||||
HexStr(hdr.pchChecksum),
|
HexStr(hdr.pchChecksum),
|
||||||
m_node_id);
|
m_node_id);
|
||||||
reject_message = true;
|
reject_message = true;
|
||||||
|
@ -1583,8 +1583,9 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
|
||||||
if (nBytes > 0)
|
if (nBytes > 0)
|
||||||
{
|
{
|
||||||
bool notify = false;
|
bool notify = false;
|
||||||
if (!pnode->ReceiveMsgBytes(Span<const uint8_t>(pchBuf, nBytes), notify))
|
if (!pnode->ReceiveMsgBytes({pchBuf, (size_t)nBytes}, notify)) {
|
||||||
pnode->CloseSocketDisconnect();
|
pnode->CloseSocketDisconnect();
|
||||||
|
}
|
||||||
RecordBytesRecv(nBytes);
|
RecordBytesRecv(nBytes);
|
||||||
if (notify) {
|
if (notify) {
|
||||||
size_t nSizeAdded = 0;
|
size_t nSizeAdded = 0;
|
||||||
|
|
|
@ -1815,7 +1815,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
|
||||||
if (!ReadRawBlockFromDisk(block_data, pindex, m_chainparams.MessageStart())) {
|
if (!ReadRawBlockFromDisk(block_data, pindex, m_chainparams.MessageStart())) {
|
||||||
assert(!"cannot load block from disk");
|
assert(!"cannot load block from disk");
|
||||||
}
|
}
|
||||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::BLOCK, MakeSpan(block_data)));
|
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::BLOCK, Span{block_data}));
|
||||||
// Don't set pblock as we've sent the block
|
// Don't set pblock as we've sent the block
|
||||||
} else {
|
} else {
|
||||||
// Send block from disk
|
// Send block from disk
|
||||||
|
|
|
@ -196,7 +196,7 @@ static void Checksum(Span<const uint8_t> addr_pubkey, uint8_t (&checksum)[CHECKS
|
||||||
|
|
||||||
SHA3_256 hasher;
|
SHA3_256 hasher;
|
||||||
|
|
||||||
hasher.Write(MakeSpan(prefix).first(prefix_len));
|
hasher.Write(Span{prefix}.first(prefix_len));
|
||||||
hasher.Write(addr_pubkey);
|
hasher.Write(addr_pubkey);
|
||||||
hasher.Write(VERSION);
|
hasher.Write(VERSION);
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)
|
||||||
|
|
||||||
CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope)
|
CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope)
|
||||||
{
|
{
|
||||||
SetLegacyIPv6(Span<const uint8_t>(reinterpret_cast<const uint8_t*>(&ipv6Addr), sizeof(ipv6Addr)));
|
SetLegacyIPv6({reinterpret_cast<const uint8_t*>(&ipv6Addr), sizeof(ipv6Addr)});
|
||||||
m_scope_id = scope;
|
m_scope_id = scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,13 +693,13 @@ uint32_t CNetAddr::GetLinkedIPv4() const
|
||||||
return ReadBE32(m_addr.data());
|
return ReadBE32(m_addr.data());
|
||||||
} else if (IsRFC6052() || IsRFC6145()) {
|
} else if (IsRFC6052() || IsRFC6145()) {
|
||||||
// mapped IPv4, SIIT translated IPv4: the IPv4 address is the last 4 bytes of the address
|
// mapped IPv4, SIIT translated IPv4: the IPv4 address is the last 4 bytes of the address
|
||||||
return ReadBE32(MakeSpan(m_addr).last(ADDR_IPV4_SIZE).data());
|
return ReadBE32(Span{m_addr}.last(ADDR_IPV4_SIZE).data());
|
||||||
} else if (IsRFC3964()) {
|
} else if (IsRFC3964()) {
|
||||||
// 6to4 tunneled IPv4: the IPv4 address is in bytes 2-6
|
// 6to4 tunneled IPv4: the IPv4 address is in bytes 2-6
|
||||||
return ReadBE32(MakeSpan(m_addr).subspan(2, ADDR_IPV4_SIZE).data());
|
return ReadBE32(Span{m_addr}.subspan(2, ADDR_IPV4_SIZE).data());
|
||||||
} else if (IsRFC4380()) {
|
} else if (IsRFC4380()) {
|
||||||
// Teredo tunneled IPv4: the IPv4 address is in the last 4 bytes of the address, but bitflipped
|
// Teredo tunneled IPv4: the IPv4 address is in the last 4 bytes of the address, but bitflipped
|
||||||
return ~ReadBE32(MakeSpan(m_addr).last(ADDR_IPV4_SIZE).data());
|
return ~ReadBE32(Span{m_addr}.last(ADDR_IPV4_SIZE).data());
|
||||||
}
|
}
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -433,7 +433,7 @@ private:
|
||||||
|
|
||||||
if (SetNetFromBIP155Network(bip155_net, address_size)) {
|
if (SetNetFromBIP155Network(bip155_net, address_size)) {
|
||||||
m_addr.resize(address_size);
|
m_addr.resize(address_size);
|
||||||
s >> MakeSpan(m_addr);
|
s >> Span{m_addr};
|
||||||
|
|
||||||
if (m_net != NET_IPV6) {
|
if (m_net != NET_IPV6) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -251,7 +251,7 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
|
||||||
// - No annexes
|
// - No annexes
|
||||||
if (witnessversion == 1 && witnessprogram.size() == WITNESS_V1_TAPROOT_SIZE && !p2sh) {
|
if (witnessversion == 1 && witnessprogram.size() == WITNESS_V1_TAPROOT_SIZE && !p2sh) {
|
||||||
// Taproot spend (non-P2SH-wrapped, version 1, witness program size 32; see BIP 341)
|
// Taproot spend (non-P2SH-wrapped, version 1, witness program size 32; see BIP 341)
|
||||||
auto stack = MakeSpan(tx.vin[i].scriptWitness.stack);
|
Span stack{tx.vin[i].scriptWitness.stack};
|
||||||
if (stack.size() >= 2 && !stack.back().empty() && stack.back()[0] == ANNEX_TAG) {
|
if (stack.size() >= 2 && !stack.back().empty() && stack.back()[0] == ANNEX_TAG) {
|
||||||
// Annexes are nonstandard as long as no semantics are defined for them.
|
// Annexes are nonstandard as long as no semantics are defined for them.
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -81,7 +81,7 @@ struct PSBTInput
|
||||||
if (final_script_sig.empty() && final_script_witness.IsNull()) {
|
if (final_script_sig.empty() && final_script_witness.IsNull()) {
|
||||||
// Write any partial signatures
|
// Write any partial signatures
|
||||||
for (auto sig_pair : partial_sigs) {
|
for (auto sig_pair : partial_sigs) {
|
||||||
SerializeToVector(s, PSBT_IN_PARTIAL_SIG, MakeSpan(sig_pair.second.first));
|
SerializeToVector(s, PSBT_IN_PARTIAL_SIG, Span{sig_pair.second.first});
|
||||||
s << sig_pair.second.second;
|
s << sig_pair.second.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,13 +157,13 @@ public:
|
||||||
//! Get the KeyID of this public key (hash of its serialization)
|
//! Get the KeyID of this public key (hash of its serialization)
|
||||||
CKeyID GetID() const
|
CKeyID GetID() const
|
||||||
{
|
{
|
||||||
return CKeyID(Hash160(MakeSpan(vch).first(size())));
|
return CKeyID(Hash160(Span{vch}.first(size())));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Get the 256-bit hash of this public key.
|
//! Get the 256-bit hash of this public key.
|
||||||
uint256 GetHash() const
|
uint256 GetHash() const
|
||||||
{
|
{
|
||||||
return Hash(MakeSpan(vch).first(size()));
|
return Hash(Span{vch}.first(size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -240,7 +240,7 @@ public:
|
||||||
explicit XOnlyPubKey(Span<const unsigned char> bytes);
|
explicit XOnlyPubKey(Span<const unsigned char> bytes);
|
||||||
|
|
||||||
/** Construct an x-only pubkey from a normal pubkey. */
|
/** Construct an x-only pubkey from a normal pubkey. */
|
||||||
explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(Span<const unsigned char>(pubkey.begin() + 1, pubkey.begin() + 33)) {}
|
explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(Span{pubkey}.subspan(1, 32)) {}
|
||||||
|
|
||||||
/** Verify a Schnorr signature against this public key.
|
/** Verify a Schnorr signature against this public key.
|
||||||
*
|
*
|
||||||
|
|
|
@ -317,7 +317,7 @@ public:
|
||||||
UniValue obj(UniValue::VOBJ);
|
UniValue obj(UniValue::VOBJ);
|
||||||
obj.pushKV("iswitness", true);
|
obj.pushKV("iswitness", true);
|
||||||
obj.pushKV("witness_version", (int)id.version);
|
obj.pushKV("witness_version", (int)id.version);
|
||||||
obj.pushKV("witness_program", HexStr(Span<const unsigned char>(id.program, id.length)));
|
obj.pushKV("witness_program", HexStr({id.program, id.length}));
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -631,7 +631,7 @@ public:
|
||||||
out.origins.emplace(entry.first.GetID(), std::make_pair<CPubKey, KeyOriginInfo>(CPubKey(entry.first), std::move(entry.second)));
|
out.origins.emplace(entry.first.GetID(), std::make_pair<CPubKey, KeyOriginInfo>(CPubKey(entry.first), std::move(entry.second)));
|
||||||
}
|
}
|
||||||
|
|
||||||
output_scripts = MakeScripts(pubkeys, MakeSpan(subscripts), out);
|
output_scripts = MakeScripts(pubkeys, Span{subscripts}, out);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -974,10 +974,10 @@ std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const S
|
||||||
}
|
}
|
||||||
KeyPath path;
|
KeyPath path;
|
||||||
DeriveType type = DeriveType::NO;
|
DeriveType type = DeriveType::NO;
|
||||||
if (split.back() == MakeSpan("*").first(1)) {
|
if (split.back() == Span{"*"}.first(1)) {
|
||||||
split.pop_back();
|
split.pop_back();
|
||||||
type = DeriveType::UNHARDENED;
|
type = DeriveType::UNHARDENED;
|
||||||
} else if (split.back() == MakeSpan("*'").first(2) || split.back() == MakeSpan("*h").first(2)) {
|
} else if (split.back() == Span{"*'"}.first(2) || split.back() == Span{"*h"}.first(2)) {
|
||||||
split.pop_back();
|
split.pop_back();
|
||||||
type = DeriveType::HARDENED;
|
type = DeriveType::HARDENED;
|
||||||
}
|
}
|
||||||
|
@ -1252,7 +1252,7 @@ std::unique_ptr<PubkeyProvider> InferXOnlyPubkey(const XOnlyPubKey& xkey, ParseS
|
||||||
std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
|
std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
|
||||||
{
|
{
|
||||||
if (ctx == ParseScriptContext::P2TR && script.size() == 34 && script[0] == 32 && script[33] == OP_CHECKSIG) {
|
if (ctx == ParseScriptContext::P2TR && script.size() == 34 && script[0] == 32 && script[33] == OP_CHECKSIG) {
|
||||||
XOnlyPubKey key{Span<const unsigned char>{script.data() + 1, script.data() + 33}};
|
XOnlyPubKey key{Span{script}.subspan(1, 32)};
|
||||||
return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider));
|
return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1858,7 +1858,7 @@ uint256 ComputeTaprootMerkleRoot(Span<const unsigned char> control, const uint25
|
||||||
uint256 k = tapleaf_hash;
|
uint256 k = tapleaf_hash;
|
||||||
for (int i = 0; i < path_len; ++i) {
|
for (int i = 0; i < path_len; ++i) {
|
||||||
CHashWriter ss_branch{HASHER_TAPBRANCH};
|
CHashWriter ss_branch{HASHER_TAPBRANCH};
|
||||||
Span<const unsigned char> node(control.data() + TAPROOT_CONTROL_BASE_SIZE + TAPROOT_CONTROL_NODE_SIZE * i, TAPROOT_CONTROL_NODE_SIZE);
|
Span node{Span{control}.subspan(TAPROOT_CONTROL_BASE_SIZE + TAPROOT_CONTROL_NODE_SIZE * i, TAPROOT_CONTROL_NODE_SIZE)};
|
||||||
if (std::lexicographical_compare(k.begin(), k.end(), node.begin(), node.end())) {
|
if (std::lexicographical_compare(k.begin(), k.end(), node.begin(), node.end())) {
|
||||||
ss_branch << k << node;
|
ss_branch << k << node;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1874,7 +1874,7 @@ static bool VerifyTaprootCommitment(const std::vector<unsigned char>& control, c
|
||||||
assert(control.size() >= TAPROOT_CONTROL_BASE_SIZE);
|
assert(control.size() >= TAPROOT_CONTROL_BASE_SIZE);
|
||||||
assert(program.size() >= uint256::size());
|
assert(program.size() >= uint256::size());
|
||||||
//! The internal pubkey (x-only, so no Y coordinate parity).
|
//! The internal pubkey (x-only, so no Y coordinate parity).
|
||||||
const XOnlyPubKey p{Span<const unsigned char>{control.data() + 1, control.data() + TAPROOT_CONTROL_BASE_SIZE}};
|
const XOnlyPubKey p{Span{control}.subspan(1, TAPROOT_CONTROL_BASE_SIZE - 1)};
|
||||||
//! The output pubkey (taken from the scriptPubKey).
|
//! The output pubkey (taken from the scriptPubKey).
|
||||||
const XOnlyPubKey q{program};
|
const XOnlyPubKey q{program};
|
||||||
// Compute the Merkle root from the leaf and the provided path.
|
// Compute the Merkle root from the leaf and the provided path.
|
||||||
|
@ -1886,7 +1886,7 @@ static bool VerifyTaprootCommitment(const std::vector<unsigned char>& control, c
|
||||||
static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion, const std::vector<unsigned char>& program, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror, bool is_p2sh)
|
static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion, const std::vector<unsigned char>& program, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror, bool is_p2sh)
|
||||||
{
|
{
|
||||||
CScript exec_script; //!< Actually executed script (last stack item in P2WSH; implied P2PKH script in P2WPKH; leaf script in P2TR)
|
CScript exec_script; //!< Actually executed script (last stack item in P2WSH; implied P2PKH script in P2WPKH; leaf script in P2TR)
|
||||||
Span<const valtype> stack{witness.stack};
|
Span stack{witness.stack};
|
||||||
ScriptExecutionData execdata;
|
ScriptExecutionData execdata;
|
||||||
|
|
||||||
if (witversion == 0) {
|
if (witversion == 0) {
|
||||||
|
|
|
@ -167,7 +167,7 @@ static bool SignTaprootScript(const SigningProvider& provider, const BaseSignatu
|
||||||
|
|
||||||
// <xonly pubkey> OP_CHECKSIG
|
// <xonly pubkey> OP_CHECKSIG
|
||||||
if (script.size() == 34 && script[33] == OP_CHECKSIG && script[0] == 0x20) {
|
if (script.size() == 34 && script[33] == OP_CHECKSIG && script[0] == 0x20) {
|
||||||
XOnlyPubKey pubkey(MakeSpan(script).subspan(1, 32));
|
XOnlyPubKey pubkey{Span{script}.subspan(1, 32)};
|
||||||
std::vector<unsigned char> sig;
|
std::vector<unsigned char> sig;
|
||||||
if (CreateTaprootScriptSig(creator, sigdata, provider, sig, pubkey, leaf_hash, sigversion)) {
|
if (CreateTaprootScriptSig(creator, sigdata, provider, sig, pubkey, leaf_hash, sigversion)) {
|
||||||
result = Vector(std::move(sig));
|
result = Vector(std::move(sig));
|
||||||
|
|
|
@ -149,7 +149,7 @@ void SerializeHDKeypaths(Stream& s, const std::map<CPubKey, KeyOriginInfo>& hd_k
|
||||||
if (!keypath_pair.first.IsValid()) {
|
if (!keypath_pair.first.IsValid()) {
|
||||||
throw std::ios_base::failure("Invalid CPubKey being serialized");
|
throw std::ios_base::failure("Invalid CPubKey being serialized");
|
||||||
}
|
}
|
||||||
SerializeToVector(s, type, MakeSpan(keypath_pair.first));
|
SerializeToVector(s, type, Span{keypath_pair.first});
|
||||||
WriteCompactSize(s, (keypath_pair.second.path.size() + 1) * sizeof(uint32_t));
|
WriteCompactSize(s, (keypath_pair.second.path.size() + 1) * sizeof(uint32_t));
|
||||||
s << keypath_pair.second.fingerprint;
|
s << keypath_pair.second.fingerprint;
|
||||||
for (const auto& path : keypath_pair.second.path) {
|
for (const auto& path : keypath_pair.second.path) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ static bool FetchAndClearCommitmentSection(const Span<const uint8_t> header, CSc
|
||||||
std::vector<uint8_t> pushdata;
|
std::vector<uint8_t> pushdata;
|
||||||
while (witness_commitment.GetOp(pc, opcode, pushdata)) {
|
while (witness_commitment.GetOp(pc, opcode, pushdata)) {
|
||||||
if (pushdata.size() > 0) {
|
if (pushdata.size() > 0) {
|
||||||
if (!found_header && pushdata.size() > (size_t) header.size() && Span<const uint8_t>(pushdata.data(), header.size()) == header) {
|
if (!found_header && pushdata.size() > (size_t)header.size() && Span{pushdata}.first(header.size()) == header) {
|
||||||
// pushdata only counts if it has the header _and_ some data
|
// pushdata only counts if it has the header _and_ some data
|
||||||
result.insert(result.end(), pushdata.begin() + header.size(), pushdata.end());
|
result.insert(result.end(), pushdata.begin() + header.size(), pushdata.end());
|
||||||
pushdata.erase(pushdata.begin() + header.size(), pushdata.end());
|
pushdata.erase(pushdata.begin() + header.size(), pushdata.end());
|
||||||
|
|
24
src/span.h
24
src/span.h
|
@ -222,13 +222,15 @@ public:
|
||||||
template <typename O> friend class Span;
|
template <typename O> friend class Span;
|
||||||
};
|
};
|
||||||
|
|
||||||
// MakeSpan helps constructing a Span of the right type automatically.
|
// Deduction guides for Span
|
||||||
/** MakeSpan for arrays: */
|
// For the pointer/size based and iterator based constructor:
|
||||||
template <typename A, int N> Span<A> constexpr MakeSpan(A (&a)[N]) { return Span<A>(a, N); }
|
template <typename T, typename EndOrSize> Span(T*, EndOrSize) -> Span<T>;
|
||||||
/** MakeSpan for temporaries / rvalue references, only supporting const output. */
|
// For the array constructor:
|
||||||
template <typename V> constexpr auto MakeSpan(V&& v SPAN_ATTR_LIFETIMEBOUND) -> typename std::enable_if<!std::is_lvalue_reference<V>::value, Span<const typename std::remove_pointer<decltype(v.data())>::type>>::type { return std::forward<V>(v); }
|
template <typename T, std::size_t N> Span(T (&)[N]) -> Span<T>;
|
||||||
/** MakeSpan for (lvalue) references, supporting mutable output. */
|
// For the temporaries/rvalue references constructor, only supporting const output.
|
||||||
template <typename V> constexpr auto MakeSpan(V& v SPAN_ATTR_LIFETIMEBOUND) -> Span<typename std::remove_pointer<decltype(v.data())>::type> { return v; }
|
template <typename T> Span(T&&) -> Span<std::enable_if_t<!std::is_lvalue_reference_v<T>, const std::remove_pointer_t<decltype(std::declval<T&&>().data())>>>;
|
||||||
|
// For (lvalue) references, supporting mutable output.
|
||||||
|
template <typename T> Span(T&) -> Span<std::remove_pointer_t<decltype(std::declval<T&>().data())>>;
|
||||||
|
|
||||||
/** Pop the last element off a span, and return a reference to that element. */
|
/** Pop the last element off a span, and return a reference to that element. */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -256,12 +258,12 @@ Span<std::byte> AsWritableBytes(Span<T> s) noexcept
|
||||||
template <typename V>
|
template <typename V>
|
||||||
Span<const std::byte> MakeByteSpan(V&& v) noexcept
|
Span<const std::byte> MakeByteSpan(V&& v) noexcept
|
||||||
{
|
{
|
||||||
return AsBytes(MakeSpan(std::forward<V>(v)));
|
return AsBytes(Span{std::forward<V>(v)});
|
||||||
}
|
}
|
||||||
template <typename V>
|
template <typename V>
|
||||||
Span<std::byte> MakeWritableByteSpan(V&& v) noexcept
|
Span<std::byte> MakeWritableByteSpan(V&& v) noexcept
|
||||||
{
|
{
|
||||||
return AsWritableBytes(MakeSpan(std::forward<V>(v)));
|
return AsWritableBytes(Span{std::forward<V>(v)});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper functions to safely cast to unsigned char pointers.
|
// Helper functions to safely cast to unsigned char pointers.
|
||||||
|
@ -274,7 +276,7 @@ inline const unsigned char* UCharCast(const std::byte* c) { return reinterpret_c
|
||||||
// Helper function to safely convert a Span to a Span<[const] unsigned char>.
|
// Helper function to safely convert a Span to a Span<[const] unsigned char>.
|
||||||
template <typename T> constexpr auto UCharSpanCast(Span<T> s) -> Span<typename std::remove_pointer<decltype(UCharCast(s.data()))>::type> { return {UCharCast(s.data()), s.size()}; }
|
template <typename T> constexpr auto UCharSpanCast(Span<T> s) -> Span<typename std::remove_pointer<decltype(UCharCast(s.data()))>::type> { return {UCharCast(s.data()), s.size()}; }
|
||||||
|
|
||||||
/** Like MakeSpan, but for (const) unsigned char member types only. Only works for (un)signed char containers. */
|
/** Like the Span constructor, but for (const) unsigned char member types only. Only works for (un)signed char containers. */
|
||||||
template <typename V> constexpr auto MakeUCharSpan(V&& v) -> decltype(UCharSpanCast(MakeSpan(std::forward<V>(v)))) { return UCharSpanCast(MakeSpan(std::forward<V>(v))); }
|
template <typename V> constexpr auto MakeUCharSpan(V&& v) -> decltype(UCharSpanCast(Span{std::forward<V>(v)})) { return UCharSpanCast(Span{std::forward<V>(v)}); }
|
||||||
|
|
||||||
#endif // BITCOIN_SPAN_H
|
#endif // BITCOIN_SPAN_H
|
||||||
|
|
|
@ -770,8 +770,8 @@ static void TestSHA3_256(const std::string& input, const std::string& output)
|
||||||
int s1 = InsecureRandRange(in_bytes.size() + 1);
|
int s1 = InsecureRandRange(in_bytes.size() + 1);
|
||||||
int s2 = InsecureRandRange(in_bytes.size() + 1 - s1);
|
int s2 = InsecureRandRange(in_bytes.size() + 1 - s1);
|
||||||
int s3 = in_bytes.size() - s1 - s2;
|
int s3 = in_bytes.size() - s1 - s2;
|
||||||
sha.Write(MakeSpan(in_bytes).first(s1)).Write(MakeSpan(in_bytes).subspan(s1, s2));
|
sha.Write(Span{in_bytes}.first(s1)).Write(Span{in_bytes}.subspan(s1, s2));
|
||||||
sha.Write(MakeSpan(in_bytes).last(s3)).Finalize(out);
|
sha.Write(Span{in_bytes}.last(s3)).Finalize(out);
|
||||||
BOOST_CHECK(std::equal(std::begin(out_bytes), std::end(out_bytes), out));
|
BOOST_CHECK(std::equal(std::begin(out_bytes), std::end(out_bytes), out));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ FUZZ_TARGET(asmap)
|
||||||
CNetAddr net_addr;
|
CNetAddr net_addr;
|
||||||
if (ipv6) {
|
if (ipv6) {
|
||||||
assert(addr_size == ADDR_IPV6_SIZE);
|
assert(addr_size == ADDR_IPV6_SIZE);
|
||||||
net_addr.SetLegacyIPv6(Span<const uint8_t>(addr_data, addr_size));
|
net_addr.SetLegacyIPv6({addr_data, addr_size});
|
||||||
} else {
|
} else {
|
||||||
assert(addr_size == ADDR_IPV4_SIZE);
|
assert(addr_size == ADDR_IPV4_SIZE);
|
||||||
in_addr ipv4;
|
in_addr ipv4;
|
||||||
|
|
|
@ -38,7 +38,7 @@ FUZZ_TARGET_INIT(utxo_snapshot, initialize_chain)
|
||||||
{
|
{
|
||||||
CAutoFile outfile{fsbridge::fopen(snapshot_path, "wb"), SER_DISK, CLIENT_VERSION};
|
CAutoFile outfile{fsbridge::fopen(snapshot_path, "wb"), SER_DISK, CLIENT_VERSION};
|
||||||
const auto file_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
|
const auto file_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
|
||||||
outfile << Span<const uint8_t>{file_data};
|
outfile << Span{file_data};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto ActivateFuzzedSnapshot{[&] {
|
const auto ActivateFuzzedSnapshot{[&] {
|
||||||
|
|
|
@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(key_io_valid_parse)
|
||||||
privkey = DecodeSecret(exp_base58string);
|
privkey = DecodeSecret(exp_base58string);
|
||||||
BOOST_CHECK_MESSAGE(privkey.IsValid(), "!IsValid:" + strTest);
|
BOOST_CHECK_MESSAGE(privkey.IsValid(), "!IsValid:" + strTest);
|
||||||
BOOST_CHECK_MESSAGE(privkey.IsCompressed() == isCompressed, "compressed mismatch:" + strTest);
|
BOOST_CHECK_MESSAGE(privkey.IsCompressed() == isCompressed, "compressed mismatch:" + strTest);
|
||||||
BOOST_CHECK_MESSAGE(Span<const uint8_t>{privkey} == Span<const uint8_t>{exp_payload}, "key mismatch:" + strTest);
|
BOOST_CHECK_MESSAGE(Span{privkey} == Span{exp_payload}, "key mismatch:" + strTest);
|
||||||
|
|
||||||
// Private key must be invalid public key
|
// Private key must be invalid public key
|
||||||
destination = DecodeDestination(exp_base58string);
|
destination = DecodeDestination(exp_base58string);
|
||||||
|
|
|
@ -386,9 +386,9 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
|
||||||
s.SetVersion(s.GetVersion() | ADDRV2_FORMAT);
|
s.SetVersion(s.GetVersion() | ADDRV2_FORMAT);
|
||||||
|
|
||||||
// Valid IPv4.
|
// Valid IPv4.
|
||||||
s << MakeSpan(ParseHex("01" // network type (IPv4)
|
s << Span{ParseHex("01" // network type (IPv4)
|
||||||
"04" // address length
|
"04" // address length
|
||||||
"01020304")); // address
|
"01020304")}; // address
|
||||||
s >> addr;
|
s >> addr;
|
||||||
BOOST_CHECK(addr.IsValid());
|
BOOST_CHECK(addr.IsValid());
|
||||||
BOOST_CHECK(addr.IsIPv4());
|
BOOST_CHECK(addr.IsIPv4());
|
||||||
|
@ -397,35 +397,35 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
|
||||||
BOOST_REQUIRE(s.empty());
|
BOOST_REQUIRE(s.empty());
|
||||||
|
|
||||||
// Invalid IPv4, valid length but address itself is shorter.
|
// Invalid IPv4, valid length but address itself is shorter.
|
||||||
s << MakeSpan(ParseHex("01" // network type (IPv4)
|
s << Span{ParseHex("01" // network type (IPv4)
|
||||||
"04" // address length
|
"04" // address length
|
||||||
"0102")); // address
|
"0102")}; // address
|
||||||
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure, HasReason("end of data"));
|
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure, HasReason("end of data"));
|
||||||
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
||||||
s.clear();
|
s.clear();
|
||||||
|
|
||||||
// Invalid IPv4, with bogus length.
|
// Invalid IPv4, with bogus length.
|
||||||
s << MakeSpan(ParseHex("01" // network type (IPv4)
|
s << Span{ParseHex("01" // network type (IPv4)
|
||||||
"05" // address length
|
"05" // address length
|
||||||
"01020304")); // address
|
"01020304")}; // address
|
||||||
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
|
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
|
||||||
HasReason("BIP155 IPv4 address with length 5 (should be 4)"));
|
HasReason("BIP155 IPv4 address with length 5 (should be 4)"));
|
||||||
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
||||||
s.clear();
|
s.clear();
|
||||||
|
|
||||||
// Invalid IPv4, with extreme length.
|
// Invalid IPv4, with extreme length.
|
||||||
s << MakeSpan(ParseHex("01" // network type (IPv4)
|
s << Span{ParseHex("01" // network type (IPv4)
|
||||||
"fd0102" // address length (513 as CompactSize)
|
"fd0102" // address length (513 as CompactSize)
|
||||||
"01020304")); // address
|
"01020304")}; // address
|
||||||
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
|
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
|
||||||
HasReason("Address too long: 513 > 512"));
|
HasReason("Address too long: 513 > 512"));
|
||||||
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
||||||
s.clear();
|
s.clear();
|
||||||
|
|
||||||
// Valid IPv6.
|
// Valid IPv6.
|
||||||
s << MakeSpan(ParseHex("02" // network type (IPv6)
|
s << Span{ParseHex("02" // network type (IPv6)
|
||||||
"10" // address length
|
"10" // address length
|
||||||
"0102030405060708090a0b0c0d0e0f10")); // address
|
"0102030405060708090a0b0c0d0e0f10")}; // address
|
||||||
s >> addr;
|
s >> addr;
|
||||||
BOOST_CHECK(addr.IsValid());
|
BOOST_CHECK(addr.IsValid());
|
||||||
BOOST_CHECK(addr.IsIPv6());
|
BOOST_CHECK(addr.IsIPv6());
|
||||||
|
@ -434,10 +434,10 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
|
||||||
BOOST_REQUIRE(s.empty());
|
BOOST_REQUIRE(s.empty());
|
||||||
|
|
||||||
// Valid IPv6, contains embedded "internal".
|
// Valid IPv6, contains embedded "internal".
|
||||||
s << MakeSpan(ParseHex(
|
s << Span{ParseHex(
|
||||||
"02" // network type (IPv6)
|
"02" // network type (IPv6)
|
||||||
"10" // address length
|
"10" // address length
|
||||||
"fd6b88c08724ca978112ca1bbdcafac2")); // address: 0xfd + sha256("bitcoin")[0:5] +
|
"fd6b88c08724ca978112ca1bbdcafac2")}; // address: 0xfd + sha256("bitcoin")[0:5] +
|
||||||
// sha256(name)[0:10]
|
// sha256(name)[0:10]
|
||||||
s >> addr;
|
s >> addr;
|
||||||
BOOST_CHECK(addr.IsInternal());
|
BOOST_CHECK(addr.IsInternal());
|
||||||
|
@ -446,44 +446,44 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
|
||||||
BOOST_REQUIRE(s.empty());
|
BOOST_REQUIRE(s.empty());
|
||||||
|
|
||||||
// Invalid IPv6, with bogus length.
|
// Invalid IPv6, with bogus length.
|
||||||
s << MakeSpan(ParseHex("02" // network type (IPv6)
|
s << Span{ParseHex("02" // network type (IPv6)
|
||||||
"04" // address length
|
"04" // address length
|
||||||
"00")); // address
|
"00")}; // address
|
||||||
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
|
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
|
||||||
HasReason("BIP155 IPv6 address with length 4 (should be 16)"));
|
HasReason("BIP155 IPv6 address with length 4 (should be 16)"));
|
||||||
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
||||||
s.clear();
|
s.clear();
|
||||||
|
|
||||||
// Invalid IPv6, contains embedded IPv4.
|
// Invalid IPv6, contains embedded IPv4.
|
||||||
s << MakeSpan(ParseHex("02" // network type (IPv6)
|
s << Span{ParseHex("02" // network type (IPv6)
|
||||||
"10" // address length
|
"10" // address length
|
||||||
"00000000000000000000ffff01020304")); // address
|
"00000000000000000000ffff01020304")}; // address
|
||||||
s >> addr;
|
s >> addr;
|
||||||
BOOST_CHECK(!addr.IsValid());
|
BOOST_CHECK(!addr.IsValid());
|
||||||
BOOST_REQUIRE(s.empty());
|
BOOST_REQUIRE(s.empty());
|
||||||
|
|
||||||
// Invalid IPv6, contains embedded TORv2.
|
// Invalid IPv6, contains embedded TORv2.
|
||||||
s << MakeSpan(ParseHex("02" // network type (IPv6)
|
s << Span{ParseHex("02" // network type (IPv6)
|
||||||
"10" // address length
|
"10" // address length
|
||||||
"fd87d87eeb430102030405060708090a")); // address
|
"fd87d87eeb430102030405060708090a")}; // address
|
||||||
s >> addr;
|
s >> addr;
|
||||||
BOOST_CHECK(!addr.IsValid());
|
BOOST_CHECK(!addr.IsValid());
|
||||||
BOOST_REQUIRE(s.empty());
|
BOOST_REQUIRE(s.empty());
|
||||||
|
|
||||||
// TORv2, no longer supported.
|
// TORv2, no longer supported.
|
||||||
s << MakeSpan(ParseHex("03" // network type (TORv2)
|
s << Span{ParseHex("03" // network type (TORv2)
|
||||||
"0a" // address length
|
"0a" // address length
|
||||||
"f1f2f3f4f5f6f7f8f9fa")); // address
|
"f1f2f3f4f5f6f7f8f9fa")}; // address
|
||||||
s >> addr;
|
s >> addr;
|
||||||
BOOST_CHECK(!addr.IsValid());
|
BOOST_CHECK(!addr.IsValid());
|
||||||
BOOST_REQUIRE(s.empty());
|
BOOST_REQUIRE(s.empty());
|
||||||
|
|
||||||
// Valid TORv3.
|
// Valid TORv3.
|
||||||
s << MakeSpan(ParseHex("04" // network type (TORv3)
|
s << Span{ParseHex("04" // network type (TORv3)
|
||||||
"20" // address length
|
"20" // address length
|
||||||
"79bcc625184b05194975c28b66b66b04" // address
|
"79bcc625184b05194975c28b66b66b04" // address
|
||||||
"69f7f6556fb1ac3189a79b40dda32f1f"
|
"69f7f6556fb1ac3189a79b40dda32f1f"
|
||||||
));
|
)};
|
||||||
s >> addr;
|
s >> addr;
|
||||||
BOOST_CHECK(addr.IsValid());
|
BOOST_CHECK(addr.IsValid());
|
||||||
BOOST_CHECK(addr.IsTor());
|
BOOST_CHECK(addr.IsTor());
|
||||||
|
@ -493,20 +493,20 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
|
||||||
BOOST_REQUIRE(s.empty());
|
BOOST_REQUIRE(s.empty());
|
||||||
|
|
||||||
// Invalid TORv3, with bogus length.
|
// Invalid TORv3, with bogus length.
|
||||||
s << MakeSpan(ParseHex("04" // network type (TORv3)
|
s << Span{ParseHex("04" // network type (TORv3)
|
||||||
"00" // address length
|
"00" // address length
|
||||||
"00" // address
|
"00" // address
|
||||||
));
|
)};
|
||||||
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
|
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
|
||||||
HasReason("BIP155 TORv3 address with length 0 (should be 32)"));
|
HasReason("BIP155 TORv3 address with length 0 (should be 32)"));
|
||||||
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
||||||
s.clear();
|
s.clear();
|
||||||
|
|
||||||
// Valid I2P.
|
// Valid I2P.
|
||||||
s << MakeSpan(ParseHex("05" // network type (I2P)
|
s << Span{ParseHex("05" // network type (I2P)
|
||||||
"20" // address length
|
"20" // address length
|
||||||
"a2894dabaec08c0051a481a6dac88b64" // address
|
"a2894dabaec08c0051a481a6dac88b64" // address
|
||||||
"f98232ae42d4b6fd2fa81952dfe36a87"));
|
"f98232ae42d4b6fd2fa81952dfe36a87")};
|
||||||
s >> addr;
|
s >> addr;
|
||||||
BOOST_CHECK(addr.IsValid());
|
BOOST_CHECK(addr.IsValid());
|
||||||
BOOST_CHECK(addr.IsI2P());
|
BOOST_CHECK(addr.IsI2P());
|
||||||
|
@ -516,20 +516,20 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
|
||||||
BOOST_REQUIRE(s.empty());
|
BOOST_REQUIRE(s.empty());
|
||||||
|
|
||||||
// Invalid I2P, with bogus length.
|
// Invalid I2P, with bogus length.
|
||||||
s << MakeSpan(ParseHex("05" // network type (I2P)
|
s << Span{ParseHex("05" // network type (I2P)
|
||||||
"03" // address length
|
"03" // address length
|
||||||
"00" // address
|
"00" // address
|
||||||
));
|
)};
|
||||||
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
|
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
|
||||||
HasReason("BIP155 I2P address with length 3 (should be 32)"));
|
HasReason("BIP155 I2P address with length 3 (should be 32)"));
|
||||||
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
||||||
s.clear();
|
s.clear();
|
||||||
|
|
||||||
// Valid CJDNS.
|
// Valid CJDNS.
|
||||||
s << MakeSpan(ParseHex("06" // network type (CJDNS)
|
s << Span{ParseHex("06" // network type (CJDNS)
|
||||||
"10" // address length
|
"10" // address length
|
||||||
"fc000001000200030004000500060007" // address
|
"fc000001000200030004000500060007" // address
|
||||||
));
|
)};
|
||||||
s >> addr;
|
s >> addr;
|
||||||
BOOST_CHECK(addr.IsValid());
|
BOOST_CHECK(addr.IsValid());
|
||||||
BOOST_CHECK(addr.IsCJDNS());
|
BOOST_CHECK(addr.IsCJDNS());
|
||||||
|
@ -538,49 +538,49 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
|
||||||
BOOST_REQUIRE(s.empty());
|
BOOST_REQUIRE(s.empty());
|
||||||
|
|
||||||
// Invalid CJDNS, wrong prefix.
|
// Invalid CJDNS, wrong prefix.
|
||||||
s << MakeSpan(ParseHex("06" // network type (CJDNS)
|
s << Span{ParseHex("06" // network type (CJDNS)
|
||||||
"10" // address length
|
"10" // address length
|
||||||
"aa000001000200030004000500060007" // address
|
"aa000001000200030004000500060007" // address
|
||||||
));
|
)};
|
||||||
s >> addr;
|
s >> addr;
|
||||||
BOOST_CHECK(addr.IsCJDNS());
|
BOOST_CHECK(addr.IsCJDNS());
|
||||||
BOOST_CHECK(!addr.IsValid());
|
BOOST_CHECK(!addr.IsValid());
|
||||||
BOOST_REQUIRE(s.empty());
|
BOOST_REQUIRE(s.empty());
|
||||||
|
|
||||||
// Invalid CJDNS, with bogus length.
|
// Invalid CJDNS, with bogus length.
|
||||||
s << MakeSpan(ParseHex("06" // network type (CJDNS)
|
s << Span{ParseHex("06" // network type (CJDNS)
|
||||||
"01" // address length
|
"01" // address length
|
||||||
"00" // address
|
"00" // address
|
||||||
));
|
)};
|
||||||
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
|
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
|
||||||
HasReason("BIP155 CJDNS address with length 1 (should be 16)"));
|
HasReason("BIP155 CJDNS address with length 1 (should be 16)"));
|
||||||
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
||||||
s.clear();
|
s.clear();
|
||||||
|
|
||||||
// Unknown, with extreme length.
|
// Unknown, with extreme length.
|
||||||
s << MakeSpan(ParseHex("aa" // network type (unknown)
|
s << Span{ParseHex("aa" // network type (unknown)
|
||||||
"fe00000002" // address length (CompactSize's MAX_SIZE)
|
"fe00000002" // address length (CompactSize's MAX_SIZE)
|
||||||
"01020304050607" // address
|
"01020304050607" // address
|
||||||
));
|
)};
|
||||||
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
|
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
|
||||||
HasReason("Address too long: 33554432 > 512"));
|
HasReason("Address too long: 33554432 > 512"));
|
||||||
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
|
||||||
s.clear();
|
s.clear();
|
||||||
|
|
||||||
// Unknown, with reasonable length.
|
// Unknown, with reasonable length.
|
||||||
s << MakeSpan(ParseHex("aa" // network type (unknown)
|
s << Span{ParseHex("aa" // network type (unknown)
|
||||||
"04" // address length
|
"04" // address length
|
||||||
"01020304" // address
|
"01020304" // address
|
||||||
));
|
)};
|
||||||
s >> addr;
|
s >> addr;
|
||||||
BOOST_CHECK(!addr.IsValid());
|
BOOST_CHECK(!addr.IsValid());
|
||||||
BOOST_REQUIRE(s.empty());
|
BOOST_REQUIRE(s.empty());
|
||||||
|
|
||||||
// Unknown, with zero length.
|
// Unknown, with zero length.
|
||||||
s << MakeSpan(ParseHex("aa" // network type (unknown)
|
s << Span{ParseHex("aa" // network type (unknown)
|
||||||
"00" // address length
|
"00" // address length
|
||||||
"" // address
|
"" // address
|
||||||
));
|
)};
|
||||||
s >> addr;
|
s >> addr;
|
||||||
BOOST_CHECK(!addr.IsValid());
|
BOOST_CHECK(!addr.IsValid());
|
||||||
BOOST_REQUIRE(s.empty());
|
BOOST_REQUIRE(s.empty());
|
||||||
|
|
|
@ -284,7 +284,7 @@ public:
|
||||||
CScript scriptPubKey = script;
|
CScript scriptPubKey = script;
|
||||||
if (wm == WitnessMode::PKH) {
|
if (wm == WitnessMode::PKH) {
|
||||||
uint160 hash;
|
uint160 hash;
|
||||||
CHash160().Write(MakeSpan(script).subspan(1)).Finalize(hash);
|
CHash160().Write(Span{script}.subspan(1)).Finalize(hash);
|
||||||
script = CScript() << OP_DUP << OP_HASH160 << ToByteVector(hash) << OP_EQUALVERIFY << OP_CHECKSIG;
|
script = CScript() << OP_DUP << OP_HASH160 << ToByteVector(hash) << OP_EQUALVERIFY << OP_CHECKSIG;
|
||||||
scriptPubKey = CScript() << witnessversion << ToByteVector(hash);
|
scriptPubKey = CScript() << witnessversion << ToByteVector(hash);
|
||||||
} else if (wm == WitnessMode::SH) {
|
} else if (wm == WitnessMode::SH) {
|
||||||
|
@ -1812,7 +1812,7 @@ BOOST_AUTO_TEST_CASE(bip341_keypath_test_vectors)
|
||||||
BOOST_CHECK_EQUAL(HexStr(sighash), input["intermediary"]["sigHash"].get_str());
|
BOOST_CHECK_EQUAL(HexStr(sighash), input["intermediary"]["sigHash"].get_str());
|
||||||
|
|
||||||
// To verify the sigmsg, hash the expected sigmsg, and compare it with the (expected) sighash.
|
// To verify the sigmsg, hash the expected sigmsg, and compare it with the (expected) sighash.
|
||||||
BOOST_CHECK_EQUAL(HexStr((CHashWriter(HASHER_TAPSIGHASH) << MakeSpan(ParseHex(input["intermediary"]["sigMsg"].get_str()))).GetSHA256()), input["intermediary"]["sigHash"].get_str());
|
BOOST_CHECK_EQUAL(HexStr((CHashWriter(HASHER_TAPSIGHASH) << Span{ParseHex(input["intermediary"]["sigMsg"].get_str())}).GetSHA256()), input["intermediary"]["sigHash"].get_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,13 +142,11 @@ BOOST_AUTO_TEST_CASE(util_HexStr)
|
||||||
"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
|
"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(
|
BOOST_CHECK_EQUAL(
|
||||||
HexStr(Span<const unsigned char>(
|
HexStr(Span{ParseHex_expected}.last(0)),
|
||||||
ParseHex_expected + sizeof(ParseHex_expected),
|
|
||||||
ParseHex_expected + sizeof(ParseHex_expected))),
|
|
||||||
"");
|
"");
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(
|
BOOST_CHECK_EQUAL(
|
||||||
HexStr(Span<const unsigned char>(ParseHex_expected, ParseHex_expected)),
|
HexStr(Span{ParseHex_expected}.first(0)),
|
||||||
"");
|
"");
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,7 +35,7 @@ std::string static EncodeDumpString(const std::string &str) {
|
||||||
std::stringstream ret;
|
std::stringstream ret;
|
||||||
for (const unsigned char c : str) {
|
for (const unsigned char c : str) {
|
||||||
if (c <= 32 || c >= 128 || c == '%') {
|
if (c <= 32 || c >= 128 || c == '%') {
|
||||||
ret << '%' << HexStr(Span<const unsigned char>(&c, 1));
|
ret << '%' << HexStr({&c, 1});
|
||||||
} else {
|
} else {
|
||||||
ret << c;
|
ret << c;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4413,5 +4413,5 @@ static const CRPCCommand commands[] =
|
||||||
{ "wallet", &walletprocesspsbt, },
|
{ "wallet", &walletprocesspsbt, },
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
return MakeSpan(commands);
|
return commands;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue