0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-09 10:43:19 -05:00

Replace MakeSpan helper with Span deduction guide

This commit is contained in:
Pieter Wuille 2021-11-01 16:32:53 -04:00
parent 383d350bd5
commit 568dd2f839
16 changed files with 106 additions and 104 deletions

View file

@ -149,7 +149,7 @@ std::string EncodeBase58Check(Span<const unsigned char> input)
return false;
}
// 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) {
vchRet.clear();
return false;

View file

@ -65,12 +65,12 @@ struct ScriptCompression
void Ser(Stream &s, const CScript& script) {
CompressedScript compr;
if (CompressScript(script, compr)) {
s << MakeSpan(compr);
s << Span{compr};
return;
}
unsigned int nSize = script.size() + nSpecialScripts;
s << VARINT(nSize);
s << MakeSpan(script);
s << Span{script};
}
template<typename Stream>
@ -79,7 +79,7 @@ struct ScriptCompression
s >> VARINT(nSize);
if (nSize < nSpecialScripts) {
CompressedScript vch(GetSpecialScriptSize(nSize), 0x00);
s >> MakeSpan(vch);
s >> Span{vch};
DecompressScript(script, nSize, vch);
return;
}
@ -90,7 +90,7 @@ struct ScriptCompression
s.ignore(nSize);
} else {
script.resize(nSize);
s >> MakeSpan(script);
s >> Span{script};
}
}
};

View file

@ -1815,7 +1815,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
if (!ReadRawBlockFromDisk(block_data, pindex, m_chainparams.MessageStart())) {
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
} else {
// Send block from disk

View file

@ -196,7 +196,7 @@ static void Checksum(Span<const uint8_t> addr_pubkey, uint8_t (&checksum)[CHECKS
SHA3_256 hasher;
hasher.Write(MakeSpan(prefix).first(prefix_len));
hasher.Write(Span{prefix}.first(prefix_len));
hasher.Write(addr_pubkey);
hasher.Write(VERSION);
@ -693,13 +693,13 @@ uint32_t CNetAddr::GetLinkedIPv4() const
return ReadBE32(m_addr.data());
} else if (IsRFC6052() || IsRFC6145()) {
// 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()) {
// 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()) {
// 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);
}

View file

@ -433,7 +433,7 @@ private:
if (SetNetFromBIP155Network(bip155_net, address_size)) {
m_addr.resize(address_size);
s >> MakeSpan(m_addr);
s >> Span{m_addr};
if (m_net != NET_IPV6) {
return;

View file

@ -251,7 +251,7 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
// - No annexes
if (witnessversion == 1 && witnessprogram.size() == WITNESS_V1_TAPROOT_SIZE && !p2sh) {
// 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) {
// Annexes are nonstandard as long as no semantics are defined for them.
return false;

View file

@ -81,7 +81,7 @@ struct PSBTInput
if (final_script_sig.empty() && final_script_witness.IsNull()) {
// Write any partial signatures
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;
}

View file

@ -157,13 +157,13 @@ public:
//! Get the KeyID of this public key (hash of its serialization)
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.
uint256 GetHash() const
{
return Hash(MakeSpan(vch).first(size()));
return Hash(Span{vch}.first(size()));
}
/*

View file

@ -631,7 +631,7 @@ public:
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;
}
@ -974,10 +974,10 @@ std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const S
}
KeyPath path;
DeriveType type = DeriveType::NO;
if (split.back() == MakeSpan("*").first(1)) {
if (split.back() == Span{"*"}.first(1)) {
split.pop_back();
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();
type = DeriveType::HARDENED;
}

View file

@ -167,7 +167,7 @@ static bool SignTaprootScript(const SigningProvider& provider, const BaseSignatu
// <xonly pubkey> OP_CHECKSIG
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;
if (CreateTaprootScriptSig(creator, sigdata, provider, sig, pubkey, leaf_hash, sigversion)) {
result = Vector(std::move(sig));

View file

@ -149,7 +149,7 @@ void SerializeHDKeypaths(Stream& s, const std::map<CPubKey, KeyOriginInfo>& hd_k
if (!keypath_pair.first.IsValid()) {
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));
s << keypath_pair.second.fingerprint;
for (const auto& path : keypath_pair.second.path) {

View file

@ -222,13 +222,15 @@ public:
template <typename O> friend class Span;
};
// MakeSpan helps constructing a Span of the right type automatically.
/** MakeSpan for arrays: */
template <typename A, int N> Span<A> constexpr MakeSpan(A (&a)[N]) { return Span<A>(a, N); }
/** MakeSpan for temporaries / rvalue references, only supporting const output. */
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); }
/** MakeSpan for (lvalue) references, supporting mutable output. */
template <typename V> constexpr auto MakeSpan(V& v SPAN_ATTR_LIFETIMEBOUND) -> Span<typename std::remove_pointer<decltype(v.data())>::type> { return v; }
// Deduction guides for Span
// For the pointer/size based and iterator based constructor:
template <typename T, typename EndOrSize> Span(T*, EndOrSize) -> Span<T>;
// For the array constructor:
template <typename T, std::size_t N> Span(T (&)[N]) -> Span<T>;
// For the temporaries/rvalue references constructor, only supporting const output.
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. */
template <typename T>
@ -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>.
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. */
template <typename V> constexpr auto MakeUCharSpan(V&& v) -> decltype(UCharSpanCast(MakeSpan(std::forward<V>(v)))) { return UCharSpanCast(MakeSpan(std::forward<V>(v))); }
/** 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(Span{std::forward<V>(v)})) { return UCharSpanCast(Span{std::forward<V>(v)}); }
#endif // BITCOIN_SPAN_H

View file

@ -770,8 +770,8 @@ static void TestSHA3_256(const std::string& input, const std::string& output)
int s1 = InsecureRandRange(in_bytes.size() + 1);
int s2 = InsecureRandRange(in_bytes.size() + 1 - s1);
int s3 = in_bytes.size() - s1 - s2;
sha.Write(MakeSpan(in_bytes).first(s1)).Write(MakeSpan(in_bytes).subspan(s1, s2));
sha.Write(MakeSpan(in_bytes).last(s3)).Finalize(out);
sha.Write(Span{in_bytes}.first(s1)).Write(Span{in_bytes}.subspan(s1, s2));
sha.Write(Span{in_bytes}.last(s3)).Finalize(out);
BOOST_CHECK(std::equal(std::begin(out_bytes), std::end(out_bytes), out));
}

View file

@ -386,9 +386,9 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s.SetVersion(s.GetVersion() | ADDRV2_FORMAT);
// Valid IPv4.
s << MakeSpan(ParseHex("01" // network type (IPv4)
"04" // address length
"01020304")); // address
s << Span{ParseHex("01" // network type (IPv4)
"04" // address length
"01020304")}; // address
s >> addr;
BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsIPv4());
@ -397,35 +397,35 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
BOOST_REQUIRE(s.empty());
// Invalid IPv4, valid length but address itself is shorter.
s << MakeSpan(ParseHex("01" // network type (IPv4)
"04" // address length
"0102")); // address
s << Span{ParseHex("01" // network type (IPv4)
"04" // address length
"0102")}; // address
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.
s.clear();
// Invalid IPv4, with bogus length.
s << MakeSpan(ParseHex("01" // network type (IPv4)
"05" // address length
"01020304")); // address
s << Span{ParseHex("01" // network type (IPv4)
"05" // address length
"01020304")}; // address
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
HasReason("BIP155 IPv4 address with length 5 (should be 4)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
// Invalid IPv4, with extreme length.
s << MakeSpan(ParseHex("01" // network type (IPv4)
"fd0102" // address length (513 as CompactSize)
"01020304")); // address
s << Span{ParseHex("01" // network type (IPv4)
"fd0102" // address length (513 as CompactSize)
"01020304")}; // address
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
HasReason("Address too long: 513 > 512"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
// Valid IPv6.
s << MakeSpan(ParseHex("02" // network type (IPv6)
"10" // address length
"0102030405060708090a0b0c0d0e0f10")); // address
s << Span{ParseHex("02" // network type (IPv6)
"10" // address length
"0102030405060708090a0b0c0d0e0f10")}; // address
s >> addr;
BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsIPv6());
@ -434,10 +434,10 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
BOOST_REQUIRE(s.empty());
// Valid IPv6, contains embedded "internal".
s << MakeSpan(ParseHex(
s << Span{ParseHex(
"02" // network type (IPv6)
"10" // address length
"fd6b88c08724ca978112ca1bbdcafac2")); // address: 0xfd + sha256("bitcoin")[0:5] +
"fd6b88c08724ca978112ca1bbdcafac2")}; // address: 0xfd + sha256("bitcoin")[0:5] +
// sha256(name)[0:10]
s >> addr;
BOOST_CHECK(addr.IsInternal());
@ -446,44 +446,44 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
BOOST_REQUIRE(s.empty());
// Invalid IPv6, with bogus length.
s << MakeSpan(ParseHex("02" // network type (IPv6)
"04" // address length
"00")); // address
s << Span{ParseHex("02" // network type (IPv6)
"04" // address length
"00")}; // address
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
HasReason("BIP155 IPv6 address with length 4 (should be 16)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
// Invalid IPv6, contains embedded IPv4.
s << MakeSpan(ParseHex("02" // network type (IPv6)
"10" // address length
"00000000000000000000ffff01020304")); // address
s << Span{ParseHex("02" // network type (IPv6)
"10" // address length
"00000000000000000000ffff01020304")}; // address
s >> addr;
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());
// Invalid IPv6, contains embedded TORv2.
s << MakeSpan(ParseHex("02" // network type (IPv6)
"10" // address length
"fd87d87eeb430102030405060708090a")); // address
s << Span{ParseHex("02" // network type (IPv6)
"10" // address length
"fd87d87eeb430102030405060708090a")}; // address
s >> addr;
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());
// TORv2, no longer supported.
s << MakeSpan(ParseHex("03" // network type (TORv2)
"0a" // address length
"f1f2f3f4f5f6f7f8f9fa")); // address
s << Span{ParseHex("03" // network type (TORv2)
"0a" // address length
"f1f2f3f4f5f6f7f8f9fa")}; // address
s >> addr;
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());
// Valid TORv3.
s << MakeSpan(ParseHex("04" // network type (TORv3)
"20" // address length
"79bcc625184b05194975c28b66b66b04" // address
"69f7f6556fb1ac3189a79b40dda32f1f"
));
s << Span{ParseHex("04" // network type (TORv3)
"20" // address length
"79bcc625184b05194975c28b66b66b04" // address
"69f7f6556fb1ac3189a79b40dda32f1f"
)};
s >> addr;
BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsTor());
@ -493,20 +493,20 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
BOOST_REQUIRE(s.empty());
// Invalid TORv3, with bogus length.
s << MakeSpan(ParseHex("04" // network type (TORv3)
"00" // address length
"00" // address
));
s << Span{ParseHex("04" // network type (TORv3)
"00" // address length
"00" // address
)};
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
HasReason("BIP155 TORv3 address with length 0 (should be 32)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
// Valid I2P.
s << MakeSpan(ParseHex("05" // network type (I2P)
"20" // address length
"a2894dabaec08c0051a481a6dac88b64" // address
"f98232ae42d4b6fd2fa81952dfe36a87"));
s << Span{ParseHex("05" // network type (I2P)
"20" // address length
"a2894dabaec08c0051a481a6dac88b64" // address
"f98232ae42d4b6fd2fa81952dfe36a87")};
s >> addr;
BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsI2P());
@ -516,20 +516,20 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
BOOST_REQUIRE(s.empty());
// Invalid I2P, with bogus length.
s << MakeSpan(ParseHex("05" // network type (I2P)
"03" // address length
"00" // address
));
s << Span{ParseHex("05" // network type (I2P)
"03" // address length
"00" // address
)};
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
HasReason("BIP155 I2P address with length 3 (should be 32)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
// Valid CJDNS.
s << MakeSpan(ParseHex("06" // network type (CJDNS)
"10" // address length
"fc000001000200030004000500060007" // address
));
s << Span{ParseHex("06" // network type (CJDNS)
"10" // address length
"fc000001000200030004000500060007" // address
)};
s >> addr;
BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsCJDNS());
@ -538,49 +538,49 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
BOOST_REQUIRE(s.empty());
// Invalid CJDNS, wrong prefix.
s << MakeSpan(ParseHex("06" // network type (CJDNS)
"10" // address length
"aa000001000200030004000500060007" // address
));
s << Span{ParseHex("06" // network type (CJDNS)
"10" // address length
"aa000001000200030004000500060007" // address
)};
s >> addr;
BOOST_CHECK(addr.IsCJDNS());
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());
// Invalid CJDNS, with bogus length.
s << MakeSpan(ParseHex("06" // network type (CJDNS)
"01" // address length
"00" // address
));
s << Span{ParseHex("06" // network type (CJDNS)
"01" // address length
"00" // address
)};
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
HasReason("BIP155 CJDNS address with length 1 (should be 16)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
// Unknown, with extreme length.
s << MakeSpan(ParseHex("aa" // network type (unknown)
"fe00000002" // address length (CompactSize's MAX_SIZE)
"01020304050607" // address
));
s << Span{ParseHex("aa" // network type (unknown)
"fe00000002" // address length (CompactSize's MAX_SIZE)
"01020304050607" // address
)};
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
HasReason("Address too long: 33554432 > 512"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
// Unknown, with reasonable length.
s << MakeSpan(ParseHex("aa" // network type (unknown)
"04" // address length
"01020304" // address
));
s << Span{ParseHex("aa" // network type (unknown)
"04" // address length
"01020304" // address
)};
s >> addr;
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());
// Unknown, with zero length.
s << MakeSpan(ParseHex("aa" // network type (unknown)
"00" // address length
"" // address
));
s << Span{ParseHex("aa" // network type (unknown)
"00" // address length
"" // address
)};
s >> addr;
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());

View file

@ -284,7 +284,7 @@ public:
CScript scriptPubKey = script;
if (wm == WitnessMode::PKH) {
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;
scriptPubKey = CScript() << witnessversion << ToByteVector(hash);
} 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());
// 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());
}
}

View file

@ -4937,5 +4937,5 @@ static const CRPCCommand commands[] =
{ "wallet", &walletprocesspsbt, },
};
// clang-format on
return MakeSpan(commands);
return Span{commands};
}