Merge bitcoin/bitcoin#31519: refactor: Use std::span over Span
Some checks are pending
CI / test each commit (push) Waiting to run
CI / macOS 14 native, arm64, no depends, sqlite only, gui (push) Waiting to run
CI / macOS 14 native, arm64, fuzz (push) Waiting to run
CI / Win64 native, VS 2022 (push) Waiting to run
CI / Win64 native fuzz, VS 2022 (push) Waiting to run
CI / ASan + LSan + UBSan + integer, no depends, USDT (push) Waiting to run

ffff4a293a bench: Update span-serialize comment (MarcoFalke)
fa4d6ec97b refactor: Avoid false-positive gcc warning (MarcoFalke)
fa942332b4 scripted-diff: Bump copyright headers after std::span changes (MarcoFalke)
fa0c6b7179 refactor: Remove unused Span alias (MarcoFalke)
fade0b5e5e scripted-diff: Use std::span over Span (MarcoFalke)
fadccc26c0 refactor: Make Span an alias of std::span (MarcoFalke)
fa27e36717 test: Fix broken span_tests (MarcoFalke)
fadf02ef8b refactor: Return std::span from MakeUCharSpan (MarcoFalke)
fa720b94be refactor: Return std::span from MakeByteSpan (MarcoFalke)

Pull request description:

  `Span` has some issues:

  * It does not support fixed-size spans, which are available through `std::span`.
  * It is confusing to have it available and in use at the same time with `std::span`.
  * It does not obey the standard library iterator build hardening flags. See https://github.com/bitcoin/bitcoin/issues/31272 for a discussion. For example, this allows to catch issues like the one fixed in commit fabeca3458.

  Both types are type-safe and can even implicitly convert into each other in most contexts.

  However, exclusively using `std::span` seems less confusing, so do it here with a scripted-diff.

ACKs for top commit:
  l0rinc:
    reACK ffff4a293a
  theuni:
    ACK ffff4a293a.

Tree-SHA512: 9cc2f1f43551e2c07cc09f38b1f27d11e57e9e9bc0c6138c8fddd0cef54b91acd8b14711205ff949be874294a121910d0aceffe0e8914c4cff07f1e0e87ad5b8
This commit is contained in:
merge-script 2025-03-20 13:41:54 +08:00
commit aa87e0b446
No known key found for this signature in database
GPG key ID: 2EEB9F5CC09526C1
122 changed files with 695 additions and 890 deletions

View file

@ -856,14 +856,14 @@ class A
- *Rationale*: Easier to understand what is happening, thus easier to spot mistakes, even for those - *Rationale*: Easier to understand what is happening, thus easier to spot mistakes, even for those
that are not language lawyers. that are not language lawyers.
- Use `Span` as function argument when it can operate on any range-like container. - Use `std::span` as function argument when it can operate on any range-like container.
- *Rationale*: Compared to `Foo(const vector<int>&)` this avoids the need for a (potentially expensive) - *Rationale*: Compared to `Foo(const vector<int>&)` this avoids the need for a (potentially expensive)
conversion to vector if the caller happens to have the input stored in another type of container. conversion to vector if the caller happens to have the input stored in another type of container.
However, be aware of the pitfalls documented in [span.h](../src/span.h). However, be aware of the pitfalls documented in [span.h](../src/span.h).
```cpp ```cpp
void Foo(Span<const int> data); void Foo(std::span<const int> data);
std::vector<int> vec{1,2,3}; std::vector<int> vec{1,2,3};
Foo(vec); Foo(vec);

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2022 The Bitcoin Core developers // Copyright (c) 2014-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -86,7 +86,7 @@ static const int8_t mapBase58[256] = {
return true; return true;
} }
std::string EncodeBase58(Span<const unsigned char> input) std::string EncodeBase58(std::span<const unsigned char> input)
{ {
// Skip & count leading zeroes. // Skip & count leading zeroes.
int zeroes = 0; int zeroes = 0;
@ -134,7 +134,7 @@ bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet, in
return DecodeBase58(str.c_str(), vchRet, max_ret_len); return DecodeBase58(str.c_str(), vchRet, max_ret_len);
} }
std::string EncodeBase58Check(Span<const unsigned char> input) std::string EncodeBase58Check(std::span<const unsigned char> input)
{ {
// add 4-byte hash check to the end // add 4-byte hash check to the end
std::vector<unsigned char> vch(input.begin(), input.end()); std::vector<unsigned char> vch(input.begin(), input.end());
@ -151,7 +151,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(Span{vchRet}.first(vchRet.size() - 4)); uint256 hash = Hash(std::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;

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -22,7 +22,7 @@
/** /**
* Encode a byte span as a base58-encoded string * Encode a byte span as a base58-encoded string
*/ */
std::string EncodeBase58(Span<const unsigned char> input); std::string EncodeBase58(std::span<const unsigned char> input);
/** /**
* Decode a base58-encoded string (str) into a byte vector (vchRet). * Decode a base58-encoded string (str) into a byte vector (vchRet).
@ -33,7 +33,7 @@ std::string EncodeBase58(Span<const unsigned char> input);
/** /**
* Encode a byte span into a base58-encoded string, including checksum * Encode a byte span into a base58-encoded string, including checksum
*/ */
std::string EncodeBase58Check(Span<const unsigned char> input); std::string EncodeBase58Check(std::span<const unsigned char> input);
/** /**
* Decode a base58-encoded string (str) that includes a checksum into a byte * Decode a base58-encoded string (str) that includes a checksum into a byte

View file

@ -1,4 +1,4 @@
// Copyright (c) 2022 The Bitcoin Core developers // Copyright (c) 2022-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php. // file COPYING or https://www.opensource.org/licenses/mit-license.php.
@ -44,9 +44,8 @@ static void LoadExternalBlockFile(benchmark::Bench& bench)
auto params{testing_setup->m_node.chainman->GetParams()}; auto params{testing_setup->m_node.chainman->GetParams()};
ss << params.MessageStart(); ss << params.MessageStart();
ss << static_cast<uint32_t>(benchmark::data::block413567.size()); ss << static_cast<uint32_t>(benchmark::data::block413567.size());
// We can't use the streaming serialization (ss << benchmark::data::block413567) // Use span-serialization to avoid writing the size first.
// because that first writes a compact size. ss << std::span{benchmark::data::block413567};
ss << Span{benchmark::data::block413567};
// Create the test file. // Create the test file.
{ {

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023 The Bitcoin Core developers // Copyright (c) 2023-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -22,8 +22,8 @@
#include <iterator> #include <iterator>
#include <string> #include <string>
BIP324Cipher::BIP324Cipher(const CKey& key, Span<const std::byte> ent32) noexcept : BIP324Cipher::BIP324Cipher(const CKey& key, std::span<const std::byte> ent32) noexcept
m_key(key) : m_key(key)
{ {
m_our_pubkey = m_key.EllSwiftCreate(ent32); m_our_pubkey = m_key.EllSwiftCreate(ent32);
} }
@ -70,7 +70,7 @@ void BIP324Cipher::Initialize(const EllSwiftPubKey& their_pubkey, bool initiator
m_key = CKey(); m_key = CKey();
} }
void BIP324Cipher::Encrypt(Span<const std::byte> contents, Span<const std::byte> aad, bool ignore, Span<std::byte> output) noexcept void BIP324Cipher::Encrypt(std::span<const std::byte> contents, std::span<const std::byte> aad, bool ignore, std::span<std::byte> output) noexcept
{ {
assert(output.size() == contents.size() + EXPANSION); assert(output.size() == contents.size() + EXPANSION);
@ -86,7 +86,7 @@ void BIP324Cipher::Encrypt(Span<const std::byte> contents, Span<const std::byte>
m_send_p_cipher->Encrypt(header, contents, aad, output.subspan(LENGTH_LEN)); m_send_p_cipher->Encrypt(header, contents, aad, output.subspan(LENGTH_LEN));
} }
uint32_t BIP324Cipher::DecryptLength(Span<const std::byte> input) noexcept uint32_t BIP324Cipher::DecryptLength(std::span<const std::byte> input) noexcept
{ {
assert(input.size() == LENGTH_LEN); assert(input.size() == LENGTH_LEN);
@ -97,7 +97,7 @@ uint32_t BIP324Cipher::DecryptLength(Span<const std::byte> input) noexcept
return uint32_t(buf[0]) + (uint32_t(buf[1]) << 8) + (uint32_t(buf[2]) << 16); return uint32_t(buf[0]) + (uint32_t(buf[1]) << 8) + (uint32_t(buf[2]) << 16);
} }
bool BIP324Cipher::Decrypt(Span<const std::byte> input, Span<const std::byte> aad, bool& ignore, Span<std::byte> contents) noexcept bool BIP324Cipher::Decrypt(std::span<const std::byte> input, std::span<const std::byte> aad, bool& ignore, std::span<std::byte> contents) noexcept
{ {
assert(input.size() + LENGTH_LEN == contents.size() + EXPANSION); assert(input.size() + LENGTH_LEN == contents.size() + EXPANSION);

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023 The Bitcoin Core developers // Copyright (c) 2023-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -45,7 +45,7 @@ public:
BIP324Cipher() = delete; BIP324Cipher() = delete;
/** Initialize a BIP324 cipher with specified key and encoding entropy (testing only). */ /** Initialize a BIP324 cipher with specified key and encoding entropy (testing only). */
BIP324Cipher(const CKey& key, Span<const std::byte> ent32) noexcept; BIP324Cipher(const CKey& key, std::span<const std::byte> ent32) noexcept;
/** Initialize a BIP324 cipher with specified key (testing only). */ /** Initialize a BIP324 cipher with specified key (testing only). */
BIP324Cipher(const CKey& key, const EllSwiftPubKey& pubkey) noexcept; BIP324Cipher(const CKey& key, const EllSwiftPubKey& pubkey) noexcept;
@ -68,29 +68,29 @@ public:
* *
* It must hold that output.size() == contents.size() + EXPANSION. * It must hold that output.size() == contents.size() + EXPANSION.
*/ */
void Encrypt(Span<const std::byte> contents, Span<const std::byte> aad, bool ignore, Span<std::byte> output) noexcept; void Encrypt(std::span<const std::byte> contents, std::span<const std::byte> aad, bool ignore, std::span<std::byte> output) noexcept;
/** Decrypt the length of a packet. Only after Initialize(). /** Decrypt the length of a packet. Only after Initialize().
* *
* It must hold that input.size() == LENGTH_LEN. * It must hold that input.size() == LENGTH_LEN.
*/ */
unsigned DecryptLength(Span<const std::byte> input) noexcept; unsigned DecryptLength(std::span<const std::byte> input) noexcept;
/** Decrypt a packet. Only after Initialize(). /** Decrypt a packet. Only after Initialize().
* *
* It must hold that input.size() + LENGTH_LEN == contents.size() + EXPANSION. * It must hold that input.size() + LENGTH_LEN == contents.size() + EXPANSION.
* Contents.size() must equal the length returned by DecryptLength. * Contents.size() must equal the length returned by DecryptLength.
*/ */
bool Decrypt(Span<const std::byte> input, Span<const std::byte> aad, bool& ignore, Span<std::byte> contents) noexcept; bool Decrypt(std::span<const std::byte> input, std::span<const std::byte> aad, bool& ignore, std::span<std::byte> contents) noexcept;
/** Get the Session ID. Only after Initialize(). */ /** Get the Session ID. Only after Initialize(). */
Span<const std::byte> GetSessionID() const noexcept { return m_session_id; } std::span<const std::byte> GetSessionID() const noexcept { return m_session_id; }
/** Get the Garbage Terminator to send. Only after Initialize(). */ /** Get the Garbage Terminator to send. Only after Initialize(). */
Span<const std::byte> GetSendGarbageTerminator() const noexcept { return m_send_garbage_terminator; } std::span<const std::byte> GetSendGarbageTerminator() const noexcept { return m_send_garbage_terminator; }
/** Get the expected Garbage Terminator to receive. Only after Initialize(). */ /** Get the expected Garbage Terminator to receive. Only after Initialize(). */
Span<const std::byte> GetReceiveGarbageTerminator() const noexcept { return m_recv_garbage_terminator; } std::span<const std::byte> GetReceiveGarbageTerminator() const noexcept { return m_recv_garbage_terminator; }
}; };
#endif // BITCOIN_BIP324_H #endif // BITCOIN_BIP324_H

View file

@ -75,7 +75,7 @@ public:
* *
* @param depgraph The original DepGraph that is being remapped. * @param depgraph The original DepGraph that is being remapped.
* *
* @param mapping A Span such that mapping[i] gives the position in the new DepGraph * @param mapping A span such that mapping[i] gives the position in the new DepGraph
* for position i in the old depgraph. Its size must be equal to * for position i in the old depgraph. Its size must be equal to
* depgraph.PositionRange(). The value of mapping[i] is ignored if * depgraph.PositionRange(). The value of mapping[i] is ignored if
* position i is a hole in depgraph (i.e., if !depgraph.Positions()[i]). * position i is a hole in depgraph (i.e., if !depgraph.Positions()[i]).
@ -86,7 +86,7 @@ public:
* *
* Complexity: O(N^2) where N=depgraph.TxCount(). * Complexity: O(N^2) where N=depgraph.TxCount().
*/ */
DepGraph(const DepGraph<SetType>& depgraph, Span<const ClusterIndex> mapping, ClusterIndex pos_range) noexcept : entries(pos_range) DepGraph(const DepGraph<SetType>& depgraph, std::span<const ClusterIndex> mapping, ClusterIndex pos_range) noexcept : entries(pos_range)
{ {
Assume(mapping.size() == depgraph.PositionRange()); Assume(mapping.size() == depgraph.PositionRange());
Assume((pos_range == 0) == (depgraph.TxCount() == 0)); Assume((pos_range == 0) == (depgraph.TxCount() == 0));
@ -371,7 +371,7 @@ struct SetInfo
/** Compute the feerates of the chunks of linearization. */ /** Compute the feerates of the chunks of linearization. */
template<typename SetType> template<typename SetType>
std::vector<FeeFrac> ChunkLinearization(const DepGraph<SetType>& depgraph, Span<const ClusterIndex> linearization) noexcept std::vector<FeeFrac> ChunkLinearization(const DepGraph<SetType>& depgraph, std::span<const ClusterIndex> linearization) noexcept
{ {
std::vector<FeeFrac> ret; std::vector<FeeFrac> ret;
for (ClusterIndex i : linearization) { for (ClusterIndex i : linearization) {
@ -396,7 +396,7 @@ class LinearizationChunking
const DepGraph<SetType>& m_depgraph; const DepGraph<SetType>& m_depgraph;
/** The linearization we started from, possibly with removed prefix stripped. */ /** The linearization we started from, possibly with removed prefix stripped. */
Span<const ClusterIndex> m_linearization; std::span<const ClusterIndex> m_linearization;
/** Chunk sets and their feerates, of what remains of the linearization. */ /** Chunk sets and their feerates, of what remains of the linearization. */
std::vector<SetInfo<SetType>> m_chunks; std::vector<SetInfo<SetType>> m_chunks;
@ -437,7 +437,7 @@ class LinearizationChunking
public: public:
/** Initialize a LinearizationSubset object for a given length of linearization. */ /** Initialize a LinearizationSubset object for a given length of linearization. */
explicit LinearizationChunking(const DepGraph<SetType>& depgraph LIFETIMEBOUND, Span<const ClusterIndex> lin LIFETIMEBOUND) noexcept : explicit LinearizationChunking(const DepGraph<SetType>& depgraph LIFETIMEBOUND, std::span<const ClusterIndex> lin LIFETIMEBOUND) noexcept :
m_depgraph(depgraph), m_linearization(lin) m_depgraph(depgraph), m_linearization(lin)
{ {
// Mark everything in lin as todo still. // Mark everything in lin as todo still.
@ -1016,7 +1016,7 @@ public:
* Complexity: possibly O(N * min(max_iterations + N, sqrt(2^N))) where N=depgraph.TxCount(). * Complexity: possibly O(N * min(max_iterations + N, sqrt(2^N))) where N=depgraph.TxCount().
*/ */
template<typename SetType> template<typename SetType>
std::pair<std::vector<ClusterIndex>, bool> Linearize(const DepGraph<SetType>& depgraph, uint64_t max_iterations, uint64_t rng_seed, Span<const ClusterIndex> old_linearization = {}) noexcept std::pair<std::vector<ClusterIndex>, bool> Linearize(const DepGraph<SetType>& depgraph, uint64_t max_iterations, uint64_t rng_seed, std::span<const ClusterIndex> old_linearization = {}) noexcept
{ {
Assume(old_linearization.empty() || old_linearization.size() == depgraph.TxCount()); Assume(old_linearization.empty() || old_linearization.size() == depgraph.TxCount());
if (depgraph.TxCount() == 0) return {{}, true}; if (depgraph.TxCount() == 0) return {{}, true};
@ -1110,7 +1110,7 @@ std::pair<std::vector<ClusterIndex>, bool> Linearize(const DepGraph<SetType>& de
* postlinearize" process. * postlinearize" process.
*/ */
template<typename SetType> template<typename SetType>
void PostLinearize(const DepGraph<SetType>& depgraph, Span<ClusterIndex> linearization) void PostLinearize(const DepGraph<SetType>& depgraph, std::span<ClusterIndex> linearization)
{ {
// This algorithm performs a number of passes (currently 2); the even ones operate from back to // This algorithm performs a number of passes (currently 2); the even ones operate from back to
// front, the odd ones from front to back. Each results in an equal-or-better linearization // front, the odd ones from front to back. Each results in an equal-or-better linearization
@ -1299,7 +1299,7 @@ void PostLinearize(const DepGraph<SetType>& depgraph, Span<ClusterIndex> lineari
* Complexity: O(N^2) where N=depgraph.TxCount(); O(N) if both inputs are identical. * Complexity: O(N^2) where N=depgraph.TxCount(); O(N) if both inputs are identical.
*/ */
template<typename SetType> template<typename SetType>
std::vector<ClusterIndex> MergeLinearizations(const DepGraph<SetType>& depgraph, Span<const ClusterIndex> lin1, Span<const ClusterIndex> lin2) std::vector<ClusterIndex> MergeLinearizations(const DepGraph<SetType>& depgraph, std::span<const ClusterIndex> lin1, std::span<const ClusterIndex> lin2)
{ {
Assume(lin1.size() == depgraph.TxCount()); Assume(lin1.size() == depgraph.TxCount());
Assume(lin2.size() == depgraph.TxCount()); Assume(lin2.size() == depgraph.TxCount());

View file

@ -1,4 +1,4 @@
// Copyright (c) 2012-2022 The Bitcoin Core developers // Copyright (c) 2012-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -40,13 +40,13 @@ CBloomFilter::CBloomFilter(const unsigned int nElements, const double nFPRate, c
{ {
} }
inline unsigned int CBloomFilter::Hash(unsigned int nHashNum, Span<const unsigned char> vDataToHash) const inline unsigned int CBloomFilter::Hash(unsigned int nHashNum, std::span<const unsigned char> vDataToHash) const
{ {
// 0xFBA4C795 chosen as it guarantees a reasonable bit difference between nHashNum values. // 0xFBA4C795 chosen as it guarantees a reasonable bit difference between nHashNum values.
return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash) % (vData.size() * 8); return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash) % (vData.size() * 8);
} }
void CBloomFilter::insert(Span<const unsigned char> vKey) void CBloomFilter::insert(std::span<const unsigned char> vKey)
{ {
if (vData.empty()) // Avoid divide-by-zero (CVE-2013-5700) if (vData.empty()) // Avoid divide-by-zero (CVE-2013-5700)
return; return;
@ -65,7 +65,7 @@ void CBloomFilter::insert(const COutPoint& outpoint)
insert(MakeUCharSpan(stream)); insert(MakeUCharSpan(stream));
} }
bool CBloomFilter::contains(Span<const unsigned char> vKey) const bool CBloomFilter::contains(std::span<const unsigned char> vKey) const
{ {
if (vData.empty()) // Avoid divide-by-zero (CVE-2013-5700) if (vData.empty()) // Avoid divide-by-zero (CVE-2013-5700)
return true; return true;
@ -187,12 +187,12 @@ CRollingBloomFilter::CRollingBloomFilter(const unsigned int nElements, const dou
} }
/* Similar to CBloomFilter::Hash */ /* Similar to CBloomFilter::Hash */
static inline uint32_t RollingBloomHash(unsigned int nHashNum, uint32_t nTweak, Span<const unsigned char> vDataToHash) static inline uint32_t RollingBloomHash(unsigned int nHashNum, uint32_t nTweak, std::span<const unsigned char> vDataToHash)
{ {
return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash); return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash);
} }
void CRollingBloomFilter::insert(Span<const unsigned char> vKey) void CRollingBloomFilter::insert(std::span<const unsigned char> vKey)
{ {
if (nEntriesThisGeneration == nEntriesPerGeneration) { if (nEntriesThisGeneration == nEntriesPerGeneration) {
nEntriesThisGeneration = 0; nEntriesThisGeneration = 0;
@ -223,7 +223,7 @@ void CRollingBloomFilter::insert(Span<const unsigned char> vKey)
} }
} }
bool CRollingBloomFilter::contains(Span<const unsigned char> vKey) const bool CRollingBloomFilter::contains(std::span<const unsigned char> vKey) const
{ {
for (int n = 0; n < nHashFuncs; n++) { for (int n = 0; n < nHashFuncs; n++) {
uint32_t h = RollingBloomHash(n, nTweak, vKey); uint32_t h = RollingBloomHash(n, nTweak, vKey);

View file

@ -1,4 +1,4 @@
// Copyright (c) 2012-2021 The Bitcoin Core developers // Copyright (c) 2012-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -49,7 +49,7 @@ private:
unsigned int nTweak; unsigned int nTweak;
unsigned char nFlags; unsigned char nFlags;
unsigned int Hash(unsigned int nHashNum, Span<const unsigned char> vDataToHash) const; unsigned int Hash(unsigned int nHashNum, std::span<const unsigned char> vDataToHash) const;
public: public:
/** /**
@ -66,10 +66,10 @@ public:
SERIALIZE_METHODS(CBloomFilter, obj) { READWRITE(obj.vData, obj.nHashFuncs, obj.nTweak, obj.nFlags); } SERIALIZE_METHODS(CBloomFilter, obj) { READWRITE(obj.vData, obj.nHashFuncs, obj.nTweak, obj.nFlags); }
void insert(Span<const unsigned char> vKey); void insert(std::span<const unsigned char> vKey);
void insert(const COutPoint& outpoint); void insert(const COutPoint& outpoint);
bool contains(Span<const unsigned char> vKey) const; bool contains(std::span<const unsigned char> vKey) const;
bool contains(const COutPoint& outpoint) const; bool contains(const COutPoint& outpoint) const;
//! True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS //! True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS
@ -110,8 +110,8 @@ class CRollingBloomFilter
public: public:
CRollingBloomFilter(const unsigned int nElements, const double nFPRate); CRollingBloomFilter(const unsigned int nElements, const double nFPRate);
void insert(Span<const unsigned char> vKey); void insert(std::span<const unsigned char> vKey);
bool contains(Span<const unsigned char> vKey) const; bool contains(std::span<const unsigned char> vKey) const;
void reset(); void reset();

View file

@ -1,4 +1,4 @@
// Copyright (c) 2024 The Bitcoin Core developers // Copyright (c) 2024-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php. // file COPYING or https://www.opensource.org/licenses/mit-license.php.
@ -179,7 +179,7 @@ std::string PCPResultString(uint8_t result_code)
} }
//! Wrap address in IPv6 according to RFC6887. wrapped_addr needs to be able to store 16 bytes. //! Wrap address in IPv6 according to RFC6887. wrapped_addr needs to be able to store 16 bytes.
[[nodiscard]] bool PCPWrapAddress(Span<uint8_t> wrapped_addr, const CNetAddr &addr) [[nodiscard]] bool PCPWrapAddress(std::span<uint8_t> wrapped_addr, const CNetAddr &addr)
{ {
Assume(wrapped_addr.size() == ADDR_IPV6_SIZE); Assume(wrapped_addr.size() == ADDR_IPV6_SIZE);
if (addr.IsIPv4()) { if (addr.IsIPv4()) {
@ -200,7 +200,7 @@ std::string PCPResultString(uint8_t result_code)
} }
//! Unwrap PCP-encoded address according to RFC6887. //! Unwrap PCP-encoded address according to RFC6887.
CNetAddr PCPUnwrapAddress(Span<const uint8_t> wrapped_addr) CNetAddr PCPUnwrapAddress(std::span<const uint8_t> wrapped_addr)
{ {
Assume(wrapped_addr.size() == ADDR_IPV6_SIZE); Assume(wrapped_addr.size() == ADDR_IPV6_SIZE);
if (util::HasPrefix(wrapped_addr, IPV4_IN_IPV6_PREFIX)) { if (util::HasPrefix(wrapped_addr, IPV4_IN_IPV6_PREFIX)) {
@ -215,9 +215,9 @@ CNetAddr PCPUnwrapAddress(Span<const uint8_t> wrapped_addr)
} }
//! PCP or NAT-PMP send-receive loop. //! PCP or NAT-PMP send-receive loop.
std::optional<std::vector<uint8_t>> PCPSendRecv(Sock &sock, const std::string &protocol, Span<const uint8_t> request, int num_tries, std::optional<std::vector<uint8_t>> PCPSendRecv(Sock &sock, const std::string &protocol, std::span<const uint8_t> request, int num_tries,
std::chrono::milliseconds timeout_per_try, std::chrono::milliseconds timeout_per_try,
std::function<bool(Span<const uint8_t>)> check_packet) std::function<bool(std::span<const uint8_t>)> check_packet)
{ {
using namespace std::chrono; using namespace std::chrono;
// UDP is a potentially lossy protocol, so we try to send again a few times. // UDP is a potentially lossy protocol, so we try to send again a few times.
@ -254,9 +254,9 @@ std::optional<std::vector<uint8_t>> PCPSendRecv(Sock &sock, const std::string &p
LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "%s: Could not receive response: %s\n", protocol, NetworkErrorString(WSAGetLastError())); LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "%s: Could not receive response: %s\n", protocol, NetworkErrorString(WSAGetLastError()));
return std::nullopt; // Network-level error, probably no use retrying. return std::nullopt; // Network-level error, probably no use retrying.
} }
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "%s: Received response of %d bytes: %s\n", protocol, recvsz, HexStr(Span(response, recvsz))); LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "%s: Received response of %d bytes: %s\n", protocol, recvsz, HexStr(std::span(response, recvsz)));
if (check_packet(Span<uint8_t>(response, recvsz))) { if (check_packet(std::span<uint8_t>(response, recvsz))) {
got_response = true; // Got expected response, break from receive loop as well as from retry loop. got_response = true; // Got expected response, break from receive loop as well as from retry loop.
break; break;
} }
@ -309,7 +309,7 @@ std::variant<MappingResult, MappingError> NATPMPRequestPortMap(const CNetAddr &g
request[NATPMP_HDR_OP_OFS] = NATPMP_REQUEST | NATPMP_OP_GETEXTERNAL; request[NATPMP_HDR_OP_OFS] = NATPMP_REQUEST | NATPMP_OP_GETEXTERNAL;
auto recv_res = PCPSendRecv(*sock, "natpmp", request, num_tries, timeout_per_try, auto recv_res = PCPSendRecv(*sock, "natpmp", request, num_tries, timeout_per_try,
[&](const Span<const uint8_t> response) -> bool { [&](const std::span<const uint8_t> response) -> bool {
if (response.size() < NATPMP_GETEXTERNAL_RESPONSE_SIZE) { if (response.size() < NATPMP_GETEXTERNAL_RESPONSE_SIZE) {
LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "natpmp: Response too small\n"); LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "natpmp: Response too small\n");
return false; // Wasn't response to what we expected, try receiving next packet. return false; // Wasn't response to what we expected, try receiving next packet.
@ -346,7 +346,7 @@ std::variant<MappingResult, MappingError> NATPMPRequestPortMap(const CNetAddr &g
WriteBE32(request.data() + NATPMP_MAP_REQUEST_LIFETIME_OFS, lifetime); WriteBE32(request.data() + NATPMP_MAP_REQUEST_LIFETIME_OFS, lifetime);
recv_res = PCPSendRecv(*sock, "natpmp", request, num_tries, timeout_per_try, recv_res = PCPSendRecv(*sock, "natpmp", request, num_tries, timeout_per_try,
[&](const Span<const uint8_t> response) -> bool { [&](const std::span<const uint8_t> response) -> bool {
if (response.size() < NATPMP_MAP_RESPONSE_SIZE) { if (response.size() < NATPMP_MAP_RESPONSE_SIZE) {
LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "natpmp: Response too small\n"); LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "natpmp: Response too small\n");
return false; // Wasn't response to what we expected, try receiving next packet. return false; // Wasn't response to what we expected, try receiving next packet.
@ -438,7 +438,7 @@ std::variant<MappingResult, MappingError> PCPRequestPortMap(const PCPMappingNonc
request[ofs + PCP_HDR_VERSION_OFS] = PCP_VERSION; request[ofs + PCP_HDR_VERSION_OFS] = PCP_VERSION;
request[ofs + PCP_HDR_OP_OFS] = PCP_REQUEST | PCP_OP_MAP; request[ofs + PCP_HDR_OP_OFS] = PCP_REQUEST | PCP_OP_MAP;
WriteBE32(request.data() + ofs + PCP_HDR_LIFETIME_OFS, lifetime); WriteBE32(request.data() + ofs + PCP_HDR_LIFETIME_OFS, lifetime);
if (!PCPWrapAddress(Span(request).subspan(ofs + PCP_REQUEST_HDR_IP_OFS, ADDR_IPV6_SIZE), internal)) return MappingError::NETWORK_ERROR; if (!PCPWrapAddress(std::span(request).subspan(ofs + PCP_REQUEST_HDR_IP_OFS, ADDR_IPV6_SIZE), internal)) return MappingError::NETWORK_ERROR;
ofs += PCP_HDR_SIZE; ofs += PCP_HDR_SIZE;
@ -449,7 +449,7 @@ std::variant<MappingResult, MappingError> PCPRequestPortMap(const PCPMappingNonc
request[ofs + PCP_MAP_PROTOCOL_OFS] = PCP_PROTOCOL_TCP; request[ofs + PCP_MAP_PROTOCOL_OFS] = PCP_PROTOCOL_TCP;
WriteBE16(request.data() + ofs + PCP_MAP_INTERNAL_PORT_OFS, port); WriteBE16(request.data() + ofs + PCP_MAP_INTERNAL_PORT_OFS, port);
WriteBE16(request.data() + ofs + PCP_MAP_EXTERNAL_PORT_OFS, port); WriteBE16(request.data() + ofs + PCP_MAP_EXTERNAL_PORT_OFS, port);
if (!PCPWrapAddress(Span(request).subspan(ofs + PCP_MAP_EXTERNAL_IP_OFS, ADDR_IPV6_SIZE), bind)) return MappingError::NETWORK_ERROR; if (!PCPWrapAddress(std::span(request).subspan(ofs + PCP_MAP_EXTERNAL_IP_OFS, ADDR_IPV6_SIZE), bind)) return MappingError::NETWORK_ERROR;
ofs += PCP_MAP_SIZE; ofs += PCP_MAP_SIZE;
Assume(ofs == request.size()); Assume(ofs == request.size());
@ -457,7 +457,7 @@ std::variant<MappingResult, MappingError> PCPRequestPortMap(const PCPMappingNonc
// Receive loop. // Receive loop.
bool is_natpmp = false; bool is_natpmp = false;
auto recv_res = PCPSendRecv(*sock, "pcp", request, num_tries, timeout_per_try, auto recv_res = PCPSendRecv(*sock, "pcp", request, num_tries, timeout_per_try,
[&](const Span<const uint8_t> response) -> bool { [&](const std::span<const uint8_t> response) -> bool {
// Unsupported version according to RFC6887 appendix A and RFC6886 section 3.5, can fall back to NAT-PMP. // Unsupported version according to RFC6887 appendix A and RFC6886 section 3.5, can fall back to NAT-PMP.
if (response.size() == NATPMP_RESPONSE_HDR_SIZE && response[PCP_HDR_VERSION_OFS] == NATPMP_VERSION && response[PCP_RESPONSE_HDR_RESULT_OFS] == NATPMP_RESULT_UNSUPP_VERSION) { if (response.size() == NATPMP_RESPONSE_HDR_SIZE && response[PCP_HDR_VERSION_OFS] == NATPMP_VERSION && response[PCP_RESPONSE_HDR_RESULT_OFS] == NATPMP_RESULT_UNSUPP_VERSION) {
is_natpmp = true; is_natpmp = true;

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2021 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -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 << Span{compr}; s << std::span{compr};
return; return;
} }
unsigned int nSize = script.size() + nSpecialScripts; unsigned int nSize = script.size() + nSpecialScripts;
s << VARINT(nSize); s << VARINT(nSize);
s << Span{script}; s << std::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 >> Span{vch}; s >> std::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 >> Span{script}; s >> std::span{script};
} }
} }
}; };

View file

@ -22,7 +22,7 @@
#define REPEAT10(a) do { {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; } while(0) #define REPEAT10(a) do { {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; } while(0)
void ChaCha20Aligned::SetKey(Span<const std::byte> key) noexcept void ChaCha20Aligned::SetKey(std::span<const std::byte> key) noexcept
{ {
assert(key.size() == KEYLEN); assert(key.size() == KEYLEN);
input[0] = ReadLE32(key.data() + 0); input[0] = ReadLE32(key.data() + 0);
@ -44,7 +44,7 @@ ChaCha20Aligned::~ChaCha20Aligned()
memory_cleanse(input, sizeof(input)); memory_cleanse(input, sizeof(input));
} }
ChaCha20Aligned::ChaCha20Aligned(Span<const std::byte> key) noexcept ChaCha20Aligned::ChaCha20Aligned(std::span<const std::byte> key) noexcept
{ {
SetKey(key); SetKey(key);
} }
@ -57,7 +57,7 @@ void ChaCha20Aligned::Seek(Nonce96 nonce, uint32_t block_counter) noexcept
input[11] = nonce.second >> 32; input[11] = nonce.second >> 32;
} }
inline void ChaCha20Aligned::Keystream(Span<std::byte> output) noexcept inline void ChaCha20Aligned::Keystream(std::span<std::byte> output) noexcept
{ {
std::byte* c = output.data(); std::byte* c = output.data();
size_t blocks = output.size() / BLOCKLEN; size_t blocks = output.size() / BLOCKLEN;
@ -158,7 +158,7 @@ inline void ChaCha20Aligned::Keystream(Span<std::byte> output) noexcept
} }
} }
inline void ChaCha20Aligned::Crypt(Span<const std::byte> in_bytes, Span<std::byte> out_bytes) noexcept inline void ChaCha20Aligned::Crypt(std::span<const std::byte> in_bytes, std::span<std::byte> out_bytes) noexcept
{ {
assert(in_bytes.size() == out_bytes.size()); assert(in_bytes.size() == out_bytes.size());
const std::byte* m = in_bytes.data(); const std::byte* m = in_bytes.data();
@ -279,7 +279,7 @@ inline void ChaCha20Aligned::Crypt(Span<const std::byte> in_bytes, Span<std::byt
} }
} }
void ChaCha20::Keystream(Span<std::byte> out) noexcept void ChaCha20::Keystream(std::span<std::byte> out) noexcept
{ {
if (out.empty()) return; if (out.empty()) return;
if (m_bufleft) { if (m_bufleft) {
@ -300,7 +300,7 @@ void ChaCha20::Keystream(Span<std::byte> out) noexcept
} }
} }
void ChaCha20::Crypt(Span<const std::byte> input, Span<std::byte> output) noexcept void ChaCha20::Crypt(std::span<const std::byte> input, std::span<std::byte> output) noexcept
{ {
assert(input.size() == output.size()); assert(input.size() == output.size());
@ -334,20 +334,20 @@ ChaCha20::~ChaCha20()
memory_cleanse(m_buffer.data(), m_buffer.size()); memory_cleanse(m_buffer.data(), m_buffer.size());
} }
void ChaCha20::SetKey(Span<const std::byte> key) noexcept void ChaCha20::SetKey(std::span<const std::byte> key) noexcept
{ {
m_aligned.SetKey(key); m_aligned.SetKey(key);
m_bufleft = 0; m_bufleft = 0;
memory_cleanse(m_buffer.data(), m_buffer.size()); memory_cleanse(m_buffer.data(), m_buffer.size());
} }
FSChaCha20::FSChaCha20(Span<const std::byte> key, uint32_t rekey_interval) noexcept : FSChaCha20::FSChaCha20(std::span<const std::byte> key, uint32_t rekey_interval) noexcept :
m_chacha20(key), m_rekey_interval(rekey_interval) m_chacha20(key), m_rekey_interval(rekey_interval)
{ {
assert(key.size() == KEYLEN); assert(key.size() == KEYLEN);
} }
void FSChaCha20::Crypt(Span<const std::byte> input, Span<std::byte> output) noexcept void FSChaCha20::Crypt(std::span<const std::byte> input, std::span<std::byte> output) noexcept
{ {
assert(input.size() == output.size()); assert(input.size() == output.size());

View file

@ -1,4 +1,4 @@
// Copyright (c) 2017-2022 The Bitcoin Core developers // Copyright (c) 2017-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -38,13 +38,13 @@ public:
ChaCha20Aligned() noexcept = delete; ChaCha20Aligned() noexcept = delete;
/** Initialize a cipher with specified 32-byte key. */ /** Initialize a cipher with specified 32-byte key. */
ChaCha20Aligned(Span<const std::byte> key) noexcept; ChaCha20Aligned(std::span<const std::byte> key) noexcept;
/** Destructor to clean up private memory. */ /** Destructor to clean up private memory. */
~ChaCha20Aligned(); ~ChaCha20Aligned();
/** Set 32-byte key, and seek to nonce 0 and block position 0. */ /** Set 32-byte key, and seek to nonce 0 and block position 0. */
void SetKey(Span<const std::byte> key) noexcept; void SetKey(std::span<const std::byte> key) noexcept;
/** Type for 96-bit nonces used by the Set function below. /** Type for 96-bit nonces used by the Set function below.
* *
@ -64,13 +64,13 @@ public:
void Seek(Nonce96 nonce, uint32_t block_counter) noexcept; void Seek(Nonce96 nonce, uint32_t block_counter) noexcept;
/** outputs the keystream into out, whose length must be a multiple of BLOCKLEN. */ /** outputs the keystream into out, whose length must be a multiple of BLOCKLEN. */
void Keystream(Span<std::byte> out) noexcept; void Keystream(std::span<std::byte> out) noexcept;
/** en/deciphers the message <input> and write the result into <output> /** en/deciphers the message <input> and write the result into <output>
* *
* The size of input and output must be equal, and be a multiple of BLOCKLEN. * The size of input and output must be equal, and be a multiple of BLOCKLEN.
*/ */
void Crypt(Span<const std::byte> input, Span<std::byte> output) noexcept; void Crypt(std::span<const std::byte> input, std::span<std::byte> output) noexcept;
}; };
/** Unrestricted ChaCha20 cipher. */ /** Unrestricted ChaCha20 cipher. */
@ -89,13 +89,13 @@ public:
ChaCha20() noexcept = delete; ChaCha20() noexcept = delete;
/** Initialize a cipher with specified 32-byte key. */ /** Initialize a cipher with specified 32-byte key. */
ChaCha20(Span<const std::byte> key) noexcept : m_aligned(key) {} ChaCha20(std::span<const std::byte> key) noexcept : m_aligned(key) {}
/** Destructor to clean up private memory. */ /** Destructor to clean up private memory. */
~ChaCha20(); ~ChaCha20();
/** Set 32-byte key, and seek to nonce 0 and block position 0. */ /** Set 32-byte key, and seek to nonce 0 and block position 0. */
void SetKey(Span<const std::byte> key) noexcept; void SetKey(std::span<const std::byte> key) noexcept;
/** 96-bit nonce type. */ /** 96-bit nonce type. */
using Nonce96 = ChaCha20Aligned::Nonce96; using Nonce96 = ChaCha20Aligned::Nonce96;
@ -111,10 +111,10 @@ public:
* *
* The size of in_bytes and out_bytes must be equal. * The size of in_bytes and out_bytes must be equal.
*/ */
void Crypt(Span<const std::byte> in_bytes, Span<std::byte> out_bytes) noexcept; void Crypt(std::span<const std::byte> in_bytes, std::span<std::byte> out_bytes) noexcept;
/** outputs the keystream to out. */ /** outputs the keystream to out. */
void Keystream(Span<std::byte> out) noexcept; void Keystream(std::span<std::byte> out) noexcept;
}; };
/** Forward-secure ChaCha20 /** Forward-secure ChaCha20
@ -150,10 +150,10 @@ public:
FSChaCha20& operator=(FSChaCha20&&) = delete; FSChaCha20& operator=(FSChaCha20&&) = delete;
/** Construct an FSChaCha20 cipher that rekeys every rekey_interval Crypt() calls. */ /** Construct an FSChaCha20 cipher that rekeys every rekey_interval Crypt() calls. */
FSChaCha20(Span<const std::byte> key, uint32_t rekey_interval) noexcept; FSChaCha20(std::span<const std::byte> key, uint32_t rekey_interval) noexcept;
/** Encrypt or decrypt a chunk. */ /** Encrypt or decrypt a chunk. */
void Crypt(Span<const std::byte> input, Span<std::byte> output) noexcept; void Crypt(std::span<const std::byte> input, std::span<std::byte> output) noexcept;
}; };
#endif // BITCOIN_CRYPTO_CHACHA20_H #endif // BITCOIN_CRYPTO_CHACHA20_H

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023 The Bitcoin Core developers // Copyright (c) 2023-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -13,12 +13,12 @@
#include <assert.h> #include <assert.h>
#include <cstddef> #include <cstddef>
AEADChaCha20Poly1305::AEADChaCha20Poly1305(Span<const std::byte> key) noexcept : m_chacha20(key) AEADChaCha20Poly1305::AEADChaCha20Poly1305(std::span<const std::byte> key) noexcept : m_chacha20(key)
{ {
assert(key.size() == KEYLEN); assert(key.size() == KEYLEN);
} }
void AEADChaCha20Poly1305::SetKey(Span<const std::byte> key) noexcept void AEADChaCha20Poly1305::SetKey(std::span<const std::byte> key) noexcept
{ {
assert(key.size() == KEYLEN); assert(key.size() == KEYLEN);
m_chacha20.SetKey(key); m_chacha20.SetKey(key);
@ -36,7 +36,7 @@ int timingsafe_bcmp_internal(const unsigned char* b1, const unsigned char* b2, s
} }
/** Compute poly1305 tag. chacha20 must be set to the right nonce, block 0. Will be at block 1 after. */ /** Compute poly1305 tag. chacha20 must be set to the right nonce, block 0. Will be at block 1 after. */
void ComputeTag(ChaCha20& chacha20, Span<const std::byte> aad, Span<const std::byte> cipher, Span<std::byte> tag) noexcept void ComputeTag(ChaCha20& chacha20, std::span<const std::byte> aad, std::span<const std::byte> cipher, std::span<std::byte> tag) noexcept
{ {
static const std::byte PADDING[16] = {{}}; static const std::byte PADDING[16] = {{}};
@ -45,15 +45,15 @@ void ComputeTag(ChaCha20& chacha20, Span<const std::byte> aad, Span<const std::b
chacha20.Keystream(first_block); chacha20.Keystream(first_block);
// Use the first 32 bytes of the first keystream block as poly1305 key. // Use the first 32 bytes of the first keystream block as poly1305 key.
Poly1305 poly1305{Span{first_block}.first(Poly1305::KEYLEN)}; Poly1305 poly1305{std::span{first_block}.first(Poly1305::KEYLEN)};
// Compute tag: // Compute tag:
// - Process the padded AAD with Poly1305. // - Process the padded AAD with Poly1305.
const unsigned aad_padding_length = (16 - (aad.size() % 16)) % 16; const unsigned aad_padding_length = (16 - (aad.size() % 16)) % 16;
poly1305.Update(aad).Update(Span{PADDING}.first(aad_padding_length)); poly1305.Update(aad).Update(std::span{PADDING}.first(aad_padding_length));
// - Process the padded ciphertext with Poly1305. // - Process the padded ciphertext with Poly1305.
const unsigned cipher_padding_length = (16 - (cipher.size() % 16)) % 16; const unsigned cipher_padding_length = (16 - (cipher.size() % 16)) % 16;
poly1305.Update(cipher).Update(Span{PADDING}.first(cipher_padding_length)); poly1305.Update(cipher).Update(std::span{PADDING}.first(cipher_padding_length));
// - Process the AAD and plaintext length with Poly1305. // - Process the AAD and plaintext length with Poly1305.
std::byte length_desc[Poly1305::TAGLEN]; std::byte length_desc[Poly1305::TAGLEN];
WriteLE64(length_desc, aad.size()); WriteLE64(length_desc, aad.size());
@ -66,7 +66,7 @@ void ComputeTag(ChaCha20& chacha20, Span<const std::byte> aad, Span<const std::b
} // namespace } // namespace
void AEADChaCha20Poly1305::Encrypt(Span<const std::byte> plain1, Span<const std::byte> plain2, Span<const std::byte> aad, Nonce96 nonce, Span<std::byte> cipher) noexcept void AEADChaCha20Poly1305::Encrypt(std::span<const std::byte> plain1, std::span<const std::byte> plain2, std::span<const std::byte> aad, Nonce96 nonce, std::span<std::byte> cipher) noexcept
{ {
assert(cipher.size() == plain1.size() + plain2.size() + EXPANSION); assert(cipher.size() == plain1.size() + plain2.size() + EXPANSION);
@ -80,7 +80,7 @@ void AEADChaCha20Poly1305::Encrypt(Span<const std::byte> plain1, Span<const std:
ComputeTag(m_chacha20, aad, cipher.first(cipher.size() - EXPANSION), cipher.last(EXPANSION)); ComputeTag(m_chacha20, aad, cipher.first(cipher.size() - EXPANSION), cipher.last(EXPANSION));
} }
bool AEADChaCha20Poly1305::Decrypt(Span<const std::byte> cipher, Span<const std::byte> aad, Nonce96 nonce, Span<std::byte> plain1, Span<std::byte> plain2) noexcept bool AEADChaCha20Poly1305::Decrypt(std::span<const std::byte> cipher, std::span<const std::byte> aad, Nonce96 nonce, std::span<std::byte> plain1, std::span<std::byte> plain2) noexcept
{ {
assert(cipher.size() == plain1.size() + plain2.size() + EXPANSION); assert(cipher.size() == plain1.size() + plain2.size() + EXPANSION);
@ -96,7 +96,7 @@ bool AEADChaCha20Poly1305::Decrypt(Span<const std::byte> cipher, Span<const std:
return true; return true;
} }
void AEADChaCha20Poly1305::Keystream(Nonce96 nonce, Span<std::byte> keystream) noexcept void AEADChaCha20Poly1305::Keystream(Nonce96 nonce, std::span<std::byte> keystream) noexcept
{ {
// Skip the first output block, as it's used for generating the poly1305 key. // Skip the first output block, as it's used for generating the poly1305 key.
m_chacha20.Seek(nonce, 1); m_chacha20.Seek(nonce, 1);
@ -111,7 +111,7 @@ void FSChaCha20Poly1305::NextPacket() noexcept
std::byte one_block[ChaCha20Aligned::BLOCKLEN]; std::byte one_block[ChaCha20Aligned::BLOCKLEN];
m_aead.Keystream({0xFFFFFFFF, m_rekey_counter}, one_block); m_aead.Keystream({0xFFFFFFFF, m_rekey_counter}, one_block);
// Switch keys. // Switch keys.
m_aead.SetKey(Span{one_block}.first(KEYLEN)); m_aead.SetKey(std::span{one_block}.first(KEYLEN));
// Wipe the generated keystream (a copy remains inside m_aead, which will be cleaned up // Wipe the generated keystream (a copy remains inside m_aead, which will be cleaned up
// once it cycles again, or is destroyed). // once it cycles again, or is destroyed).
memory_cleanse(one_block, sizeof(one_block)); memory_cleanse(one_block, sizeof(one_block));
@ -121,13 +121,13 @@ void FSChaCha20Poly1305::NextPacket() noexcept
} }
} }
void FSChaCha20Poly1305::Encrypt(Span<const std::byte> plain1, Span<const std::byte> plain2, Span<const std::byte> aad, Span<std::byte> cipher) noexcept void FSChaCha20Poly1305::Encrypt(std::span<const std::byte> plain1, std::span<const std::byte> plain2, std::span<const std::byte> aad, std::span<std::byte> cipher) noexcept
{ {
m_aead.Encrypt(plain1, plain2, aad, {m_packet_counter, m_rekey_counter}, cipher); m_aead.Encrypt(plain1, plain2, aad, {m_packet_counter, m_rekey_counter}, cipher);
NextPacket(); NextPacket();
} }
bool FSChaCha20Poly1305::Decrypt(Span<const std::byte> cipher, Span<const std::byte> aad, Span<std::byte> plain1, Span<std::byte> plain2) noexcept bool FSChaCha20Poly1305::Decrypt(std::span<const std::byte> cipher, std::span<const std::byte> aad, std::span<std::byte> plain1, std::span<std::byte> plain2) noexcept
{ {
bool ret = m_aead.Decrypt(cipher, aad, {m_packet_counter, m_rekey_counter}, plain1, plain2); bool ret = m_aead.Decrypt(cipher, aad, {m_packet_counter, m_rekey_counter}, plain1, plain2);
NextPacket(); NextPacket();

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023 The Bitcoin Core developers // Copyright (c) 2023-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -26,10 +26,10 @@ public:
static constexpr unsigned EXPANSION = Poly1305::TAGLEN; static constexpr unsigned EXPANSION = Poly1305::TAGLEN;
/** Initialize an AEAD instance with a specified 32-byte key. */ /** Initialize an AEAD instance with a specified 32-byte key. */
AEADChaCha20Poly1305(Span<const std::byte> key) noexcept; AEADChaCha20Poly1305(std::span<const std::byte> key) noexcept;
/** Switch to another 32-byte key. */ /** Switch to another 32-byte key. */
void SetKey(Span<const std::byte> key) noexcept; void SetKey(std::span<const std::byte> key) noexcept;
/** 96-bit nonce type. */ /** 96-bit nonce type. */
using Nonce96 = ChaCha20::Nonce96; using Nonce96 = ChaCha20::Nonce96;
@ -38,7 +38,7 @@ public:
* *
* Requires cipher.size() = plain.size() + EXPANSION. * Requires cipher.size() = plain.size() + EXPANSION.
*/ */
void Encrypt(Span<const std::byte> plain, Span<const std::byte> aad, Nonce96 nonce, Span<std::byte> cipher) noexcept void Encrypt(std::span<const std::byte> plain, std::span<const std::byte> aad, Nonce96 nonce, std::span<std::byte> cipher) noexcept
{ {
Encrypt(plain, {}, aad, nonce, cipher); Encrypt(plain, {}, aad, nonce, cipher);
} }
@ -47,13 +47,13 @@ public:
* *
* Requires cipher.size() = plain1.size() + plain2.size() + EXPANSION. * Requires cipher.size() = plain1.size() + plain2.size() + EXPANSION.
*/ */
void Encrypt(Span<const std::byte> plain1, Span<const std::byte> plain2, Span<const std::byte> aad, Nonce96 nonce, Span<std::byte> cipher) noexcept; void Encrypt(std::span<const std::byte> plain1, std::span<const std::byte> plain2, std::span<const std::byte> aad, Nonce96 nonce, std::span<std::byte> cipher) noexcept;
/** Decrypt a message with a specified 96-bit nonce and aad. Returns true if valid. /** Decrypt a message with a specified 96-bit nonce and aad. Returns true if valid.
* *
* Requires cipher.size() = plain.size() + EXPANSION. * Requires cipher.size() = plain.size() + EXPANSION.
*/ */
bool Decrypt(Span<const std::byte> cipher, Span<const std::byte> aad, Nonce96 nonce, Span<std::byte> plain) noexcept bool Decrypt(std::span<const std::byte> cipher, std::span<const std::byte> aad, Nonce96 nonce, std::span<std::byte> plain) noexcept
{ {
return Decrypt(cipher, aad, nonce, plain, {}); return Decrypt(cipher, aad, nonce, plain, {});
} }
@ -62,14 +62,14 @@ public:
* *
* Requires cipher.size() = plain1.size() + plain2.size() + EXPANSION. * Requires cipher.size() = plain1.size() + plain2.size() + EXPANSION.
*/ */
bool Decrypt(Span<const std::byte> cipher, Span<const std::byte> aad, Nonce96 nonce, Span<std::byte> plain1, Span<std::byte> plain2) noexcept; bool Decrypt(std::span<const std::byte> cipher, std::span<const std::byte> aad, Nonce96 nonce, std::span<std::byte> plain1, std::span<std::byte> plain2) noexcept;
/** Get a number of keystream bytes from the underlying stream cipher. /** Get a number of keystream bytes from the underlying stream cipher.
* *
* This is equivalent to Encrypt() with plain set to that many zero bytes, and dropping the * This is equivalent to Encrypt() with plain set to that many zero bytes, and dropping the
* last EXPANSION bytes off the result. * last EXPANSION bytes off the result.
*/ */
void Keystream(Nonce96 nonce, Span<std::byte> keystream) noexcept; void Keystream(Nonce96 nonce, std::span<std::byte> keystream) noexcept;
}; };
/** Forward-secure wrapper around AEADChaCha20Poly1305. /** Forward-secure wrapper around AEADChaCha20Poly1305.
@ -111,14 +111,14 @@ public:
FSChaCha20Poly1305& operator=(FSChaCha20Poly1305&&) = delete; FSChaCha20Poly1305& operator=(FSChaCha20Poly1305&&) = delete;
/** Construct an FSChaCha20Poly1305 cipher that rekeys every rekey_interval operations. */ /** Construct an FSChaCha20Poly1305 cipher that rekeys every rekey_interval operations. */
FSChaCha20Poly1305(Span<const std::byte> key, uint32_t rekey_interval) noexcept : FSChaCha20Poly1305(std::span<const std::byte> key, uint32_t rekey_interval) noexcept :
m_aead(key), m_rekey_interval(rekey_interval) {} m_aead(key), m_rekey_interval(rekey_interval) {}
/** Encrypt a message with a specified aad. /** Encrypt a message with a specified aad.
* *
* Requires cipher.size() = plain.size() + EXPANSION. * Requires cipher.size() = plain.size() + EXPANSION.
*/ */
void Encrypt(Span<const std::byte> plain, Span<const std::byte> aad, Span<std::byte> cipher) noexcept void Encrypt(std::span<const std::byte> plain, std::span<const std::byte> aad, std::span<std::byte> cipher) noexcept
{ {
Encrypt(plain, {}, aad, cipher); Encrypt(plain, {}, aad, cipher);
} }
@ -127,13 +127,13 @@ public:
* *
* Requires cipher.size() = plain.size() + EXPANSION. * Requires cipher.size() = plain.size() + EXPANSION.
*/ */
void Encrypt(Span<const std::byte> plain1, Span<const std::byte> plain2, Span<const std::byte> aad, Span<std::byte> cipher) noexcept; void Encrypt(std::span<const std::byte> plain1, std::span<const std::byte> plain2, std::span<const std::byte> aad, std::span<std::byte> cipher) noexcept;
/** Decrypt a message with a specified aad. Returns true if valid. /** Decrypt a message with a specified aad. Returns true if valid.
* *
* Requires cipher.size() = plain.size() + EXPANSION. * Requires cipher.size() = plain.size() + EXPANSION.
*/ */
bool Decrypt(Span<const std::byte> cipher, Span<const std::byte> aad, Span<std::byte> plain) noexcept bool Decrypt(std::span<const std::byte> cipher, std::span<const std::byte> aad, std::span<std::byte> plain) noexcept
{ {
return Decrypt(cipher, aad, plain, {}); return Decrypt(cipher, aad, plain, {});
} }
@ -142,7 +142,7 @@ public:
* *
* Requires cipher.size() = plain1.size() + plain2.size() + EXPANSION. * Requires cipher.size() = plain1.size() + plain2.size() + EXPANSION.
*/ */
bool Decrypt(Span<const std::byte> cipher, Span<const std::byte> aad, Span<std::byte> plain1, Span<std::byte> plain2) noexcept; bool Decrypt(std::span<const std::byte> cipher, std::span<const std::byte> aad, std::span<std::byte> plain1, std::span<std::byte> plain2) noexcept;
}; };
#endif // BITCOIN_CRYPTO_CHACHA20POLY1305_H #endif // BITCOIN_CRYPTO_CHACHA20POLY1305_H

View file

@ -26,7 +26,7 @@ constexpr std::array<ByteAsHex, 256> CreateByteToHexMap()
} // namespace } // namespace
std::string HexStr(const Span<const uint8_t> s) std::string HexStr(const std::span<const uint8_t> s)
{ {
std::string rv(s.size() * 2, '\0'); std::string rv(s.size() * 2, '\0');
static constexpr auto byte_to_hex = CreateByteToHexMap(); static constexpr auto byte_to_hex = CreateByteToHexMap();

View file

@ -14,9 +14,9 @@
/** /**
* Convert a span of bytes to a lower-case hexadecimal string. * Convert a span of bytes to a lower-case hexadecimal string.
*/ */
std::string HexStr(const Span<const uint8_t> s); std::string HexStr(const std::span<const uint8_t> s);
inline std::string HexStr(const Span<const char> s) { return HexStr(MakeUCharSpan(s)); } inline std::string HexStr(const std::span<const char> s) { return HexStr(MakeUCharSpan(s)); }
inline std::string HexStr(const Span<const std::byte> s) { return HexStr(MakeUCharSpan(s)); } inline std::string HexStr(const std::span<const std::byte> s) { return HexStr(MakeUCharSpan(s)); }
signed char HexDigit(char c); signed char HexDigit(char c);

View file

@ -1,4 +1,4 @@
// Copyright (c) 2017-2022 The Bitcoin Core developers // Copyright (c) 2017-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -532,7 +532,7 @@ void Num3072::ToBytes(unsigned char (&out)[BYTE_SIZE]) {
} }
} }
Num3072 MuHash3072::ToNum3072(Span<const unsigned char> in) { Num3072 MuHash3072::ToNum3072(std::span<const unsigned char> in) {
unsigned char tmp[Num3072::BYTE_SIZE]; unsigned char tmp[Num3072::BYTE_SIZE];
uint256 hashed_in{(HashWriter{} << in).GetSHA256()}; uint256 hashed_in{(HashWriter{} << in).GetSHA256()};
@ -543,7 +543,7 @@ Num3072 MuHash3072::ToNum3072(Span<const unsigned char> in) {
return out; return out;
} }
MuHash3072::MuHash3072(Span<const unsigned char> in) noexcept MuHash3072::MuHash3072(std::span<const unsigned char> in) noexcept
{ {
m_numerator = ToNum3072(in); m_numerator = ToNum3072(in);
} }
@ -573,12 +573,12 @@ MuHash3072& MuHash3072::operator/=(const MuHash3072& div) noexcept
return *this; return *this;
} }
MuHash3072& MuHash3072::Insert(Span<const unsigned char> in) noexcept { MuHash3072& MuHash3072::Insert(std::span<const unsigned char> in) noexcept {
m_numerator.Multiply(ToNum3072(in)); m_numerator.Multiply(ToNum3072(in));
return *this; return *this;
} }
MuHash3072& MuHash3072::Remove(Span<const unsigned char> in) noexcept { MuHash3072& MuHash3072::Remove(std::span<const unsigned char> in) noexcept {
m_denominator.Multiply(ToNum3072(in)); m_denominator.Multiply(ToNum3072(in));
return *this; return *this;
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) 2017-2021 The Bitcoin Core developers // Copyright (c) 2017-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -102,20 +102,20 @@ private:
Num3072 m_numerator; Num3072 m_numerator;
Num3072 m_denominator; Num3072 m_denominator;
Num3072 ToNum3072(Span<const unsigned char> in); Num3072 ToNum3072(std::span<const unsigned char> in);
public: public:
/* The empty set. */ /* The empty set. */
MuHash3072() noexcept = default; MuHash3072() noexcept = default;
/* A singleton with variable sized data in it. */ /* A singleton with variable sized data in it. */
explicit MuHash3072(Span<const unsigned char> in) noexcept; explicit MuHash3072(std::span<const unsigned char> in) noexcept;
/* Insert a single piece of data into the set. */ /* Insert a single piece of data into the set. */
MuHash3072& Insert(Span<const unsigned char> in) noexcept; MuHash3072& Insert(std::span<const unsigned char> in) noexcept;
/* Remove a single piece of data from the set. */ /* Remove a single piece of data from the set. */
MuHash3072& Remove(Span<const unsigned char> in) noexcept; MuHash3072& Remove(std::span<const unsigned char> in) noexcept;
/* Multiply (resulting in a hash for the union of the sets) */ /* Multiply (resulting in a hash for the union of the sets) */
MuHash3072& operator*=(const MuHash3072& mul) noexcept; MuHash3072& operator*=(const MuHash3072& mul) noexcept;

View file

@ -1,4 +1,4 @@
// Copyright (c) 2019-2022 The Bitcoin Core developers // Copyright (c) 2019-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -33,7 +33,7 @@ void poly1305_finish(poly1305_context *st, unsigned char mac[16]) noexcept;
} // namespace poly1305_donna } // namespace poly1305_donna
/** C++ wrapper with std::byte Span interface around poly1305_donna code. */ /** C++ wrapper with std::byte span interface around poly1305_donna code. */
class Poly1305 class Poly1305
{ {
poly1305_donna::poly1305_context m_ctx; poly1305_donna::poly1305_context m_ctx;
@ -46,21 +46,21 @@ public:
static constexpr unsigned KEYLEN{32}; static constexpr unsigned KEYLEN{32};
/** Construct a Poly1305 object with a given 32-byte key. */ /** Construct a Poly1305 object with a given 32-byte key. */
Poly1305(Span<const std::byte> key) noexcept Poly1305(std::span<const std::byte> key) noexcept
{ {
assert(key.size() == KEYLEN); assert(key.size() == KEYLEN);
poly1305_donna::poly1305_init(&m_ctx, UCharCast(key.data())); poly1305_donna::poly1305_init(&m_ctx, UCharCast(key.data()));
} }
/** Process message bytes. */ /** Process message bytes. */
Poly1305& Update(Span<const std::byte> msg) noexcept Poly1305& Update(std::span<const std::byte> msg) noexcept
{ {
poly1305_donna::poly1305_update(&m_ctx, UCharCast(msg.data()), msg.size()); poly1305_donna::poly1305_update(&m_ctx, UCharCast(msg.data()), msg.size());
return *this; return *this;
} }
/** Write authentication tag to 16-byte out. */ /** Write authentication tag to 16-byte out. */
void Finalize(Span<std::byte> out) noexcept void Finalize(std::span<std::byte> out) noexcept
{ {
assert(out.size() == TAGLEN); assert(out.size() == TAGLEN);
poly1305_donna::poly1305_finish(&m_ctx, UCharCast(out.data())); poly1305_donna::poly1305_finish(&m_ctx, UCharCast(out.data()));

View file

@ -1,4 +1,4 @@
// Copyright (c) 2020 The Bitcoin Core developers // Copyright (c) 2020-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -103,7 +103,7 @@ void KeccakF(uint64_t (&st)[25])
} }
} }
SHA3_256& SHA3_256::Write(Span<const unsigned char> data) SHA3_256& SHA3_256::Write(std::span<const unsigned char> data)
{ {
if (m_bufsize && data.size() >= sizeof(m_buffer) - m_bufsize) { if (m_bufsize && data.size() >= sizeof(m_buffer) - m_bufsize) {
// Fill the buffer and process it. // Fill the buffer and process it.
@ -133,7 +133,7 @@ SHA3_256& SHA3_256::Write(Span<const unsigned char> data)
return *this; return *this;
} }
SHA3_256& SHA3_256::Finalize(Span<unsigned char> output) SHA3_256& SHA3_256::Finalize(std::span<unsigned char> output)
{ {
assert(output.size() == OUTPUT_SIZE); assert(output.size() == OUTPUT_SIZE);
std::fill(m_buffer + m_bufsize, m_buffer + sizeof(m_buffer), 0); std::fill(m_buffer + m_bufsize, m_buffer + sizeof(m_buffer), 0);

View file

@ -1,4 +1,4 @@
// Copyright (c) 2020-2022 The Bitcoin Core developers // Copyright (c) 2020-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -33,8 +33,8 @@ public:
static constexpr size_t OUTPUT_SIZE = 32; static constexpr size_t OUTPUT_SIZE = 32;
SHA3_256() = default; SHA3_256() = default;
SHA3_256& Write(Span<const unsigned char> data); SHA3_256& Write(std::span<const unsigned char> data);
SHA3_256& Finalize(Span<unsigned char> output); SHA3_256& Finalize(std::span<unsigned char> output);
SHA3_256& Reset(); SHA3_256& Reset();
}; };

View file

@ -1,4 +1,4 @@
// Copyright (c) 2016-2020 The Bitcoin Core developers // Copyright (c) 2016-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -45,7 +45,7 @@ CSipHasher& CSipHasher::Write(uint64_t data)
return *this; return *this;
} }
CSipHasher& CSipHasher::Write(Span<const unsigned char> data) CSipHasher& CSipHasher::Write(std::span<const unsigned char> data)
{ {
uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3]; uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
uint64_t t = tmp; uint64_t t = tmp;

View file

@ -1,4 +1,4 @@
// Copyright (c) 2016-2020 The Bitcoin Core developers // Copyright (c) 2016-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -27,7 +27,7 @@ public:
*/ */
CSipHasher& Write(uint64_t data); CSipHasher& Write(uint64_t data);
/** Hash arbitrary bytes. */ /** Hash arbitrary bytes. */
CSipHasher& Write(Span<const unsigned char> data); CSipHasher& Write(std::span<const unsigned char> data);
/** Compute the 64-bit SipHash-2-4 of the data written so far. The object remains untouched. */ /** Compute the 64-bit SipHash-2-4 of the data written so far. The object remains untouched. */
uint64_t Finalize() const; uint64_t Finalize() const;
}; };

View file

@ -1,4 +1,4 @@
// Copyright (c) 2012-2022 The Bitcoin Core developers // Copyright (c) 2012-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -168,7 +168,7 @@ void CDBBatch::Clear()
size_estimate = 0; size_estimate = 0;
} }
void CDBBatch::WriteImpl(Span<const std::byte> key, DataStream& ssValue) void CDBBatch::WriteImpl(std::span<const std::byte> key, DataStream& ssValue)
{ {
leveldb::Slice slKey(CharCast(key.data()), key.size()); leveldb::Slice slKey(CharCast(key.data()), key.size());
ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent)); ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent));
@ -184,7 +184,7 @@ void CDBBatch::WriteImpl(Span<const std::byte> key, DataStream& ssValue)
size_estimate += 3 + (slKey.size() > 127) + slKey.size() + (slValue.size() > 127) + slValue.size(); size_estimate += 3 + (slKey.size() > 127) + slKey.size() + (slValue.size() > 127) + slValue.size();
} }
void CDBBatch::EraseImpl(Span<const std::byte> key) void CDBBatch::EraseImpl(std::span<const std::byte> key)
{ {
leveldb::Slice slKey(CharCast(key.data()), key.size()); leveldb::Slice slKey(CharCast(key.data()), key.size());
m_impl_batch->batch.Delete(slKey); m_impl_batch->batch.Delete(slKey);
@ -336,7 +336,7 @@ std::vector<unsigned char> CDBWrapper::CreateObfuscateKey() const
return ret; return ret;
} }
std::optional<std::string> CDBWrapper::ReadImpl(Span<const std::byte> key) const std::optional<std::string> CDBWrapper::ReadImpl(std::span<const std::byte> key) const
{ {
leveldb::Slice slKey(CharCast(key.data()), key.size()); leveldb::Slice slKey(CharCast(key.data()), key.size());
std::string strValue; std::string strValue;
@ -350,7 +350,7 @@ std::optional<std::string> CDBWrapper::ReadImpl(Span<const std::byte> key) const
return strValue; return strValue;
} }
bool CDBWrapper::ExistsImpl(Span<const std::byte> key) const bool CDBWrapper::ExistsImpl(std::span<const std::byte> key) const
{ {
leveldb::Slice slKey(CharCast(key.data()), key.size()); leveldb::Slice slKey(CharCast(key.data()), key.size());
@ -365,7 +365,7 @@ bool CDBWrapper::ExistsImpl(Span<const std::byte> key) const
return true; return true;
} }
size_t CDBWrapper::EstimateSizeImpl(Span<const std::byte> key1, Span<const std::byte> key2) const size_t CDBWrapper::EstimateSizeImpl(std::span<const std::byte> key1, std::span<const std::byte> key2) const
{ {
leveldb::Slice slKey1(CharCast(key1.data()), key1.size()); leveldb::Slice slKey1(CharCast(key1.data()), key1.size());
leveldb::Slice slKey2(CharCast(key2.data()), key2.size()); leveldb::Slice slKey2(CharCast(key2.data()), key2.size());
@ -396,18 +396,18 @@ CDBIterator* CDBWrapper::NewIterator()
return new CDBIterator{*this, std::make_unique<CDBIterator::IteratorImpl>(DBContext().pdb->NewIterator(DBContext().iteroptions))}; return new CDBIterator{*this, std::make_unique<CDBIterator::IteratorImpl>(DBContext().pdb->NewIterator(DBContext().iteroptions))};
} }
void CDBIterator::SeekImpl(Span<const std::byte> key) void CDBIterator::SeekImpl(std::span<const std::byte> key)
{ {
leveldb::Slice slKey(CharCast(key.data()), key.size()); leveldb::Slice slKey(CharCast(key.data()), key.size());
m_impl_iter->iter->Seek(slKey); m_impl_iter->iter->Seek(slKey);
} }
Span<const std::byte> CDBIterator::GetKeyImpl() const std::span<const std::byte> CDBIterator::GetKeyImpl() const
{ {
return MakeByteSpan(m_impl_iter->iter->key()); return MakeByteSpan(m_impl_iter->iter->key());
} }
Span<const std::byte> CDBIterator::GetValueImpl() const std::span<const std::byte> CDBIterator::GetValueImpl() const
{ {
return MakeByteSpan(m_impl_iter->iter->value()); return MakeByteSpan(m_impl_iter->iter->value());
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) 2012-2022 The Bitcoin Core developers // Copyright (c) 2012-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -85,8 +85,8 @@ private:
size_t size_estimate{0}; size_t size_estimate{0};
void WriteImpl(Span<const std::byte> key, DataStream& ssValue); void WriteImpl(std::span<const std::byte> key, DataStream& ssValue);
void EraseImpl(Span<const std::byte> key); void EraseImpl(std::span<const std::byte> key);
public: public:
/** /**
@ -129,9 +129,9 @@ private:
const CDBWrapper &parent; const CDBWrapper &parent;
const std::unique_ptr<IteratorImpl> m_impl_iter; const std::unique_ptr<IteratorImpl> m_impl_iter;
void SeekImpl(Span<const std::byte> key); void SeekImpl(std::span<const std::byte> key);
Span<const std::byte> GetKeyImpl() const; std::span<const std::byte> GetKeyImpl() const;
Span<const std::byte> GetValueImpl() const; std::span<const std::byte> GetValueImpl() const;
public: public:
@ -206,9 +206,9 @@ private:
//! whether or not the database resides in memory //! whether or not the database resides in memory
bool m_is_memory; bool m_is_memory;
std::optional<std::string> ReadImpl(Span<const std::byte> key) const; std::optional<std::string> ReadImpl(std::span<const std::byte> key) const;
bool ExistsImpl(Span<const std::byte> key) const; bool ExistsImpl(std::span<const std::byte> key) const;
size_t EstimateSizeImpl(Span<const std::byte> key1, Span<const std::byte> key2) const; size_t EstimateSizeImpl(std::span<const std::byte> key1, std::span<const std::byte> key2) const;
auto& DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); } auto& DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); }
public: public:

View file

@ -1,4 +1,4 @@
// Copyright (c) 2013-2022 The Bitcoin Core developers // Copyright (c) 2013-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -10,7 +10,7 @@
#include <bit> #include <bit>
#include <string> #include <string>
unsigned int MurmurHash3(unsigned int nHashSeed, Span<const unsigned char> vDataToHash) unsigned int MurmurHash3(unsigned int nHashSeed, std::span<const unsigned char> vDataToHash)
{ {
// The following is MurmurHash3 (x86_32), see https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp // The following is MurmurHash3 (x86_32), see https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp
uint32_t h1 = nHashSeed; uint32_t h1 = nHashSeed;

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -27,14 +27,14 @@ private:
public: public:
static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE; static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE;
void Finalize(Span<unsigned char> output) { void Finalize(std::span<unsigned char> output) {
assert(output.size() == OUTPUT_SIZE); assert(output.size() == OUTPUT_SIZE);
unsigned char buf[CSHA256::OUTPUT_SIZE]; unsigned char buf[CSHA256::OUTPUT_SIZE];
sha.Finalize(buf); sha.Finalize(buf);
sha.Reset().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data()); sha.Reset().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data());
} }
CHash256& Write(Span<const unsigned char> input) { CHash256& Write(std::span<const unsigned char> input) {
sha.Write(input.data(), input.size()); sha.Write(input.data(), input.size());
return *this; return *this;
} }
@ -52,14 +52,14 @@ private:
public: public:
static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE; static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE;
void Finalize(Span<unsigned char> output) { void Finalize(std::span<unsigned char> output) {
assert(output.size() == OUTPUT_SIZE); assert(output.size() == OUTPUT_SIZE);
unsigned char buf[CSHA256::OUTPUT_SIZE]; unsigned char buf[CSHA256::OUTPUT_SIZE];
sha.Finalize(buf); sha.Finalize(buf);
CRIPEMD160().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data()); CRIPEMD160().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data());
} }
CHash160& Write(Span<const unsigned char> input) { CHash160& Write(std::span<const unsigned char> input) {
sha.Write(input.data(), input.size()); sha.Write(input.data(), input.size());
return *this; return *this;
} }
@ -103,7 +103,7 @@ private:
CSHA256 ctx; CSHA256 ctx;
public: public:
void write(Span<const std::byte> src) void write(std::span<const std::byte> src)
{ {
ctx.Write(UCharCast(src.data()), src.size()); ctx.Write(UCharCast(src.data()), src.size());
} }
@ -155,7 +155,7 @@ private:
public: public:
explicit HashVerifier(Source& source LIFETIMEBOUND) : m_source{source} {} explicit HashVerifier(Source& source LIFETIMEBOUND) : m_source{source} {}
void read(Span<std::byte> dst) void read(std::span<std::byte> dst)
{ {
m_source.read(dst); m_source.read(dst);
this->write(dst); this->write(dst);
@ -189,7 +189,7 @@ private:
public: public:
explicit HashedSourceWriter(Source& source LIFETIMEBOUND) : HashWriter{}, m_source{source} {} explicit HashedSourceWriter(Source& source LIFETIMEBOUND) : HashWriter{}, m_source{source} {}
void write(Span<const std::byte> src) void write(std::span<const std::byte> src)
{ {
m_source.write(src); m_source.write(src);
HashWriter::write(src); HashWriter::write(src);
@ -206,7 +206,7 @@ public:
/** Single-SHA256 a 32-byte input (represented as uint256). */ /** Single-SHA256 a 32-byte input (represented as uint256). */
[[nodiscard]] uint256 SHA256Uint256(const uint256& input); [[nodiscard]] uint256 SHA256Uint256(const uint256& input);
unsigned int MurmurHash3(unsigned int nHashSeed, Span<const unsigned char> vDataToHash); unsigned int MurmurHash3(unsigned int nHashSeed, std::span<const unsigned char> vDataToHash);
void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]); void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]);
@ -219,7 +219,7 @@ void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char he
HashWriter TaggedHash(const std::string& tag); HashWriter TaggedHash(const std::string& tag);
/** Compute the 160-bit RIPEMD-160 hash of an array. */ /** Compute the 160-bit RIPEMD-160 hash of an array. */
inline uint160 RIPEMD160(Span<const unsigned char> data) inline uint160 RIPEMD160(std::span<const unsigned char> data)
{ {
uint160 result; uint160 result;
CRIPEMD160().Write(data.data(), data.size()).Finalize(result.begin()); CRIPEMD160().Write(data.data(), data.size()).Finalize(result.begin());

View file

@ -1,4 +1,4 @@
// Copyright (c) 2020-2022 The Bitcoin Core developers // Copyright (c) 2020-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -23,6 +23,7 @@
#include <chrono> #include <chrono>
#include <memory> #include <memory>
#include <ranges>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
@ -309,7 +310,7 @@ Session::Reply Session::SendRequestAndGetReply(const Sock& sock,
reply.full = sock.RecvUntilTerminator('\n', recv_timeout, *m_interrupt, MAX_MSG_SIZE); reply.full = sock.RecvUntilTerminator('\n', recv_timeout, *m_interrupt, MAX_MSG_SIZE);
for (const auto& kv : Split(reply.full, ' ')) { for (const auto& kv : Split(reply.full, ' ')) {
const auto& pos = std::find(kv.begin(), kv.end(), '='); const auto pos{std::ranges::find(kv, '=')};
if (pos != kv.end()) { if (pos != kv.end()) {
reply.keys.emplace(std::string{kv.begin(), pos}, std::string{pos + 1, kv.end()}); reply.keys.emplace(std::string{kv.begin(), pos}, std::string{pos + 1, kv.end()});
} else { } else {

View file

@ -1,4 +1,4 @@
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Copyright (c) 2017 The Zcash developers // Copyright (c) 2017 The Zcash developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -269,7 +269,7 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)
return true; return true;
} }
bool CKey::SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const bool CKey::SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const
{ {
KeyPair kp = ComputeKeyPair(merkle_root); KeyPair kp = ComputeKeyPair(merkle_root);
return kp.SignSchnorr(hash, sig, aux); return kp.SignSchnorr(hash, sig, aux);
@ -308,7 +308,7 @@ bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const
return ret; return ret;
} }
EllSwiftPubKey CKey::EllSwiftCreate(Span<const std::byte> ent32) const EllSwiftPubKey CKey::EllSwiftCreate(std::span<const std::byte> ent32) const
{ {
assert(keydata); assert(keydata);
assert(ent32.size() == 32); assert(ent32.size() == 32);
@ -365,7 +365,7 @@ bool CExtKey::Derive(CExtKey &out, unsigned int _nChild) const {
return key.Derive(out.key, out.chaincode, _nChild, chaincode); return key.Derive(out.key, out.chaincode, _nChild, chaincode);
} }
void CExtKey::SetSeed(Span<const std::byte> seed) void CExtKey::SetSeed(std::span<const std::byte> seed)
{ {
static const unsigned char hashkey[] = {'B','i','t','c','o','i','n',' ','s','e','e','d'}; static const unsigned char hashkey[] = {'B','i','t','c','o','i','n',' ','s','e','e','d'};
std::vector<unsigned char, secure_allocator<unsigned char>> vout(64); std::vector<unsigned char, secure_allocator<unsigned char>> vout(64);
@ -423,7 +423,7 @@ KeyPair::KeyPair(const CKey& key, const uint256* merkle_root)
if (!success) ClearKeyPairData(); if (!success) ClearKeyPairData();
} }
bool KeyPair::SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256& aux) const bool KeyPair::SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256& aux) const
{ {
assert(sig.size() == 64); assert(sig.size() == 64);
if (!IsValid()) return false; if (!IsValid()) return false;

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Copyright (c) 2017 The Zcash developers // Copyright (c) 2017 The Zcash developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -170,7 +170,7 @@ public:
* (this is used for key path spending, with specific * (this is used for key path spending, with specific
* Merkle root of the script tree). * Merkle root of the script tree).
*/ */
bool SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const; bool SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const;
//! Derive BIP32 child key. //! Derive BIP32 child key.
[[nodiscard]] bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const; [[nodiscard]] bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
@ -192,7 +192,7 @@ public:
* resulting encoding will be indistinguishable from uniform to any adversary who does not * resulting encoding will be indistinguishable from uniform to any adversary who does not
* know the private key (because the private key itself is always used as entropy as well). * know the private key (because the private key itself is always used as entropy as well).
*/ */
EllSwiftPubKey EllSwiftCreate(Span<const std::byte> entropy) const; EllSwiftPubKey EllSwiftCreate(std::span<const std::byte> entropy) const;
/** Compute a BIP324-style ECDH shared secret. /** Compute a BIP324-style ECDH shared secret.
* *
@ -250,7 +250,7 @@ struct CExtKey {
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]); void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
[[nodiscard]] bool Derive(CExtKey& out, unsigned int nChild) const; [[nodiscard]] bool Derive(CExtKey& out, unsigned int nChild) const;
CExtPubKey Neuter() const; CExtPubKey Neuter() const;
void SetSeed(Span<const std::byte> seed); void SetSeed(std::span<const std::byte> seed);
}; };
/** KeyPair /** KeyPair
@ -286,7 +286,7 @@ public:
KeyPair(const KeyPair& other) { *this = other; } KeyPair(const KeyPair& other) { *this = other; }
friend KeyPair CKey::ComputeKeyPair(const uint256* merkle_root) const; friend KeyPair CKey::ComputeKeyPair(const uint256* merkle_root) const;
[[nodiscard]] bool SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256& aux) const; [[nodiscard]] bool SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256& aux) const;
//! Check whether this keypair is valid. //! Check whether this keypair is valid.
bool IsValid() const { return !!m_keypair; } bool IsValid() const { return !!m_keypair; }

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -663,7 +663,7 @@ void CNode::CopyStats(CNodeStats& stats)
} }
#undef X #undef X
bool CNode::ReceiveMsgBytes(Span<const uint8_t> msg_bytes, bool& complete) bool CNode::ReceiveMsgBytes(std::span<const uint8_t> msg_bytes, bool& complete)
{ {
complete = false; complete = false;
const auto time = GetTime<std::chrono::microseconds>(); const auto time = GetTime<std::chrono::microseconds>();
@ -731,7 +731,7 @@ Transport::Info V1Transport::GetInfo() const noexcept
return {.transport_type = TransportProtocolType::V1, .session_id = {}}; return {.transport_type = TransportProtocolType::V1, .session_id = {}};
} }
int V1Transport::readHeader(Span<const uint8_t> msg_bytes) int V1Transport::readHeader(std::span<const uint8_t> msg_bytes)
{ {
AssertLockHeld(m_recv_mutex); AssertLockHeld(m_recv_mutex);
// copy data to temporary parsing buffer // copy data to temporary parsing buffer
@ -772,7 +772,7 @@ int V1Transport::readHeader(Span<const uint8_t> msg_bytes)
return nCopy; return nCopy;
} }
int V1Transport::readData(Span<const uint8_t> msg_bytes) int V1Transport::readData(std::span<const uint8_t> msg_bytes)
{ {
AssertLockHeld(m_recv_mutex); AssertLockHeld(m_recv_mutex);
unsigned int nRemaining = hdr.nMessageSize - nDataPos; unsigned int nRemaining = hdr.nMessageSize - nDataPos;
@ -823,7 +823,7 @@ CNetMessage V1Transport::GetReceivedMessage(const std::chrono::microseconds time
if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0) { if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0) {
LogDebug(BCLog::NET, "Header error: Wrong checksum (%s, %u bytes), expected %s was %s, peer=%d\n", LogDebug(BCLog::NET, "Header error: Wrong checksum (%s, %u bytes), expected %s was %s, peer=%d\n",
SanitizeString(msg.m_type), msg.m_message_size, SanitizeString(msg.m_type), msg.m_message_size,
HexStr(Span{hash}.first(CMessageHeader::CHECKSUM_SIZE)), HexStr(std::span{hash}.first(CMessageHeader::CHECKSUM_SIZE)),
HexStr(hdr.pchChecksum), HexStr(hdr.pchChecksum),
m_node_id); m_node_id);
reject_message = true; reject_message = true;
@ -868,14 +868,14 @@ Transport::BytesToSend V1Transport::GetBytesToSend(bool have_next_message) const
AssertLockNotHeld(m_send_mutex); AssertLockNotHeld(m_send_mutex);
LOCK(m_send_mutex); LOCK(m_send_mutex);
if (m_sending_header) { if (m_sending_header) {
return {Span{m_header_to_send}.subspan(m_bytes_sent), return {std::span{m_header_to_send}.subspan(m_bytes_sent),
// We have more to send after the header if the message has payload, or if there // We have more to send after the header if the message has payload, or if there
// is a next message after that. // is a next message after that.
have_next_message || !m_message_to_send.data.empty(), have_next_message || !m_message_to_send.data.empty(),
m_message_to_send.m_type m_message_to_send.m_type
}; };
} else { } else {
return {Span{m_message_to_send.data}.subspan(m_bytes_sent), return {std::span{m_message_to_send.data}.subspan(m_bytes_sent),
// We only have more to send after this message's payload if there is another // We only have more to send after this message's payload if there is another
// message. // message.
have_next_message, have_next_message,
@ -997,7 +997,7 @@ void V2Transport::StartSendingHandshake() noexcept
// We cannot wipe m_send_garbage as it will still be used as AAD later in the handshake. // We cannot wipe m_send_garbage as it will still be used as AAD later in the handshake.
} }
V2Transport::V2Transport(NodeId nodeid, bool initiating, const CKey& key, Span<const std::byte> ent32, std::vector<uint8_t> garbage) noexcept V2Transport::V2Transport(NodeId nodeid, bool initiating, const CKey& key, std::span<const std::byte> ent32, std::vector<uint8_t> garbage) noexcept
: m_cipher{key, ent32}, m_initiating{initiating}, m_nodeid{nodeid}, : m_cipher{key, ent32}, m_initiating{initiating}, m_nodeid{nodeid},
m_v1_fallback{nodeid}, m_v1_fallback{nodeid},
m_recv_state{initiating ? RecvState::KEY : RecvState::KEY_MAYBE_V1}, m_recv_state{initiating ? RecvState::KEY : RecvState::KEY_MAYBE_V1},
@ -1098,7 +1098,7 @@ void V2Transport::ProcessReceivedMaybeV1Bytes() noexcept
} else if (m_recv_buffer.size() == v1_prefix.size()) { } else if (m_recv_buffer.size() == v1_prefix.size()) {
// Full match with the v1 prefix, so fall back to v1 behavior. // Full match with the v1 prefix, so fall back to v1 behavior.
LOCK(m_send_mutex); LOCK(m_send_mutex);
Span<const uint8_t> feedback{m_recv_buffer}; std::span<const uint8_t> feedback{m_recv_buffer};
// Feed already received bytes to v1 transport. It should always accept these, because it's // Feed already received bytes to v1 transport. It should always accept these, because it's
// less than the size of a v1 header, and these are the first bytes fed to m_v1_fallback. // less than the size of a v1 header, and these are the first bytes fed to m_v1_fallback.
bool ret = m_v1_fallback.ReceivedBytes(feedback); bool ret = m_v1_fallback.ReceivedBytes(feedback);
@ -1132,7 +1132,7 @@ bool V2Transport::ProcessReceivedKeyBytes() noexcept
if (!m_initiating && m_recv_buffer.size() >= OFFSET + MATCH.size()) { if (!m_initiating && m_recv_buffer.size() >= OFFSET + MATCH.size()) {
if (std::equal(MATCH.begin(), MATCH.end(), m_recv_buffer.begin() + OFFSET)) { if (std::equal(MATCH.begin(), MATCH.end(), m_recv_buffer.begin() + OFFSET)) {
LogDebug(BCLog::NET, "V2 transport error: V1 peer with wrong MessageStart %s\n", LogDebug(BCLog::NET, "V2 transport error: V1 peer with wrong MessageStart %s\n",
HexStr(Span(m_recv_buffer).first(OFFSET))); HexStr(std::span(m_recv_buffer).first(OFFSET)));
return false; return false;
} }
} }
@ -1319,7 +1319,7 @@ size_t V2Transport::GetMaxBytesToProcess() noexcept
return 0; return 0;
} }
bool V2Transport::ReceivedBytes(Span<const uint8_t>& msg_bytes) noexcept bool V2Transport::ReceivedBytes(std::span<const uint8_t>& msg_bytes) noexcept
{ {
AssertLockNotHeld(m_recv_mutex); AssertLockNotHeld(m_recv_mutex);
/** How many bytes to allocate in the receive buffer at most above what is received so far. */ /** How many bytes to allocate in the receive buffer at most above what is received so far. */
@ -1409,7 +1409,7 @@ bool V2Transport::ReceivedBytes(Span<const uint8_t>& msg_bytes) noexcept
return true; return true;
} }
std::optional<std::string> V2Transport::GetMessageType(Span<const uint8_t>& contents) noexcept std::optional<std::string> V2Transport::GetMessageType(std::span<const uint8_t>& contents) noexcept
{ {
if (contents.size() == 0) return std::nullopt; // Empty contents if (contents.size() == 0) return std::nullopt; // Empty contents
uint8_t first_byte = contents[0]; uint8_t first_byte = contents[0];
@ -1456,7 +1456,7 @@ CNetMessage V2Transport::GetReceivedMessage(std::chrono::microseconds time, bool
if (m_recv_state == RecvState::V1) return m_v1_fallback.GetReceivedMessage(time, reject_message); if (m_recv_state == RecvState::V1) return m_v1_fallback.GetReceivedMessage(time, reject_message);
Assume(m_recv_state == RecvState::APP_READY); Assume(m_recv_state == RecvState::APP_READY);
Span<const uint8_t> contents{m_recv_decode_buffer}; std::span<const uint8_t> contents{m_recv_decode_buffer};
auto msg_type = GetMessageType(contents); auto msg_type = GetMessageType(contents);
CNetMessage msg{DataStream{}}; CNetMessage msg{DataStream{}};
// Note that BIP324Cipher::EXPANSION also includes the length descriptor size. // Note that BIP324Cipher::EXPANSION also includes the length descriptor size.
@ -1519,7 +1519,7 @@ Transport::BytesToSend V2Transport::GetBytesToSend(bool have_next_message) const
if (m_send_state == SendState::MAYBE_V1) Assume(m_send_buffer.empty()); if (m_send_state == SendState::MAYBE_V1) Assume(m_send_buffer.empty());
Assume(m_send_pos <= m_send_buffer.size()); Assume(m_send_pos <= m_send_buffer.size());
return { return {
Span{m_send_buffer}.subspan(m_send_pos), std::span{m_send_buffer}.subspan(m_send_pos),
// We only have more to send after the current m_send_buffer if there is a (next) // We only have more to send after the current m_send_buffer if there is a (next)
// message to be sent, and we're capable of sending packets. */ // message to be sent, and we're capable of sending packets. */
have_next_message && m_send_state == SendState::READY, have_next_message && m_send_state == SendState::READY,
@ -2050,7 +2050,7 @@ bool CConnman::InactivityCheck(const CNode& node) const
return false; return false;
} }
Sock::EventsPerSock CConnman::GenerateWaitSockets(Span<CNode* const> nodes) Sock::EventsPerSock CConnman::GenerateWaitSockets(std::span<CNode* const> nodes)
{ {
Sock::EventsPerSock events_per_sock; Sock::EventsPerSock events_per_sock;
@ -2511,7 +2511,7 @@ bool CConnman::MaybePickPreferredNetwork(std::optional<Network>& network)
return false; return false;
} }
void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, Span<const std::string> seed_nodes) void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, std::span<const std::string> seed_nodes)
{ {
AssertLockNotHeld(m_unused_i2p_sessions_mutex); AssertLockNotHeld(m_unused_i2p_sessions_mutex);
AssertLockNotHeld(m_reconnections_mutex); AssertLockNotHeld(m_reconnections_mutex);
@ -3982,7 +3982,7 @@ void CConnman::ASMapHealthCheck()
// Dump binary message to file, with timestamp. // Dump binary message to file, with timestamp.
static void CaptureMessageToFile(const CAddress& addr, static void CaptureMessageToFile(const CAddress& addr,
const std::string& msg_type, const std::string& msg_type,
Span<const unsigned char> data, std::span<const unsigned char> data,
bool is_incoming) bool is_incoming)
{ {
// Note: This function captures the message at the time of processing, // Note: This function captures the message at the time of processing,
@ -4002,7 +4002,7 @@ static void CaptureMessageToFile(const CAddress& addr,
AutoFile f{fsbridge::fopen(path, "ab")}; AutoFile f{fsbridge::fopen(path, "ab")};
ser_writedata64(f, now.count()); ser_writedata64(f, now.count());
f << Span{msg_type}; f << std::span{msg_type};
for (auto i = msg_type.length(); i < CMessageHeader::MESSAGE_TYPE_SIZE; ++i) { for (auto i = msg_type.length(); i < CMessageHeader::MESSAGE_TYPE_SIZE; ++i) {
f << uint8_t{'\0'}; f << uint8_t{'\0'};
} }
@ -4013,6 +4013,6 @@ static void CaptureMessageToFile(const CAddress& addr,
std::function<void(const CAddress& addr, std::function<void(const CAddress& addr,
const std::string& msg_type, const std::string& msg_type,
Span<const unsigned char> data, std::span<const unsigned char> data,
bool is_incoming)> bool is_incoming)>
CaptureMessage = CaptureMessageToFile; CaptureMessage = CaptureMessageToFile;

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -276,7 +276,7 @@ public:
* *
* Consumed bytes are chopped off the front of msg_bytes. * Consumed bytes are chopped off the front of msg_bytes.
*/ */
virtual bool ReceivedBytes(Span<const uint8_t>& msg_bytes) = 0; virtual bool ReceivedBytes(std::span<const uint8_t>& msg_bytes) = 0;
/** Retrieve a completed message from transport. /** Retrieve a completed message from transport.
* *
@ -298,14 +298,14 @@ public:
virtual bool SetMessageToSend(CSerializedNetMsg& msg) noexcept = 0; virtual bool SetMessageToSend(CSerializedNetMsg& msg) noexcept = 0;
/** Return type for GetBytesToSend, consisting of: /** Return type for GetBytesToSend, consisting of:
* - Span<const uint8_t> to_send: span of bytes to be sent over the wire (possibly empty). * - std::span<const uint8_t> to_send: span of bytes to be sent over the wire (possibly empty).
* - bool more: whether there will be more bytes to be sent after the ones in to_send are * - bool more: whether there will be more bytes to be sent after the ones in to_send are
* all sent (as signaled by MarkBytesSent()). * all sent (as signaled by MarkBytesSent()).
* - const std::string& m_type: message type on behalf of which this is being sent * - const std::string& m_type: message type on behalf of which this is being sent
* ("" for bytes that are not on behalf of any message). * ("" for bytes that are not on behalf of any message).
*/ */
using BytesToSend = std::tuple< using BytesToSend = std::tuple<
Span<const uint8_t> /*to_send*/, std::span<const uint8_t> /*to_send*/,
bool /*more*/, bool /*more*/,
const std::string& /*m_type*/ const std::string& /*m_type*/
>; >;
@ -380,8 +380,8 @@ private:
unsigned int nDataPos GUARDED_BY(m_recv_mutex); unsigned int nDataPos GUARDED_BY(m_recv_mutex);
const uint256& GetMessageHash() const EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex); const uint256& GetMessageHash() const EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex);
int readHeader(Span<const uint8_t> msg_bytes) EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex); int readHeader(std::span<const uint8_t> msg_bytes) EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex);
int readData(Span<const uint8_t> msg_bytes) EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex); int readData(std::span<const uint8_t> msg_bytes) EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex);
void Reset() EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex) { void Reset() EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex) {
AssertLockHeld(m_recv_mutex); AssertLockHeld(m_recv_mutex);
@ -424,7 +424,7 @@ public:
Info GetInfo() const noexcept override; Info GetInfo() const noexcept override;
bool ReceivedBytes(Span<const uint8_t>& msg_bytes) override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex) bool ReceivedBytes(std::span<const uint8_t>& msg_bytes) override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
{ {
AssertLockNotHeld(m_recv_mutex); AssertLockNotHeld(m_recv_mutex);
LOCK(m_recv_mutex); LOCK(m_recv_mutex);
@ -616,7 +616,7 @@ private:
/** Change the send state. */ /** Change the send state. */
void SetSendState(SendState send_state) noexcept EXCLUSIVE_LOCKS_REQUIRED(m_send_mutex); void SetSendState(SendState send_state) noexcept EXCLUSIVE_LOCKS_REQUIRED(m_send_mutex);
/** Given a packet's contents, find the message type (if valid), and strip it from contents. */ /** Given a packet's contents, find the message type (if valid), and strip it from contents. */
static std::optional<std::string> GetMessageType(Span<const uint8_t>& contents) noexcept; static std::optional<std::string> GetMessageType(std::span<const uint8_t>& contents) noexcept;
/** Determine how many received bytes can be processed in one go (not allowed in V1 state). */ /** Determine how many received bytes can be processed in one go (not allowed in V1 state). */
size_t GetMaxBytesToProcess() noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex); size_t GetMaxBytesToProcess() noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex);
/** Put our public key + garbage in the send buffer. */ /** Put our public key + garbage in the send buffer. */
@ -641,11 +641,11 @@ public:
V2Transport(NodeId nodeid, bool initiating) noexcept; V2Transport(NodeId nodeid, bool initiating) noexcept;
/** Construct a V2 transport with specified keys and garbage (test use only). */ /** Construct a V2 transport with specified keys and garbage (test use only). */
V2Transport(NodeId nodeid, bool initiating, const CKey& key, Span<const std::byte> ent32, std::vector<uint8_t> garbage) noexcept; V2Transport(NodeId nodeid, bool initiating, const CKey& key, std::span<const std::byte> ent32, std::vector<uint8_t> garbage) noexcept;
// Receive side functions. // Receive side functions.
bool ReceivedMessageComplete() const noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex); bool ReceivedMessageComplete() const noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex);
bool ReceivedBytes(Span<const uint8_t>& msg_bytes) noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex, !m_send_mutex); bool ReceivedBytes(std::span<const uint8_t>& msg_bytes) noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex, !m_send_mutex);
CNetMessage GetReceivedMessage(std::chrono::microseconds time, bool& reject_message) noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex); CNetMessage GetReceivedMessage(std::chrono::microseconds time, bool& reject_message) noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex);
// Send side functions. // Send side functions.
@ -914,7 +914,7 @@ public:
* @return True if the peer should stay connected, * @return True if the peer should stay connected,
* False if the peer should be disconnected from. * False if the peer should be disconnected from.
*/ */
bool ReceiveMsgBytes(Span<const uint8_t> msg_bytes, bool& complete) EXCLUSIVE_LOCKS_REQUIRED(!cs_vRecv); bool ReceiveMsgBytes(std::span<const uint8_t> msg_bytes, bool& complete) EXCLUSIVE_LOCKS_REQUIRED(!cs_vRecv);
void SetCommonVersion(int greatest_common_version) void SetCommonVersion(int greatest_common_version)
{ {
@ -1297,7 +1297,7 @@ private:
void ThreadOpenAddedConnections() EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex, !m_unused_i2p_sessions_mutex, !m_reconnections_mutex); void ThreadOpenAddedConnections() EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex, !m_unused_i2p_sessions_mutex, !m_reconnections_mutex);
void AddAddrFetch(const std::string& strDest) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex); void AddAddrFetch(const std::string& strDest) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex);
void ProcessAddrFetch() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_unused_i2p_sessions_mutex); void ProcessAddrFetch() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_unused_i2p_sessions_mutex);
void ThreadOpenConnections(std::vector<std::string> connect, Span<const std::string> seed_nodes) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_added_nodes_mutex, !m_nodes_mutex, !m_unused_i2p_sessions_mutex, !m_reconnections_mutex); void ThreadOpenConnections(std::vector<std::string> connect, std::span<const std::string> seed_nodes) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_added_nodes_mutex, !m_nodes_mutex, !m_unused_i2p_sessions_mutex, !m_reconnections_mutex);
void ThreadMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc); void ThreadMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
void ThreadI2PAcceptIncoming(); void ThreadI2PAcceptIncoming();
void AcceptConnection(const ListenSocket& hListenSocket); void AcceptConnection(const ListenSocket& hListenSocket);
@ -1325,7 +1325,7 @@ private:
* @param[in] nodes Select from these nodes' sockets. * @param[in] nodes Select from these nodes' sockets.
* @return sockets to check for readiness * @return sockets to check for readiness
*/ */
Sock::EventsPerSock GenerateWaitSockets(Span<CNode* const> nodes); Sock::EventsPerSock GenerateWaitSockets(std::span<CNode* const> nodes);
/** /**
* Check connected and listening sockets for IO readiness and process them accordingly. * Check connected and listening sockets for IO readiness and process them accordingly.
@ -1679,7 +1679,7 @@ private:
/** Defaults to `CaptureMessageToFile()`, but can be overridden by unit tests. */ /** Defaults to `CaptureMessageToFile()`, but can be overridden by unit tests. */
extern std::function<void(const CAddress& addr, extern std::function<void(const CAddress& addr,
const std::string& msg_type, const std::string& msg_type,
Span<const unsigned char> data, std::span<const unsigned char> data,
bool is_incoming)> bool is_incoming)>
CaptureMessage; CaptureMessage;

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -2281,7 +2281,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
pfrom.fDisconnect = true; pfrom.fDisconnect = true;
return; return;
} }
MakeAndPushMessage(pfrom, NetMsgType::BLOCK, Span{block_data}); MakeAndPushMessage(pfrom, NetMsgType::BLOCK, std::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

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -134,7 +134,7 @@ void CNetAddr::SetIP(const CNetAddr& ipIn)
m_addr = ipIn.m_addr; m_addr = ipIn.m_addr;
} }
void CNetAddr::SetLegacyIPv6(Span<const uint8_t> ipv6) void CNetAddr::SetLegacyIPv6(std::span<const uint8_t> ipv6)
{ {
assert(ipv6.size() == ADDR_IPV6_SIZE); assert(ipv6.size() == ADDR_IPV6_SIZE);
@ -187,7 +187,7 @@ static constexpr size_t CHECKSUM_LEN = 2;
static const unsigned char VERSION[] = {3}; static const unsigned char VERSION[] = {3};
static constexpr size_t TOTAL_LEN = ADDR_TORV3_SIZE + CHECKSUM_LEN + sizeof(VERSION); static constexpr size_t TOTAL_LEN = ADDR_TORV3_SIZE + CHECKSUM_LEN + sizeof(VERSION);
static void Checksum(Span<const uint8_t> addr_pubkey, uint8_t (&checksum)[CHECKSUM_LEN]) static void Checksum(std::span<const uint8_t> addr_pubkey, uint8_t (&checksum)[CHECKSUM_LEN])
{ {
// TORv3 CHECKSUM = H(".onion checksum" | PUBKEY | VERSION)[:2] // TORv3 CHECKSUM = H(".onion checksum" | PUBKEY | VERSION)[:2]
static const unsigned char prefix[] = ".onion checksum"; static const unsigned char prefix[] = ".onion checksum";
@ -195,7 +195,7 @@ static void Checksum(Span<const uint8_t> addr_pubkey, uint8_t (&checksum)[CHECKS
SHA3_256 hasher; SHA3_256 hasher;
hasher.Write(Span{prefix}.first(prefix_len)); hasher.Write(std::span{prefix}.first(prefix_len));
hasher.Write(addr_pubkey); hasher.Write(addr_pubkey);
hasher.Write(VERSION); hasher.Write(VERSION);
@ -241,9 +241,9 @@ bool CNetAddr::SetTor(const std::string& addr)
} }
if (input->size() == torv3::TOTAL_LEN) { if (input->size() == torv3::TOTAL_LEN) {
Span<const uint8_t> input_pubkey{input->data(), ADDR_TORV3_SIZE}; std::span<const uint8_t> input_pubkey{input->data(), ADDR_TORV3_SIZE};
Span<const uint8_t> input_checksum{input->data() + ADDR_TORV3_SIZE, torv3::CHECKSUM_LEN}; std::span<const uint8_t> input_checksum{input->data() + ADDR_TORV3_SIZE, torv3::CHECKSUM_LEN};
Span<const uint8_t> input_version{input->data() + ADDR_TORV3_SIZE + torv3::CHECKSUM_LEN, sizeof(torv3::VERSION)}; std::span<const uint8_t> input_version{input->data() + ADDR_TORV3_SIZE + torv3::CHECKSUM_LEN, sizeof(torv3::VERSION)};
if (!std::ranges::equal(input_version, torv3::VERSION)) { if (!std::ranges::equal(input_version, torv3::VERSION)) {
return false; return false;
@ -508,14 +508,14 @@ enum Network CNetAddr::GetNetwork() const
return m_net; return m_net;
} }
static std::string IPv4ToString(Span<const uint8_t> a) static std::string IPv4ToString(std::span<const uint8_t> a)
{ {
return strprintf("%u.%u.%u.%u", a[0], a[1], a[2], a[3]); return strprintf("%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
} }
// Return an IPv6 address text representation with zero compression as described in RFC 5952 // Return an IPv6 address text representation with zero compression as described in RFC 5952
// ("A Recommendation for IPv6 Address Text Representation"). // ("A Recommendation for IPv6 Address Text Representation").
static std::string IPv6ToString(Span<const uint8_t> a, uint32_t scope_id) static std::string IPv6ToString(std::span<const uint8_t> a, uint32_t scope_id)
{ {
assert(a.size() == ADDR_IPV6_SIZE); assert(a.size() == ADDR_IPV6_SIZE);
const std::array groups{ const std::array groups{
@ -570,7 +570,7 @@ static std::string IPv6ToString(Span<const uint8_t> a, uint32_t scope_id)
return r; return r;
} }
std::string OnionToString(Span<const uint8_t> addr) std::string OnionToString(std::span<const uint8_t> addr)
{ {
uint8_t checksum[torv3::CHECKSUM_LEN]; uint8_t checksum[torv3::CHECKSUM_LEN];
torv3::Checksum(addr, checksum); torv3::Checksum(addr, checksum);
@ -664,13 +664,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(Span{m_addr}.last(ADDR_IPV4_SIZE).data()); return ReadBE32(std::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(Span{m_addr}.subspan(2, ADDR_IPV4_SIZE).data()); return ReadBE32(std::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(Span{m_addr}.last(ADDR_IPV4_SIZE).data()); return ~ReadBE32(std::span{m_addr}.last(ADDR_IPV4_SIZE).data());
} }
assert(false); assert(false);
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -103,7 +103,7 @@ static constexpr size_t ADDR_INTERNAL_SIZE = 10;
/// SAM 3.1 and earlier do not support specifying ports and force the port to 0. /// SAM 3.1 and earlier do not support specifying ports and force the port to 0.
static constexpr uint16_t I2P_SAM31_PORT{0}; static constexpr uint16_t I2P_SAM31_PORT{0};
std::string OnionToString(Span<const uint8_t> addr); std::string OnionToString(std::span<const uint8_t> addr);
/** /**
* Network address. * Network address.
@ -139,7 +139,7 @@ public:
* (e.g. IPv4) disguised as IPv6. This encoding is used in the legacy * (e.g. IPv4) disguised as IPv6. This encoding is used in the legacy
* `addr` encoding. * `addr` encoding.
*/ */
void SetLegacyIPv6(Span<const uint8_t> ipv6); void SetLegacyIPv6(std::span<const uint8_t> ipv6);
bool SetInternal(const std::string& name); bool SetInternal(const std::string& name);
@ -437,7 +437,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 >> Span{m_addr}; s >> std::span{m_addr};
if (m_net != NET_IPV6) { if (m_net != NET_IPV6) {
return; return;

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -281,7 +281,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)
Span stack{tx.vin[i].scriptWitness.stack}; std::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;

View file

@ -1,4 +1,4 @@
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -543,7 +543,7 @@ bool DecodeBase64PSBT(PartiallySignedTransaction& psbt, const std::string& base6
return DecodeRawPSBT(psbt, MakeByteSpan(*tx_data), error); return DecodeRawPSBT(psbt, MakeByteSpan(*tx_data), error);
} }
bool DecodeRawPSBT(PartiallySignedTransaction& psbt, Span<const std::byte> tx_data, std::string& error) bool DecodeRawPSBT(PartiallySignedTransaction& psbt, std::span<const std::byte> tx_data, std::string& error)
{ {
DataStream ss_data{tx_data}; DataStream ss_data{tx_data};
try { try {

View file

@ -1,4 +1,4 @@
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -188,7 +188,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, Span{keypath_pair.first}); SerializeToVector(s, type, std::span{keypath_pair.first});
SerializeHDKeypath(s, keypath_pair.second); SerializeHDKeypath(s, keypath_pair.second);
} }
} }
@ -242,7 +242,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 (const auto& sig_pair : partial_sigs) { for (const auto& sig_pair : partial_sigs) {
SerializeToVector(s, CompactSizeWriter(PSBT_IN_PARTIAL_SIG), Span{sig_pair.second.first}); SerializeToVector(s, CompactSizeWriter(PSBT_IN_PARTIAL_SIG), std::span{sig_pair.second.first});
s << sig_pair.second.second; s << sig_pair.second.second;
} }
@ -269,25 +269,25 @@ struct PSBTInput
// Write any ripemd160 preimage // Write any ripemd160 preimage
for (const auto& [hash, preimage] : ripemd160_preimages) { for (const auto& [hash, preimage] : ripemd160_preimages) {
SerializeToVector(s, CompactSizeWriter(PSBT_IN_RIPEMD160), Span{hash}); SerializeToVector(s, CompactSizeWriter(PSBT_IN_RIPEMD160), std::span{hash});
s << preimage; s << preimage;
} }
// Write any sha256 preimage // Write any sha256 preimage
for (const auto& [hash, preimage] : sha256_preimages) { for (const auto& [hash, preimage] : sha256_preimages) {
SerializeToVector(s, CompactSizeWriter(PSBT_IN_SHA256), Span{hash}); SerializeToVector(s, CompactSizeWriter(PSBT_IN_SHA256), std::span{hash});
s << preimage; s << preimage;
} }
// Write any hash160 preimage // Write any hash160 preimage
for (const auto& [hash, preimage] : hash160_preimages) { for (const auto& [hash, preimage] : hash160_preimages) {
SerializeToVector(s, CompactSizeWriter(PSBT_IN_HASH160), Span{hash}); SerializeToVector(s, CompactSizeWriter(PSBT_IN_HASH160), std::span{hash});
s << preimage; s << preimage;
} }
// Write any hash256 preimage // Write any hash256 preimage
for (const auto& [hash, preimage] : hash256_preimages) { for (const auto& [hash, preimage] : hash256_preimages) {
SerializeToVector(s, CompactSizeWriter(PSBT_IN_HASH256), Span{hash}); SerializeToVector(s, CompactSizeWriter(PSBT_IN_HASH256), std::span{hash});
s << preimage; s << preimage;
} }
@ -308,7 +308,7 @@ struct PSBTInput
for (const auto& [leaf, control_blocks] : m_tap_scripts) { for (const auto& [leaf, control_blocks] : m_tap_scripts) {
const auto& [script, leaf_ver] = leaf; const auto& [script, leaf_ver] = leaf;
for (const auto& control_block : control_blocks) { for (const auto& control_block : control_blocks) {
SerializeToVector(s, PSBT_IN_TAP_LEAF_SCRIPT, Span{control_block}); SerializeToVector(s, PSBT_IN_TAP_LEAF_SCRIPT, std::span{control_block});
std::vector<unsigned char> value_v(script.begin(), script.end()); std::vector<unsigned char> value_v(script.begin(), script.end());
value_v.push_back((uint8_t)leaf_ver); value_v.push_back((uint8_t)leaf_ver);
s << value_v; s << value_v;
@ -594,7 +594,7 @@ struct PSBTInput
} else if (key.size() != 65) { } else if (key.size() != 65) {
throw std::ios_base::failure("Input Taproot script signature key is not 65 bytes"); throw std::ios_base::failure("Input Taproot script signature key is not 65 bytes");
} }
SpanReader s_key{Span{key}.subspan(1)}; SpanReader s_key{std::span{key}.subspan(1)};
XOnlyPubKey xonly; XOnlyPubKey xonly;
uint256 hash; uint256 hash;
s_key >> xonly; s_key >> xonly;
@ -636,7 +636,7 @@ struct PSBTInput
} else if (key.size() != 33) { } else if (key.size() != 33) {
throw std::ios_base::failure("Input Taproot BIP32 keypath key is not at 33 bytes"); throw std::ios_base::failure("Input Taproot BIP32 keypath key is not at 33 bytes");
} }
SpanReader s_key{Span{key}.subspan(1)}; SpanReader s_key{std::span{key}.subspan(1)};
XOnlyPubKey xonly; XOnlyPubKey xonly;
s_key >> xonly; s_key >> xonly;
std::set<uint256> leaf_hashes; std::set<uint256> leaf_hashes;
@ -893,7 +893,7 @@ struct PSBTOutput
} else if (key.size() != 33) { } else if (key.size() != 33) {
throw std::ios_base::failure("Output Taproot BIP32 keypath key is not at 33 bytes"); throw std::ios_base::failure("Output Taproot BIP32 keypath key is not at 33 bytes");
} }
XOnlyPubKey xonly(uint256(Span<uint8_t>(key).last(32))); XOnlyPubKey xonly(uint256(std::span<uint8_t>(key).last(32)));
std::set<uint256> leaf_hashes; std::set<uint256> leaf_hashes;
uint64_t value_len = ReadCompactSize(s); uint64_t value_len = ReadCompactSize(s);
size_t before_hashes = s.size(); size_t before_hashes = s.size();
@ -1279,6 +1279,6 @@ bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransacti
//! Decode a base64ed PSBT into a PartiallySignedTransaction //! Decode a base64ed PSBT into a PartiallySignedTransaction
[[nodiscard]] bool DecodeBase64PSBT(PartiallySignedTransaction& decoded_psbt, const std::string& base64_psbt, std::string& error); [[nodiscard]] bool DecodeBase64PSBT(PartiallySignedTransaction& decoded_psbt, const std::string& base64_psbt, std::string& error);
//! Decode a raw (binary blob) PSBT into a PartiallySignedTransaction //! Decode a raw (binary blob) PSBT into a PartiallySignedTransaction
[[nodiscard]] bool DecodeRawPSBT(PartiallySignedTransaction& decoded_psbt, Span<const std::byte> raw_psbt, std::string& error); [[nodiscard]] bool DecodeRawPSBT(PartiallySignedTransaction& decoded_psbt, std::span<const std::byte> raw_psbt, std::string& error);
#endif // BITCOIN_PSBT_H #endif // BITCOIN_PSBT_H

View file

@ -1,4 +1,4 @@
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Copyright (c) 2017 The Zcash developers // Copyright (c) 2017 The Zcash developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -227,7 +227,7 @@ bool XOnlyPubKey::IsFullyValid() const
return secp256k1_xonly_pubkey_parse(secp256k1_context_static, &pubkey, m_keydata.data()); return secp256k1_xonly_pubkey_parse(secp256k1_context_static, &pubkey, m_keydata.data());
} }
bool XOnlyPubKey::VerifySchnorr(const uint256& msg, Span<const unsigned char> sigbytes) const bool XOnlyPubKey::VerifySchnorr(const uint256& msg, std::span<const unsigned char> sigbytes) const
{ {
assert(sigbytes.size() == 64); assert(sigbytes.size() == 64);
secp256k1_xonly_pubkey pubkey; secp256k1_xonly_pubkey pubkey;
@ -353,7 +353,7 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChi
return true; return true;
} }
EllSwiftPubKey::EllSwiftPubKey(Span<const std::byte> ellswift) noexcept EllSwiftPubKey::EllSwiftPubKey(std::span<const std::byte> ellswift) noexcept
{ {
assert(ellswift.size() == SIZE); assert(ellswift.size() == SIZE);
std::copy(ellswift.begin(), ellswift.end(), m_pubkey.begin()); std::copy(ellswift.begin(), ellswift.end(), m_pubkey.begin());

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Copyright (c) 2017 The Zcash developers // Copyright (c) 2017 The Zcash developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -103,7 +103,7 @@ public:
} }
//! Construct a public key from a byte vector. //! Construct a public key from a byte vector.
explicit CPubKey(Span<const uint8_t> _vch) explicit CPubKey(std::span<const uint8_t> _vch)
{ {
Set(_vch.begin(), _vch.end()); Set(_vch.begin(), _vch.end());
} }
@ -142,14 +142,14 @@ public:
{ {
unsigned int len = size(); unsigned int len = size();
::WriteCompactSize(s, len); ::WriteCompactSize(s, len);
s << Span{vch, len}; s << std::span{vch, len};
} }
template <typename Stream> template <typename Stream>
void Unserialize(Stream& s) void Unserialize(Stream& s)
{ {
const unsigned int len(::ReadCompactSize(s)); const unsigned int len(::ReadCompactSize(s));
if (len <= SIZE) { if (len <= SIZE) {
s >> Span{vch, len}; s >> std::span{vch, len};
if (len != size()) { if (len != size()) {
Invalidate(); Invalidate();
} }
@ -163,13 +163,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(Span{vch}.first(size()))); return CKeyID(Hash160(std::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(Span{vch}.first(size())); return Hash(std::span{vch}.first(size()));
} }
/* /*
@ -257,13 +257,13 @@ public:
constexpr explicit XOnlyPubKey(std::span<const unsigned char> bytes) : m_keydata{bytes} {} constexpr explicit XOnlyPubKey(std::span<const unsigned char> bytes) : m_keydata{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{pubkey}.subspan(1, 32)) {} explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(std::span{pubkey}.subspan(1, 32)) {}
/** Verify a Schnorr signature against this public key. /** Verify a Schnorr signature against this public key.
* *
* sigbytes must be exactly 64 bytes. * sigbytes must be exactly 64 bytes.
*/ */
bool VerifySchnorr(const uint256& msg, Span<const unsigned char> sigbytes) const; bool VerifySchnorr(const uint256& msg, std::span<const unsigned char> sigbytes) const;
/** Compute the Taproot tweak as specified in BIP341, with *this as internal /** Compute the Taproot tweak as specified in BIP341, with *this as internal
* key: * key:
@ -317,7 +317,7 @@ public:
EllSwiftPubKey() noexcept = default; EllSwiftPubKey() noexcept = default;
/** Construct a new ellswift public key from a given serialization. */ /** Construct a new ellswift public key from a given serialization. */
EllSwiftPubKey(Span<const std::byte> ellswift) noexcept; EllSwiftPubKey(std::span<const std::byte> ellswift) noexcept;
/** Decode to normal compressed CPubKey (for debugging purposes). */ /** Decode to normal compressed CPubKey (for debugging purposes). */
CPubKey Decode() const; CPubKey Decode() const;

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -505,7 +505,7 @@ public:
// Handle requests for deterministic randomness. // Handle requests for deterministic randomness.
if (!always_use_real_rng && m_deterministic_prng.has_value()) [[unlikely]] { if (!always_use_real_rng && m_deterministic_prng.has_value()) [[unlikely]] {
// Overwrite the beginning of buf, which will be used for output. // Overwrite the beginning of buf, which will be used for output.
m_deterministic_prng->Keystream(AsWritableBytes(Span{buf, num})); m_deterministic_prng->Keystream(std::as_writable_bytes(std::span{buf, num}));
// Do not require strong seeding for deterministic output. // Do not require strong seeding for deterministic output.
ret = true; ret = true;
} }
@ -673,13 +673,13 @@ void MakeRandDeterministicDANGEROUS(const uint256& seed) noexcept
} }
std::atomic<bool> g_used_g_prng{false}; // Only accessed from tests std::atomic<bool> g_used_g_prng{false}; // Only accessed from tests
void GetRandBytes(Span<unsigned char> bytes) noexcept void GetRandBytes(std::span<unsigned char> bytes) noexcept
{ {
g_used_g_prng = true; g_used_g_prng = true;
ProcRand(bytes.data(), bytes.size(), RNGLevel::FAST, /*always_use_real_rng=*/false); ProcRand(bytes.data(), bytes.size(), RNGLevel::FAST, /*always_use_real_rng=*/false);
} }
void GetStrongRandBytes(Span<unsigned char> bytes) noexcept void GetStrongRandBytes(std::span<unsigned char> bytes) noexcept
{ {
ProcRand(bytes.data(), bytes.size(), RNGLevel::SLOW, /*always_use_real_rng=*/true); ProcRand(bytes.data(), bytes.size(), RNGLevel::SLOW, /*always_use_real_rng=*/true);
} }
@ -698,7 +698,7 @@ void FastRandomContext::RandomSeed() noexcept
requires_seed = false; requires_seed = false;
} }
void FastRandomContext::fillrand(Span<std::byte> output) noexcept void FastRandomContext::fillrand(std::span<std::byte> output) noexcept
{ {
if (requires_seed) RandomSeed(); if (requires_seed) RandomSeed();
rng.Keystream(output); rng.Keystream(output);

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -114,7 +114,7 @@ void RandAddEvent(const uint32_t event_info) noexcept;
* *
* Thread-safe. * Thread-safe.
*/ */
void GetRandBytes(Span<unsigned char> bytes) noexcept; void GetRandBytes(std::span<unsigned char> bytes) noexcept;
/** /**
* Gather entropy from various sources, feed it into the internal PRNG, and * Gather entropy from various sources, feed it into the internal PRNG, and
@ -126,7 +126,7 @@ void GetRandBytes(Span<unsigned char> bytes) noexcept;
* *
* Thread-safe. * Thread-safe.
*/ */
void GetStrongRandBytes(Span<unsigned char> bytes) noexcept; void GetStrongRandBytes(std::span<unsigned char> bytes) noexcept;
/* ============================= RANDOM NUMBER GENERATION CLASSES ============================= /* ============================= RANDOM NUMBER GENERATION CLASSES =============================
@ -144,7 +144,7 @@ class RandomMixin;
/** A concept for RandomMixin-based random number generators. */ /** A concept for RandomMixin-based random number generators. */
template<typename T> template<typename T>
concept RandomNumberGenerator = requires(T& rng, Span<std::byte> s) { concept RandomNumberGenerator = requires(T& rng, std::span<std::byte> s) {
// A random number generator must provide rand64(). // A random number generator must provide rand64().
{ rng.rand64() } noexcept -> std::same_as<uint64_t>; { rng.rand64() } noexcept -> std::same_as<uint64_t>;
// A random number generator must derive from RandomMixin, which adds other rand* functions. // A random number generator must derive from RandomMixin, which adds other rand* functions.
@ -263,8 +263,8 @@ public:
} }
} }
/** Fill a Span with random bytes. */ /** Fill a span with random bytes. */
void fillrand(Span<std::byte> span) noexcept void fillrand(std::span<std::byte> span) noexcept
{ {
while (span.size() >= 8) { while (span.size() >= 8) {
uint64_t gen = Impl().rand64(); uint64_t gen = Impl().rand64();
@ -400,8 +400,8 @@ public:
return ReadLE64(buf.data()); return ReadLE64(buf.data());
} }
/** Fill a byte Span with random bytes. This overrides the RandomMixin version. */ /** Fill a byte span with random bytes. This overrides the RandomMixin version. */
void fillrand(Span<std::byte> output) noexcept; void fillrand(std::span<std::byte> output) noexcept;
}; };
/** xoroshiro128++ PRNG. Extremely fast, not appropriate for cryptographic purposes. /** xoroshiro128++ PRNG. Extremely fast, not appropriate for cryptographic purposes.

View file

@ -1,5 +1,5 @@
// Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -1074,7 +1074,7 @@ static RPCHelpMan decodepsbt()
UniValue keypath(UniValue::VOBJ); UniValue keypath(UniValue::VOBJ);
keypath.pushKV("xpub", EncodeBase58Check(ser_xpub)); keypath.pushKV("xpub", EncodeBase58Check(ser_xpub));
keypath.pushKV("master_fingerprint", HexStr(Span<unsigned char>(xpub_pair.first.fingerprint, xpub_pair.first.fingerprint + 4))); keypath.pushKV("master_fingerprint", HexStr(std::span<unsigned char>(xpub_pair.first.fingerprint, xpub_pair.first.fingerprint + 4)));
keypath.pushKV("path", WriteHDKeypath(xpub_pair.first.path)); keypath.pushKV("path", WriteHDKeypath(xpub_pair.first.path));
global_xpubs.push_back(std::move(keypath)); global_xpubs.push_back(std::move(keypath));
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) 2018-2022 The Bitcoin Core developers // Copyright (c) 2018-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -102,7 +102,7 @@ uint64_t PolyMod(uint64_t c, int val)
return c; return c;
} }
std::string DescriptorChecksum(const Span<const char>& span) std::string DescriptorChecksum(const std::span<const char>& span)
{ {
/** A character set designed such that: /** A character set designed such that:
* - The most common 'unprotected' descriptor characters (hex, keypaths) are in the first group of 32. * - The most common 'unprotected' descriptor characters (hex, keypaths) are in the first group of 32.
@ -595,7 +595,7 @@ protected:
* The origin info of the provided pubkeys is automatically added. * The origin info of the provided pubkeys is automatically added.
* @return A vector with scriptPubKeys for this descriptor. * @return A vector with scriptPubKeys for this descriptor.
*/ */
virtual std::vector<CScript> MakeScripts(const std::vector<CPubKey>& pubkeys, Span<const CScript> scripts, FlatSigningProvider& out) const = 0; virtual std::vector<CScript> MakeScripts(const std::vector<CPubKey>& pubkeys, std::span<const CScript> scripts, FlatSigningProvider& out) const = 0;
public: public:
DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args() {} DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args() {}
@ -725,7 +725,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, Span{subscripts}, out); output_scripts = MakeScripts(pubkeys, std::span{subscripts}, out);
return true; return true;
} }
@ -790,7 +790,7 @@ class AddressDescriptor final : public DescriptorImpl
const CTxDestination m_destination; const CTxDestination m_destination;
protected: protected:
std::string ToStringExtra() const override { return EncodeDestination(m_destination); } std::string ToStringExtra() const override { return EncodeDestination(m_destination); }
std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, Span<const CScript>, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(m_destination)); } std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript>, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(m_destination)); }
public: public:
AddressDescriptor(CTxDestination destination) : DescriptorImpl({}, "addr"), m_destination(std::move(destination)) {} AddressDescriptor(CTxDestination destination) : DescriptorImpl({}, "addr"), m_destination(std::move(destination)) {}
bool IsSolvable() const final { return false; } bool IsSolvable() const final { return false; }
@ -815,7 +815,7 @@ class RawDescriptor final : public DescriptorImpl
const CScript m_script; const CScript m_script;
protected: protected:
std::string ToStringExtra() const override { return HexStr(m_script); } std::string ToStringExtra() const override { return HexStr(m_script); }
std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, Span<const CScript>, FlatSigningProvider&) const override { return Vector(m_script); } std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript>, FlatSigningProvider&) const override { return Vector(m_script); }
public: public:
RawDescriptor(CScript script) : DescriptorImpl({}, "raw"), m_script(std::move(script)) {} RawDescriptor(CScript script) : DescriptorImpl({}, "raw"), m_script(std::move(script)) {}
bool IsSolvable() const final { return false; } bool IsSolvable() const final { return false; }
@ -843,7 +843,7 @@ class PKDescriptor final : public DescriptorImpl
private: private:
const bool m_xonly; const bool m_xonly;
protected: protected:
std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider&) const override std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override
{ {
if (m_xonly) { if (m_xonly) {
CScript script = CScript() << ToByteVector(XOnlyPubKey(keys[0])) << OP_CHECKSIG; CScript script = CScript() << ToByteVector(XOnlyPubKey(keys[0])) << OP_CHECKSIG;
@ -881,7 +881,7 @@ public:
class PKHDescriptor final : public DescriptorImpl class PKHDescriptor final : public DescriptorImpl
{ {
protected: protected:
std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider& out) const override std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider& out) const override
{ {
CKeyID id = keys[0].GetID(); CKeyID id = keys[0].GetID();
out.pubkeys.emplace(id, keys[0]); out.pubkeys.emplace(id, keys[0]);
@ -915,7 +915,7 @@ public:
class WPKHDescriptor final : public DescriptorImpl class WPKHDescriptor final : public DescriptorImpl
{ {
protected: protected:
std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider& out) const override std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider& out) const override
{ {
CKeyID id = keys[0].GetID(); CKeyID id = keys[0].GetID();
out.pubkeys.emplace(id, keys[0]); out.pubkeys.emplace(id, keys[0]);
@ -949,7 +949,7 @@ public:
class ComboDescriptor final : public DescriptorImpl class ComboDescriptor final : public DescriptorImpl
{ {
protected: protected:
std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider& out) const override std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider& out) const override
{ {
std::vector<CScript> ret; std::vector<CScript> ret;
CKeyID id = keys[0].GetID(); CKeyID id = keys[0].GetID();
@ -980,7 +980,7 @@ class MultisigDescriptor final : public DescriptorImpl
const bool m_sorted; const bool m_sorted;
protected: protected:
std::string ToStringExtra() const override { return strprintf("%i", m_threshold); } std::string ToStringExtra() const override { return strprintf("%i", m_threshold); }
std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider&) const override { std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override {
if (m_sorted) { if (m_sorted) {
std::vector<CPubKey> sorted_keys(keys); std::vector<CPubKey> sorted_keys(keys);
std::sort(sorted_keys.begin(), sorted_keys.end()); std::sort(sorted_keys.begin(), sorted_keys.end());
@ -1026,7 +1026,7 @@ class MultiADescriptor final : public DescriptorImpl
const bool m_sorted; const bool m_sorted;
protected: protected:
std::string ToStringExtra() const override { return strprintf("%i", m_threshold); } std::string ToStringExtra() const override { return strprintf("%i", m_threshold); }
std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider&) const override { std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override {
CScript ret; CScript ret;
std::vector<XOnlyPubKey> xkeys; std::vector<XOnlyPubKey> xkeys;
xkeys.reserve(keys.size()); xkeys.reserve(keys.size());
@ -1069,7 +1069,7 @@ public:
class SHDescriptor final : public DescriptorImpl class SHDescriptor final : public DescriptorImpl
{ {
protected: protected:
std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, Span<const CScript> scripts, FlatSigningProvider& out) const override std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript> scripts, FlatSigningProvider& out) const override
{ {
auto ret = Vector(GetScriptForDestination(ScriptHash(scripts[0]))); auto ret = Vector(GetScriptForDestination(ScriptHash(scripts[0])));
if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]); if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]);
@ -1119,7 +1119,7 @@ public:
class WSHDescriptor final : public DescriptorImpl class WSHDescriptor final : public DescriptorImpl
{ {
protected: protected:
std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, Span<const CScript> scripts, FlatSigningProvider& out) const override std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript> scripts, FlatSigningProvider& out) const override
{ {
auto ret = Vector(GetScriptForDestination(WitnessV0ScriptHash(scripts[0]))); auto ret = Vector(GetScriptForDestination(WitnessV0ScriptHash(scripts[0])));
if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]); if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]);
@ -1161,7 +1161,7 @@ class TRDescriptor final : public DescriptorImpl
{ {
std::vector<int> m_depths; std::vector<int> m_depths;
protected: protected:
std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript> scripts, FlatSigningProvider& out) const override std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript> scripts, FlatSigningProvider& out) const override
{ {
TaprootBuilder builder; TaprootBuilder builder;
assert(m_depths.size() == scripts.size()); assert(m_depths.size() == scripts.size());
@ -1304,7 +1304,7 @@ private:
miniscript::NodeRef<uint32_t> m_node; miniscript::NodeRef<uint32_t> m_node;
protected: protected:
std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript> scripts, std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider& provider) const override FlatSigningProvider& provider) const override
{ {
const auto script_ctx{m_node->GetMsCtx()}; const auto script_ctx{m_node->GetMsCtx()};
@ -1361,7 +1361,7 @@ public:
class RawTRDescriptor final : public DescriptorImpl class RawTRDescriptor final : public DescriptorImpl
{ {
protected: protected:
std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript> scripts, FlatSigningProvider& out) const override std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript> scripts, FlatSigningProvider& out) const override
{ {
assert(keys.size() == 1); assert(keys.size() == 1);
XOnlyPubKey xpk(keys[0]); XOnlyPubKey xpk(keys[0]);
@ -1404,7 +1404,7 @@ enum class ParseScriptContext {
P2TR, //!< Inside tr() (either internal key, or BIP342 script leaf) P2TR, //!< Inside tr() (either internal key, or BIP342 script leaf)
}; };
std::optional<uint32_t> ParseKeyPathNum(Span<const char> elem, bool& apostrophe, std::string& error) std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem, bool& apostrophe, std::string& error)
{ {
bool hardened = false; bool hardened = false;
if (elem.size() > 0) { if (elem.size() > 0) {
@ -1437,7 +1437,7 @@ std::optional<uint32_t> ParseKeyPathNum(Span<const char> elem, bool& apostrophe,
* @param[in] allow_multipath Allows the parsed path to use the multipath specifier * @param[in] allow_multipath Allows the parsed path to use the multipath specifier
* @returns false if parsing failed * @returns false if parsing failed
**/ **/
[[nodiscard]] bool ParseKeyPath(const std::vector<Span<const char>>& split, std::vector<KeyPath>& out, bool& apostrophe, std::string& error, bool allow_multipath) [[nodiscard]] bool ParseKeyPath(const std::vector<std::span<const char>>& split, std::vector<KeyPath>& out, bool& apostrophe, std::string& error, bool allow_multipath)
{ {
KeyPath path; KeyPath path;
std::optional<size_t> multipath_segment_index; std::optional<size_t> multipath_segment_index;
@ -1445,7 +1445,7 @@ std::optional<uint32_t> ParseKeyPathNum(Span<const char> elem, bool& apostrophe,
std::unordered_set<uint32_t> seen_multipath; std::unordered_set<uint32_t> seen_multipath;
for (size_t i = 1; i < split.size(); ++i) { for (size_t i = 1; i < split.size(); ++i) {
const Span<const char>& elem = split[i]; const std::span<const char>& elem = split[i];
// Check if element contain multipath specifier // Check if element contain multipath specifier
if (!elem.empty() && elem.front() == '<' && elem.back() == '>') { if (!elem.empty() && elem.front() == '<' && elem.back() == '>') {
@ -1459,7 +1459,7 @@ std::optional<uint32_t> ParseKeyPathNum(Span<const char> elem, bool& apostrophe,
} }
// Parse each possible value // Parse each possible value
std::vector<Span<const char>> nums = Split(Span(elem.begin()+1, elem.end()-1), ";"); std::vector<std::span<const char>> nums = Split(std::span(elem.begin()+1, elem.end()-1), ";");
if (nums.size() < 2) { if (nums.size() < 2) {
error = "Multipath key path specifiers must have at least two items"; error = "Multipath key path specifiers must have at least two items";
return false; return false;
@ -1499,7 +1499,7 @@ std::optional<uint32_t> ParseKeyPathNum(Span<const char> elem, bool& apostrophe,
} }
/** Parse a public key that excludes origin information. */ /** Parse a public key that excludes origin information. */
std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, bool& apostrophe, std::string& error) std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner(uint32_t key_exp_index, const std::span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, bool& apostrophe, std::string& error)
{ {
std::vector<std::unique_ptr<PubkeyProvider>> ret; std::vector<std::unique_ptr<PubkeyProvider>> ret;
bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH; bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
@ -1562,11 +1562,11 @@ std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner(uint32_t key_exp_i
} }
std::vector<KeyPath> paths; std::vector<KeyPath> paths;
DeriveType type = DeriveType::NO; DeriveType type = DeriveType::NO;
if (std::ranges::equal(split.back(), Span{"*"}.first(1))) { if (std::ranges::equal(split.back(), std::span{"*"}.first(1))) {
split.pop_back(); split.pop_back();
type = DeriveType::UNHARDENED; type = DeriveType::UNHARDENED;
} else if (std::ranges::equal(split.back(), Span{"*'"}.first(2)) || std::ranges::equal(split.back(), Span{"*h"}.first(2))) { } else if (std::ranges::equal(split.back(), std::span{"*'"}.first(2)) || std::ranges::equal(split.back(), std::span{"*h"}.first(2))) {
apostrophe = std::ranges::equal(split.back(), Span{"*'"}.first(2)); apostrophe = std::ranges::equal(split.back(), std::span{"*'"}.first(2));
split.pop_back(); split.pop_back();
type = DeriveType::HARDENED; type = DeriveType::HARDENED;
} }
@ -1582,7 +1582,7 @@ std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner(uint32_t key_exp_i
} }
/** Parse a public key including origin information (if enabled). */ /** Parse a public key including origin information (if enabled). */
std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error) std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t key_exp_index, const std::span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
{ {
std::vector<std::unique_ptr<PubkeyProvider>> ret; std::vector<std::unique_ptr<PubkeyProvider>> ret;
auto origin_split = Split(sp, ']'); auto origin_split = Split(sp, ']');
@ -1755,7 +1755,7 @@ struct KeyParser {
/** Parse a script in a particular context. */ /** Parse a script in a particular context. */
// NOLINTNEXTLINE(misc-no-recursion) // NOLINTNEXTLINE(misc-no-recursion)
std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error) std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
{ {
using namespace script; using namespace script;
Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR); Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
@ -2182,7 +2182,7 @@ std::unique_ptr<DescriptorImpl> InferMultiA(const CScript& script, ParseScriptCo
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{script}.subspan(1, 32)}; XOnlyPubKey key{std::span{script}.subspan(1, 32)};
return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider), true); return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider), true);
} }
@ -2325,7 +2325,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
} // namespace } // namespace
/** Check a descriptor checksum, and update desc to be the checksum-less part. */ /** Check a descriptor checksum, and update desc to be the checksum-less part. */
bool CheckChecksum(Span<const char>& sp, bool require_checksum, std::string& error, std::string* out_checksum = nullptr) bool CheckChecksum(std::span<const char>& sp, bool require_checksum, std::string& error, std::string* out_checksum = nullptr)
{ {
auto check_split = Split(sp, '#'); auto check_split = Split(sp, '#');
if (check_split.size() > 2) { if (check_split.size() > 2) {
@ -2360,7 +2360,7 @@ bool CheckChecksum(Span<const char>& sp, bool require_checksum, std::string& err
std::vector<std::unique_ptr<Descriptor>> Parse(const std::string& descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum) std::vector<std::unique_ptr<Descriptor>> Parse(const std::string& descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum)
{ {
Span<const char> sp{descriptor}; std::span<const char> sp{descriptor};
if (!CheckChecksum(sp, require_checksum, error)) return {}; if (!CheckChecksum(sp, require_checksum, error)) return {};
uint32_t key_exp_index = 0; uint32_t key_exp_index = 0;
auto ret = ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error); auto ret = ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error);
@ -2379,7 +2379,7 @@ std::string GetDescriptorChecksum(const std::string& descriptor)
{ {
std::string ret; std::string ret;
std::string error; std::string error;
Span<const char> sp{descriptor}; std::span<const char> sp{descriptor};
if (!CheckChecksum(sp, false, error, &ret)) return ""; if (!CheckChecksum(sp, false, error, &ret)) return "";
return ret; return ret;
} }

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -1278,12 +1278,12 @@ public:
it = itBegin; it = itBegin;
while (scriptCode.GetOp(it, opcode)) { while (scriptCode.GetOp(it, opcode)) {
if (opcode == OP_CODESEPARATOR) { if (opcode == OP_CODESEPARATOR) {
s.write(AsBytes(Span{&itBegin[0], size_t(it - itBegin - 1)})); s.write(std::as_bytes(std::span{&itBegin[0], size_t(it - itBegin - 1)}));
itBegin = it; itBegin = it;
} }
} }
if (itBegin != scriptCode.end()) if (itBegin != scriptCode.end())
s.write(AsBytes(Span{&itBegin[0], size_t(it - itBegin)})); s.write(std::as_bytes(std::span{&itBegin[0], size_t(it - itBegin)}));
} }
/** Serialize an input of txTo */ /** Serialize an input of txTo */
@ -1639,7 +1639,7 @@ bool GenericTransactionSignatureChecker<T>::VerifyECDSASignature(const std::vect
} }
template <class T> template <class T>
bool GenericTransactionSignatureChecker<T>::VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const bool GenericTransactionSignatureChecker<T>::VerifySchnorrSignature(std::span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const
{ {
return pubkey.VerifySchnorr(sighash, sig); return pubkey.VerifySchnorr(sighash, sig);
} }
@ -1670,7 +1670,7 @@ bool GenericTransactionSignatureChecker<T>::CheckECDSASignature(const std::vecto
} }
template <class T> template <class T>
bool GenericTransactionSignatureChecker<T>::CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey_in, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const bool GenericTransactionSignatureChecker<T>::CheckSchnorrSignature(std::span<const unsigned char> sig, std::span<const unsigned char> pubkey_in, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const
{ {
assert(sigversion == SigVersion::TAPROOT || sigversion == SigVersion::TAPSCRIPT); assert(sigversion == SigVersion::TAPROOT || sigversion == SigVersion::TAPSCRIPT);
// Schnorr signatures have 32-byte public keys. The caller is responsible for enforcing this. // Schnorr signatures have 32-byte public keys. The caller is responsible for enforcing this.
@ -1785,7 +1785,7 @@ bool GenericTransactionSignatureChecker<T>::CheckSequence(const CScriptNum& nSeq
template class GenericTransactionSignatureChecker<CTransaction>; template class GenericTransactionSignatureChecker<CTransaction>;
template class GenericTransactionSignatureChecker<CMutableTransaction>; template class GenericTransactionSignatureChecker<CMutableTransaction>;
static bool ExecuteWitnessScript(const Span<const valtype>& stack_span, const CScript& exec_script, unsigned int flags, SigVersion sigversion, const BaseSignatureChecker& checker, ScriptExecutionData& execdata, ScriptError* serror) static bool ExecuteWitnessScript(const std::span<const valtype>& stack_span, const CScript& exec_script, unsigned int flags, SigVersion sigversion, const BaseSignatureChecker& checker, ScriptExecutionData& execdata, ScriptError* serror)
{ {
std::vector<valtype> stack{stack_span.begin(), stack_span.end()}; std::vector<valtype> stack{stack_span.begin(), stack_span.end()};
@ -1825,12 +1825,12 @@ static bool ExecuteWitnessScript(const Span<const valtype>& stack_span, const CS
return true; return true;
} }
uint256 ComputeTapleafHash(uint8_t leaf_version, Span<const unsigned char> script) uint256 ComputeTapleafHash(uint8_t leaf_version, std::span<const unsigned char> script)
{ {
return (HashWriter{HASHER_TAPLEAF} << leaf_version << CompactSizeWriter(script.size()) << script).GetSHA256(); return (HashWriter{HASHER_TAPLEAF} << leaf_version << CompactSizeWriter(script.size()) << script).GetSHA256();
} }
uint256 ComputeTapbranchHash(Span<const unsigned char> a, Span<const unsigned char> b) uint256 ComputeTapbranchHash(std::span<const unsigned char> a, std::span<const unsigned char> b)
{ {
HashWriter ss_branch{HASHER_TAPBRANCH}; HashWriter ss_branch{HASHER_TAPBRANCH};
if (std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end())) { if (std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end())) {
@ -1841,7 +1841,7 @@ uint256 ComputeTapbranchHash(Span<const unsigned char> a, Span<const unsigned ch
return ss_branch.GetSHA256(); return ss_branch.GetSHA256();
} }
uint256 ComputeTaprootMerkleRoot(Span<const unsigned char> control, const uint256& tapleaf_hash) uint256 ComputeTaprootMerkleRoot(std::span<const unsigned char> control, const uint256& tapleaf_hash)
{ {
assert(control.size() >= TAPROOT_CONTROL_BASE_SIZE); assert(control.size() >= TAPROOT_CONTROL_BASE_SIZE);
assert(control.size() <= TAPROOT_CONTROL_MAX_SIZE); assert(control.size() <= TAPROOT_CONTROL_MAX_SIZE);
@ -1850,7 +1850,7 @@ uint256 ComputeTaprootMerkleRoot(Span<const unsigned char> control, const uint25
const int path_len = (control.size() - TAPROOT_CONTROL_BASE_SIZE) / TAPROOT_CONTROL_NODE_SIZE; const int path_len = (control.size() - TAPROOT_CONTROL_BASE_SIZE) / TAPROOT_CONTROL_NODE_SIZE;
uint256 k = tapleaf_hash; uint256 k = tapleaf_hash;
for (int i = 0; i < path_len; ++i) { for (int i = 0; i < path_len; ++i) {
Span node{Span{control}.subspan(TAPROOT_CONTROL_BASE_SIZE + TAPROOT_CONTROL_NODE_SIZE * i, TAPROOT_CONTROL_NODE_SIZE)}; std::span node{std::span{control}.subspan(TAPROOT_CONTROL_BASE_SIZE + TAPROOT_CONTROL_NODE_SIZE * i, TAPROOT_CONTROL_NODE_SIZE)};
k = ComputeTapbranchHash(k, node); k = ComputeTapbranchHash(k, node);
} }
return k; return k;
@ -1861,7 +1861,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{control}.subspan(1, TAPROOT_CONTROL_BASE_SIZE - 1)}; const XOnlyPubKey p{std::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.
@ -1873,7 +1873,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 stack{witness.stack}; std::span stack{witness.stack};
ScriptExecutionData execdata; ScriptExecutionData execdata;
if (witversion == 0) { if (witversion == 0) {

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -250,7 +250,7 @@ public:
return false; return false;
} }
virtual bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const virtual bool CheckSchnorrSignature(std::span<const unsigned char> sig, std::span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const
{ {
return false; return false;
} }
@ -292,13 +292,13 @@ private:
protected: protected:
virtual bool VerifyECDSASignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; virtual bool VerifyECDSASignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
virtual bool VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const; virtual bool VerifySchnorrSignature(std::span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const;
public: public:
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, MissingDataBehavior mdb) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(nullptr) {} GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, MissingDataBehavior mdb) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(nullptr) {}
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn, MissingDataBehavior mdb) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {} GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn, MissingDataBehavior mdb) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {}
bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override; bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override;
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override; bool CheckSchnorrSignature(std::span<const unsigned char> sig, std::span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override;
bool CheckLockTime(const CScriptNum& nLockTime) const override; bool CheckLockTime(const CScriptNum& nLockTime) const override;
bool CheckSequence(const CScriptNum& nSequence) const override; bool CheckSequence(const CScriptNum& nSequence) const override;
}; };
@ -319,7 +319,7 @@ public:
return m_checker.CheckECDSASignature(scriptSig, vchPubKey, scriptCode, sigversion); return m_checker.CheckECDSASignature(scriptSig, vchPubKey, scriptCode, sigversion);
} }
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override bool CheckSchnorrSignature(std::span<const unsigned char> sig, std::span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override
{ {
return m_checker.CheckSchnorrSignature(sig, pubkey, sigversion, execdata, serror); return m_checker.CheckSchnorrSignature(sig, pubkey, sigversion, execdata, serror);
} }
@ -335,13 +335,13 @@ public:
}; };
/** Compute the BIP341 tapleaf hash from leaf version & script. */ /** Compute the BIP341 tapleaf hash from leaf version & script. */
uint256 ComputeTapleafHash(uint8_t leaf_version, Span<const unsigned char> script); uint256 ComputeTapleafHash(uint8_t leaf_version, std::span<const unsigned char> script);
/** Compute the BIP341 tapbranch hash from two branches. /** Compute the BIP341 tapbranch hash from two branches.
* Spans must be 32 bytes each. */ * Spans must be 32 bytes each. */
uint256 ComputeTapbranchHash(Span<const unsigned char> a, Span<const unsigned char> b); uint256 ComputeTapbranchHash(std::span<const unsigned char> a, std::span<const unsigned char> b);
/** Compute the BIP341 taproot script tree Merkle root from control block and leaf hash. /** Compute the BIP341 taproot script tree Merkle root from control block and leaf hash.
* Requires control block to have valid length (33 + k*32, with k in {0,1,..,128}). */ * Requires control block to have valid length (33 + k*32, with k in {0,1,..,128}). */
uint256 ComputeTaprootMerkleRoot(Span<const unsigned char> control, const uint256& tapleaf_hash); uint256 ComputeTaprootMerkleRoot(std::span<const unsigned char> control, const uint256& tapleaf_hash);
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* error = nullptr); bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* error = nullptr);
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* error = nullptr); bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* error = nullptr);

View file

@ -419,7 +419,7 @@ std::optional<int64_t> ParseScriptNumber(const Opcode& in) {
return {}; return {};
} }
int FindNextChar(Span<const char> sp, const char m) int FindNextChar(std::span<const char> sp, const char m)
{ {
for (int i = 0; i < (int)sp.size(); ++i) { for (int i = 0; i < (int)sp.size(); ++i) {
if (sp[i] == m) return i; if (sp[i] == m) return i;

View file

@ -531,7 +531,7 @@ struct Node {
NodeRef<Key> Clone() const NodeRef<Key> Clone() const
{ {
// Use TreeEval() to avoid a stack-overflow due to recursion // Use TreeEval() to avoid a stack-overflow due to recursion
auto upfn = [](const Node& node, Span<NodeRef<Key>> children) { auto upfn = [](const Node& node, std::span<NodeRef<Key>> children) {
std::vector<NodeRef<Key>> new_subs; std::vector<NodeRef<Key>> new_subs;
for (auto child = children.begin(); child != children.end(); ++child) { for (auto child = children.begin(); child != children.end(); ++child) {
new_subs.emplace_back(std::move(*child)); new_subs.emplace_back(std::move(*child));
@ -592,8 +592,8 @@ private:
* node, its state, and an index of one of its children, computes the state of that * node, its state, and an index of one of its children, computes the state of that
* child. It can modify the state. Children of a given node will have downfn() * child. It can modify the state. Children of a given node will have downfn()
* called in order. * called in order.
* - upfn is a callable (State&&, const Node&, Span<Result>) -> std::optional<Result>, * - upfn is a callable (State&&, const Node&, std::span<Result>) -> std::optional<Result>,
* which given a node, its state, and a Span of the results of its children, * which given a node, its state, and a span of the results of its children,
* computes the result of the node. If std::nullopt is returned by upfn, * computes the result of the node. If std::nullopt is returned by upfn,
* TreeEvalMaybe() immediately returns std::nullopt. * TreeEvalMaybe() immediately returns std::nullopt.
* The return value of TreeEvalMaybe is the result of the root node. * The return value of TreeEvalMaybe is the result of the root node.
@ -650,7 +650,7 @@ private:
// Invoke upfn with the last node.subs.size() elements of results as input. // Invoke upfn with the last node.subs.size() elements of results as input.
assert(results.size() >= node.subs.size()); assert(results.size() >= node.subs.size());
std::optional<Result> result{upfn(std::move(stack.back().state), node, std::optional<Result> result{upfn(std::move(stack.back().state), node,
Span<Result>{results}.last(node.subs.size()))}; std::span<Result>{results}.last(node.subs.size()))};
// If evaluation returns std::nullopt, abort immediately. // If evaluation returns std::nullopt, abort immediately.
if (!result) return {}; if (!result) return {};
// Replace the last node.subs.size() elements of results with the new result. // Replace the last node.subs.size() elements of results with the new result.
@ -664,14 +664,14 @@ private:
} }
/** Like TreeEvalMaybe, but without downfn or State type. /** Like TreeEvalMaybe, but without downfn or State type.
* upfn takes (const Node&, Span<Result>) and returns std::optional<Result>. */ * upfn takes (const Node&, std::span<Result>) and returns std::optional<Result>. */
template<typename Result, typename UpFn> template<typename Result, typename UpFn>
std::optional<Result> TreeEvalMaybe(UpFn upfn) const std::optional<Result> TreeEvalMaybe(UpFn upfn) const
{ {
struct DummyState {}; struct DummyState {};
return TreeEvalMaybe<Result>(DummyState{}, return TreeEvalMaybe<Result>(DummyState{},
[](DummyState, const Node&, size_t) { return DummyState{}; }, [](DummyState, const Node&, size_t) { return DummyState{}; },
[&upfn](DummyState, const Node& node, Span<Result> subs) { [&upfn](DummyState, const Node& node, std::span<Result> subs) {
return upfn(node, subs); return upfn(node, subs);
} }
); );
@ -685,7 +685,7 @@ private:
// unconditionally dereference the result (it cannot be std::nullopt). // unconditionally dereference the result (it cannot be std::nullopt).
return std::move(*TreeEvalMaybe<Result>(std::move(root_state), return std::move(*TreeEvalMaybe<Result>(std::move(root_state),
std::forward<DownFn>(downfn), std::forward<DownFn>(downfn),
[&upfn](State&& state, const Node& node, Span<Result> subs) { [&upfn](State&& state, const Node& node, std::span<Result> subs) {
Result res{upfn(std::move(state), node, subs)}; Result res{upfn(std::move(state), node, subs)};
return std::optional<Result>(std::move(res)); return std::optional<Result>(std::move(res));
} }
@ -693,14 +693,14 @@ private:
} }
/** Like TreeEval, but without downfn or State type. /** Like TreeEval, but without downfn or State type.
* upfn takes (const Node&, Span<Result>) and returns Result. */ * upfn takes (const Node&, std::span<Result>) and returns Result. */
template<typename Result, typename UpFn> template<typename Result, typename UpFn>
Result TreeEval(UpFn upfn) const Result TreeEval(UpFn upfn) const
{ {
struct DummyState {}; struct DummyState {};
return std::move(*TreeEvalMaybe<Result>(DummyState{}, return std::move(*TreeEvalMaybe<Result>(DummyState{},
[](DummyState, const Node&, size_t) { return DummyState{}; }, [](DummyState, const Node&, size_t) { return DummyState{}; },
[&upfn](DummyState, const Node& node, Span<Result> subs) { [&upfn](DummyState, const Node& node, std::span<Result> subs) {
Result res{upfn(node, subs)}; Result res{upfn(node, subs)};
return std::optional<Result>(std::move(res)); return std::optional<Result>(std::move(res));
} }
@ -764,7 +764,7 @@ public:
// The upward function computes for a node, given its followed-by-OP_VERIFY status // The upward function computes for a node, given its followed-by-OP_VERIFY status
// and the CScripts of its child nodes, the CScript of the node. // and the CScripts of its child nodes, the CScript of the node.
const bool is_tapscript{IsTapscript(m_script_ctx)}; const bool is_tapscript{IsTapscript(m_script_ctx)};
auto upfn = [&ctx, is_tapscript](bool verify, const Node& node, Span<CScript> subs) -> CScript { auto upfn = [&ctx, is_tapscript](bool verify, const Node& node, std::span<CScript> subs) -> CScript {
switch (node.fragment) { switch (node.fragment) {
case Fragment::PK_K: return BuildScript(ctx.ToPKBytes(node.keys[0])); case Fragment::PK_K: return BuildScript(ctx.ToPKBytes(node.keys[0]));
case Fragment::PK_H: return BuildScript(OP_DUP, OP_HASH160, ctx.ToPKHBytes(node.keys[0]), OP_EQUALVERIFY); case Fragment::PK_H: return BuildScript(OP_DUP, OP_HASH160, ctx.ToPKHBytes(node.keys[0]), OP_EQUALVERIFY);
@ -842,7 +842,7 @@ public:
// The upward function computes for a node, given whether its parent is a wrapper, // The upward function computes for a node, given whether its parent is a wrapper,
// and the string representations of its child nodes, the string representation of the node. // and the string representations of its child nodes, the string representation of the node.
const bool is_tapscript{IsTapscript(m_script_ctx)}; const bool is_tapscript{IsTapscript(m_script_ctx)};
auto upfn = [&ctx, is_tapscript](bool wrapped, const Node& node, Span<std::string> subs) -> std::optional<std::string> { auto upfn = [&ctx, is_tapscript](bool wrapped, const Node& node, std::span<std::string> subs) -> std::optional<std::string> {
std::string ret = wrapped ? ":" : ""; std::string ret = wrapped ? ":" : "";
switch (node.fragment) { switch (node.fragment) {
@ -1189,7 +1189,7 @@ private:
// Internal function which is invoked for every tree node, constructing satisfaction/dissatisfactions // Internal function which is invoked for every tree node, constructing satisfaction/dissatisfactions
// given those of its subnodes. // given those of its subnodes.
auto helper = [&ctx](const Node& node, Span<InputResult> subres) -> InputResult { auto helper = [&ctx](const Node& node, std::span<InputResult> subres) -> InputResult {
switch (node.fragment) { switch (node.fragment) {
case Fragment::PK_K: { case Fragment::PK_K: {
std::vector<unsigned char> sig; std::vector<unsigned char> sig;
@ -1385,7 +1385,7 @@ private:
return {INVALID, INVALID}; return {INVALID, INVALID};
}; };
auto tester = [&helper](const Node& node, Span<InputResult> subres) -> InputResult { auto tester = [&helper](const Node& node, std::span<InputResult> subres) -> InputResult {
auto ret = helper(node, subres); auto ret = helper(node, subres);
// Do a consistency check between the satisfaction code and the type checker // Do a consistency check between the satisfaction code and the type checker
@ -1453,7 +1453,7 @@ public:
using keyset = std::set<Key, Comp>; using keyset = std::set<Key, Comp>;
using state = std::optional<keyset>; using state = std::optional<keyset>;
auto upfn = [&ctx](const Node& node, Span<state> subs) -> state { auto upfn = [&ctx](const Node& node, std::span<state> subs) -> state {
// If this node is already known to have duplicates, nothing left to do. // If this node is already known to have duplicates, nothing left to do.
if (node.has_duplicate_keys.has_value() && *node.has_duplicate_keys) return {}; if (node.has_duplicate_keys.has_value() && *node.has_duplicate_keys) return {};
@ -1561,7 +1561,7 @@ public:
//! Find an insane subnode which has no insane children. Nullptr if there is none. //! Find an insane subnode which has no insane children. Nullptr if there is none.
const Node* FindInsaneSub() const { const Node* FindInsaneSub() const {
return TreeEval<const Node*>([](const Node& node, Span<const Node*> subs) -> const Node* { return TreeEval<const Node*>([](const Node& node, std::span<const Node*> subs) -> const Node* {
for (auto& sub: subs) if (sub) return sub; for (auto& sub: subs) if (sub) return sub;
if (!node.IsSaneSubexpression()) return &node; if (!node.IsSaneSubexpression()) return &node;
return nullptr; return nullptr;
@ -1574,7 +1574,7 @@ public:
bool IsSatisfiable(F fn) const bool IsSatisfiable(F fn) const
{ {
// TreeEval() doesn't support bool as NodeType, so use int instead. // TreeEval() doesn't support bool as NodeType, so use int instead.
return TreeEval<int>([&fn](const Node& node, Span<int> subs) -> bool { return TreeEval<int>([&fn](const Node& node, std::span<int> subs) -> bool {
switch (node.fragment) { switch (node.fragment) {
case Fragment::JUST_0: case Fragment::JUST_0:
return false; return false;
@ -1744,11 +1744,11 @@ enum class ParseContext {
CLOSE_BRACKET, CLOSE_BRACKET,
}; };
int FindNextChar(Span<const char> in, const char m); int FindNextChar(std::span<const char> in, const char m);
/** Parse a key string ending at the end of the fragment's text representation. */ /** Parse a key string ending at the end of the fragment's text representation. */
template<typename Key, typename Ctx> template<typename Key, typename Ctx>
std::optional<std::pair<Key, int>> ParseKeyEnd(Span<const char> in, const Ctx& ctx) std::optional<std::pair<Key, int>> ParseKeyEnd(std::span<const char> in, const Ctx& ctx)
{ {
int key_size = FindNextChar(in, ')'); int key_size = FindNextChar(in, ')');
if (key_size < 1) return {}; if (key_size < 1) return {};
@ -1759,7 +1759,7 @@ std::optional<std::pair<Key, int>> ParseKeyEnd(Span<const char> in, const Ctx& c
/** Parse a hex string ending at the end of the fragment's text representation. */ /** Parse a hex string ending at the end of the fragment's text representation. */
template<typename Ctx> template<typename Ctx>
std::optional<std::pair<std::vector<unsigned char>, int>> ParseHexStrEnd(Span<const char> in, const size_t expected_size, std::optional<std::pair<std::vector<unsigned char>, int>> ParseHexStrEnd(std::span<const char> in, const size_t expected_size,
const Ctx& ctx) const Ctx& ctx)
{ {
int hash_size = FindNextChar(in, ')'); int hash_size = FindNextChar(in, ')');
@ -1790,7 +1790,7 @@ void BuildBack(const MiniscriptContext script_ctx, Fragment nt, std::vector<Node
* the `IsValidTopLevel()` and `IsSaneTopLevel()` to check for these properties on the node. * the `IsValidTopLevel()` and `IsSaneTopLevel()` to check for these properties on the node.
*/ */
template<typename Key, typename Ctx> template<typename Key, typename Ctx>
inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx) inline NodeRef<Key> Parse(std::span<const char> in, const Ctx& ctx)
{ {
using namespace script; using namespace script;
@ -1814,7 +1814,7 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1); to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1);
// Parses a multi() or multi_a() from its string representation. Returns false on parsing error. // Parses a multi() or multi_a() from its string representation. Returns false on parsing error.
const auto parse_multi_exp = [&](Span<const char>& in, const bool is_multi_a) -> bool { const auto parse_multi_exp = [&](std::span<const char>& in, const bool is_multi_a) -> bool {
const auto max_keys{is_multi_a ? MAX_PUBKEYS_PER_MULTI_A : MAX_PUBKEYS_PER_MULTISIG}; const auto max_keys{is_multi_a ? MAX_PUBKEYS_PER_MULTI_A : MAX_PUBKEYS_PER_MULTISIG};
const auto required_ctx{is_multi_a ? MiniscriptContext::TAPSCRIPT : MiniscriptContext::P2WSH}; const auto required_ctx{is_multi_a ? MiniscriptContext::TAPSCRIPT : MiniscriptContext::P2WSH};
if (ctx.MsContext() != required_ctx) return false; if (ctx.MsContext() != required_ctx) return false;

View file

@ -1,4 +1,4 @@
// Copyright (c) 2018-2022 The Bitcoin Core developers // Copyright (c) 2018-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -12,7 +12,7 @@
namespace script { namespace script {
bool Const(const std::string& str, Span<const char>& sp) bool Const(const std::string& str, std::span<const char>& sp)
{ {
if ((size_t)sp.size() >= str.size() && std::equal(str.begin(), str.end(), sp.begin())) { if ((size_t)sp.size() >= str.size() && std::equal(str.begin(), str.end(), sp.begin())) {
sp = sp.subspan(str.size()); sp = sp.subspan(str.size());
@ -21,7 +21,7 @@ bool Const(const std::string& str, Span<const char>& sp)
return false; return false;
} }
bool Func(const std::string& str, Span<const char>& sp) bool Func(const std::string& str, std::span<const char>& sp)
{ {
if ((size_t)sp.size() >= str.size() + 2 && sp[str.size()] == '(' && sp[sp.size() - 1] == ')' && std::equal(str.begin(), str.end(), sp.begin())) { if ((size_t)sp.size() >= str.size() + 2 && sp[str.size()] == '(' && sp[sp.size() - 1] == ')' && std::equal(str.begin(), str.end(), sp.begin())) {
sp = sp.subspan(str.size() + 1, sp.size() - str.size() - 2); sp = sp.subspan(str.size() + 1, sp.size() - str.size() - 2);
@ -30,7 +30,7 @@ bool Func(const std::string& str, Span<const char>& sp)
return false; return false;
} }
Span<const char> Expr(Span<const char>& sp) std::span<const char> Expr(std::span<const char>& sp)
{ {
int level = 0; int level = 0;
auto it = sp.begin(); auto it = sp.begin();
@ -44,7 +44,7 @@ Span<const char> Expr(Span<const char>& sp)
} }
++it; ++it;
} }
Span<const char> ret = sp.first(it - sp.begin()); std::span<const char> ret = sp.first(it - sp.begin());
sp = sp.subspan(it - sp.begin()); sp = sp.subspan(it - sp.begin());
return ret; return ret;
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) 2018-2022 The Bitcoin Core developers // Copyright (c) 2018-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -16,7 +16,7 @@ namespace script {
* If sp's initial part matches str, sp is updated to skip that part, and true is returned. * If sp's initial part matches str, sp is updated to skip that part, and true is returned.
* Otherwise sp is unmodified and false is returned. * Otherwise sp is unmodified and false is returned.
*/ */
bool Const(const std::string& str, Span<const char>& sp); bool Const(const std::string& str, std::span<const char>& sp);
/** Parse a function call. /** Parse a function call.
* *
@ -24,7 +24,7 @@ bool Const(const std::string& str, Span<const char>& sp);
* section between the braces, and true is returned. Otherwise sp is unmodified and false * section between the braces, and true is returned. Otherwise sp is unmodified and false
* is returned. * is returned.
*/ */
bool Func(const std::string& str, Span<const char>& sp); bool Func(const std::string& str, std::span<const char>& sp);
/** Extract the expression that sp begins with. /** Extract the expression that sp begins with.
* *
@ -33,7 +33,7 @@ bool Func(const std::string& str, Span<const char>& sp);
* for "foo(bar(1),2),3" the initial part "foo(bar(1),2)" will be returned. sp will be * for "foo(bar(1),2),3" the initial part "foo(bar(1),2)" will be returned. sp will be
* updated to skip the initial part that is returned. * updated to skip the initial part that is returned.
*/ */
Span<const char> Expr(Span<const char>& sp); std::span<const char> Expr(std::span<const char>& sp);
} // namespace script } // namespace script

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -42,7 +42,7 @@ void SignatureCache::ComputeEntryECDSA(uint256& entry, const uint256& hash, cons
hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(vchSig.data(), vchSig.size()).Finalize(entry.begin()); hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(vchSig.data(), vchSig.size()).Finalize(entry.begin());
} }
void SignatureCache::ComputeEntrySchnorr(uint256& entry, const uint256& hash, Span<const unsigned char> sig, const XOnlyPubKey& pubkey) const void SignatureCache::ComputeEntrySchnorr(uint256& entry, const uint256& hash, std::span<const unsigned char> sig, const XOnlyPubKey& pubkey) const
{ {
CSHA256 hasher = m_salted_hasher_schnorr; CSHA256 hasher = m_salted_hasher_schnorr;
hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(sig.data(), sig.size()).Finalize(entry.begin()); hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(sig.data(), sig.size()).Finalize(entry.begin());
@ -73,7 +73,7 @@ bool CachingTransactionSignatureChecker::VerifyECDSASignature(const std::vector<
return true; return true;
} }
bool CachingTransactionSignatureChecker::VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const bool CachingTransactionSignatureChecker::VerifySchnorrSignature(std::span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const
{ {
uint256 entry; uint256 entry;
m_signature_cache.ComputeEntrySchnorr(entry, sighash, sig, pubkey); m_signature_cache.ComputeEntrySchnorr(entry, sighash, sig, pubkey);

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -53,7 +53,7 @@ public:
void ComputeEntryECDSA(uint256& entry, const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubkey) const; void ComputeEntryECDSA(uint256& entry, const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubkey) const;
void ComputeEntrySchnorr(uint256& entry, const uint256 &hash, Span<const unsigned char> sig, const XOnlyPubKey& pubkey) const; void ComputeEntrySchnorr(uint256& entry, const uint256 &hash, std::span<const unsigned char> sig, const XOnlyPubKey& pubkey) const;
bool Get(const uint256& entry, const bool erase); bool Get(const uint256& entry, const bool erase);
@ -70,7 +70,7 @@ public:
CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, bool storeIn, SignatureCache& signature_cache, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amountIn, txdataIn, MissingDataBehavior::ASSERT_FAIL), store(storeIn), m_signature_cache(signature_cache) {} CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, bool storeIn, SignatureCache& signature_cache, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amountIn, txdataIn, MissingDataBehavior::ASSERT_FAIL), store(storeIn), m_signature_cache(signature_cache) {}
bool VerifyECDSASignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const override; bool VerifyECDSASignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const override;
bool VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const override; bool VerifySchnorrSignature(std::span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const override;
}; };
#endif // BITCOIN_SCRIPT_SIGCACHE_H #endif // BITCOIN_SCRIPT_SIGCACHE_H

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -317,7 +317,7 @@ struct TapSatisfier: Satisfier<XOnlyPubKey> {
} }
}; };
static bool SignTaprootScript(const SigningProvider& provider, const BaseSignatureCreator& creator, SignatureData& sigdata, int leaf_version, Span<const unsigned char> script_bytes, std::vector<valtype>& result) static bool SignTaprootScript(const SigningProvider& provider, const BaseSignatureCreator& creator, SignatureData& sigdata, int leaf_version, std::span<const unsigned char> script_bytes, std::vector<valtype>& result)
{ {
// Only BIP342 tapscript signing is supported for now. // Only BIP342 tapscript signing is supported for now.
if (leaf_version != TAPROOT_LEAF_TAPSCRIPT) return false; if (leaf_version != TAPROOT_LEAF_TAPSCRIPT) return false;
@ -701,7 +701,7 @@ class DummySignatureChecker final : public BaseSignatureChecker
public: public:
DummySignatureChecker() = default; DummySignatureChecker() = default;
bool CheckECDSASignature(const std::vector<unsigned char>& sig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override { return sig.size() != 0; } bool CheckECDSASignature(const std::vector<unsigned char>& sig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override { return sig.size() != 0; }
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const override { return sig.size() != 0; } bool CheckSchnorrSignature(std::span<const unsigned char> sig, std::span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const override { return sig.size() != 0; }
bool CheckLockTime(const CScriptNum& nLockTime) const override { return true; } bool CheckLockTime(const CScriptNum& nLockTime) const override { return true; }
bool CheckSequence(const CScriptNum& nSequence) const override { return true; } bool CheckSequence(const CScriptNum& nSequence) const override { return true; }
}; };

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -368,7 +368,7 @@ void TaprootBuilder::Insert(TaprootBuilder::NodeInfo&& node, int depth)
return branch.size() == 0 || (branch.size() == 1 && branch[0]); return branch.size() == 0 || (branch.size() == 1 && branch[0]);
} }
TaprootBuilder& TaprootBuilder::Add(int depth, Span<const unsigned char> script, int leaf_version, bool track) TaprootBuilder& TaprootBuilder::Add(int depth, std::span<const unsigned char> script, int leaf_version, bool track)
{ {
assert((leaf_version & ~TAPROOT_LEAF_MASK) == 0); assert((leaf_version & ~TAPROOT_LEAF_MASK) == 0);
if (!IsValid()) return *this; if (!IsValid()) return *this;

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -115,7 +115,7 @@ public:
/** Add a new script at a certain depth in the tree. Add() operations must be called /** Add a new script at a certain depth in the tree. Add() operations must be called
* in depth-first traversal order of binary tree. If track is true, it will be included in * in depth-first traversal order of binary tree. If track is true, it will be included in
* the GetSpendData() output. */ * the GetSpendData() output. */
TaprootBuilder& Add(int depth, Span<const unsigned char> script, int leaf_version, bool track = true); TaprootBuilder& Add(int depth, std::span<const unsigned char> script, int leaf_version, bool track = true);
/** Like Add(), but for a Merkle node with a given hash to the tree. */ /** Like Add(), but for a Merkle node with a given hash to the tree. */
TaprootBuilder& AddOmitted(int depth, const uint256& hash); TaprootBuilder& AddOmitted(int depth, const uint256& hash);
/** Finalize the construction. Can only be called when IsComplete() is true. /** Finalize the construction. Can only be called when IsComplete() is true.

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -104,9 +104,9 @@ static bool MatchMultisig(const CScript& script, int& required_sigs, std::vector
return (it + 1 == script.end()); return (it + 1 == script.end());
} }
std::optional<std::pair<int, std::vector<Span<const unsigned char>>>> MatchMultiA(const CScript& script) std::optional<std::pair<int, std::vector<std::span<const unsigned char>>>> MatchMultiA(const CScript& script)
{ {
std::vector<Span<const unsigned char>> keyspans; std::vector<std::span<const unsigned char>> keyspans;
// Redundant, but very fast and selective test. // Redundant, but very fast and selective test.
if (script.size() == 0 || script[0] != 32 || script.back() != OP_NUMEQUAL) return {}; if (script.size() == 0 || script[0] != 32 || script.back() != OP_NUMEQUAL) return {};

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -59,7 +59,7 @@ CScript GetScriptForRawPubKey(const CPubKey& pubkey);
/** Determine if script is a "multi_a" script. Returns (threshold, keyspans) if so, and nullopt otherwise. /** Determine if script is a "multi_a" script. Returns (threshold, keyspans) if so, and nullopt otherwise.
* The keyspans refer to bytes in the passed script. */ * The keyspans refer to bytes in the passed script. */
std::optional<std::pair<int, std::vector<Span<const unsigned char>>>> MatchMultiA(const CScript& script LIFETIMEBOUND); std::optional<std::pair<int, std::vector<std::span<const unsigned char>>>> MatchMultiA(const CScript& script LIFETIMEBOUND);
/** Generate a multisig script. */ /** Generate a multisig script. */
CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys); CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys);

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -53,67 +53,67 @@ constexpr deserialize_type deserialize {};
*/ */
template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj) template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
{ {
s.write(AsBytes(Span{&obj, 1})); s.write(std::as_bytes(std::span{&obj, 1}));
} }
template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj) template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
{ {
obj = htole16_internal(obj); obj = htole16_internal(obj);
s.write(AsBytes(Span{&obj, 1})); s.write(std::as_bytes(std::span{&obj, 1}));
} }
template<typename Stream> inline void ser_writedata16be(Stream &s, uint16_t obj) template<typename Stream> inline void ser_writedata16be(Stream &s, uint16_t obj)
{ {
obj = htobe16_internal(obj); obj = htobe16_internal(obj);
s.write(AsBytes(Span{&obj, 1})); s.write(std::as_bytes(std::span{&obj, 1}));
} }
template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj) template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
{ {
obj = htole32_internal(obj); obj = htole32_internal(obj);
s.write(AsBytes(Span{&obj, 1})); s.write(std::as_bytes(std::span{&obj, 1}));
} }
template<typename Stream> inline void ser_writedata32be(Stream &s, uint32_t obj) template<typename Stream> inline void ser_writedata32be(Stream &s, uint32_t obj)
{ {
obj = htobe32_internal(obj); obj = htobe32_internal(obj);
s.write(AsBytes(Span{&obj, 1})); s.write(std::as_bytes(std::span{&obj, 1}));
} }
template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj) template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
{ {
obj = htole64_internal(obj); obj = htole64_internal(obj);
s.write(AsBytes(Span{&obj, 1})); s.write(std::as_bytes(std::span{&obj, 1}));
} }
template<typename Stream> inline uint8_t ser_readdata8(Stream &s) template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
{ {
uint8_t obj; uint8_t obj;
s.read(AsWritableBytes(Span{&obj, 1})); s.read(std::as_writable_bytes(std::span{&obj, 1}));
return obj; return obj;
} }
template<typename Stream> inline uint16_t ser_readdata16(Stream &s) template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
{ {
uint16_t obj; uint16_t obj;
s.read(AsWritableBytes(Span{&obj, 1})); s.read(std::as_writable_bytes(std::span{&obj, 1}));
return le16toh_internal(obj); return le16toh_internal(obj);
} }
template<typename Stream> inline uint16_t ser_readdata16be(Stream &s) template<typename Stream> inline uint16_t ser_readdata16be(Stream &s)
{ {
uint16_t obj; uint16_t obj;
s.read(AsWritableBytes(Span{&obj, 1})); s.read(std::as_writable_bytes(std::span{&obj, 1}));
return be16toh_internal(obj); return be16toh_internal(obj);
} }
template<typename Stream> inline uint32_t ser_readdata32(Stream &s) template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
{ {
uint32_t obj; uint32_t obj;
s.read(AsWritableBytes(Span{&obj, 1})); s.read(std::as_writable_bytes(std::span{&obj, 1}));
return le32toh_internal(obj); return le32toh_internal(obj);
} }
template<typename Stream> inline uint32_t ser_readdata32be(Stream &s) template<typename Stream> inline uint32_t ser_readdata32be(Stream &s)
{ {
uint32_t obj; uint32_t obj;
s.read(AsWritableBytes(Span{&obj, 1})); s.read(std::as_writable_bytes(std::span{&obj, 1}));
return be32toh_internal(obj); return be32toh_internal(obj);
} }
template<typename Stream> inline uint64_t ser_readdata64(Stream &s) template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
{ {
uint64_t obj; uint64_t obj;
s.read(AsWritableBytes(Span{&obj, 1})); s.read(std::as_writable_bytes(std::span{&obj, 1}));
return le64toh_internal(obj); return le64toh_internal(obj);
} }
@ -242,7 +242,7 @@ const Out& AsBase(const In& x)
FORMATTER_METHODS(cls, obj) FORMATTER_METHODS(cls, obj)
// Templates for serializing to anything that looks like a stream, // Templates for serializing to anything that looks like a stream,
// i.e. anything that supports .read(Span<std::byte>) and .write(Span<const std::byte>) // i.e. anything that supports .read(std::span<std::byte>) and .write(std::span<const std::byte>)
// //
// clang-format off // clang-format off
@ -265,7 +265,7 @@ template<typename Stream> inline void Serialize(Stream& s, uint64_t a) { ser_wri
template <typename Stream, BasicByte B, int N> void Serialize(Stream& s, const B (&a)[N]) { s.write(MakeByteSpan(a)); } template <typename Stream, BasicByte B, int N> void Serialize(Stream& s, const B (&a)[N]) { s.write(MakeByteSpan(a)); }
template <typename Stream, BasicByte B, std::size_t N> void Serialize(Stream& s, const std::array<B, N>& a) { s.write(MakeByteSpan(a)); } template <typename Stream, BasicByte B, std::size_t N> void Serialize(Stream& s, const std::array<B, N>& a) { s.write(MakeByteSpan(a)); }
template <typename Stream, BasicByte B, std::size_t N> void Serialize(Stream& s, std::span<B, N> span) { s.write(std::as_bytes(span)); } template <typename Stream, BasicByte B, std::size_t N> void Serialize(Stream& s, std::span<B, N> span) { s.write(std::as_bytes(span)); }
template <typename Stream, BasicByte B> void Serialize(Stream& s, Span<B> span) { s.write(AsBytes(span)); } template <typename Stream, BasicByte B> void Serialize(Stream& s, std::span<B> span) { s.write(std::as_bytes(span)); }
template <typename Stream, CharNotInt8 V> void Unserialize(Stream&, V) = delete; // char serialization forbidden. Use uint8_t or int8_t template <typename Stream, CharNotInt8 V> void Unserialize(Stream&, V) = delete; // char serialization forbidden. Use uint8_t or int8_t
template <typename Stream> void Unserialize(Stream& s, std::byte& a) { a = std::byte{ser_readdata8(s)}; } template <typename Stream> void Unserialize(Stream& s, std::byte& a) { a = std::byte{ser_readdata8(s)}; }
@ -280,7 +280,7 @@ template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a =
template <typename Stream, BasicByte B, int N> void Unserialize(Stream& s, B (&a)[N]) { s.read(MakeWritableByteSpan(a)); } template <typename Stream, BasicByte B, int N> void Unserialize(Stream& s, B (&a)[N]) { s.read(MakeWritableByteSpan(a)); }
template <typename Stream, BasicByte B, std::size_t N> void Unserialize(Stream& s, std::array<B, N>& a) { s.read(MakeWritableByteSpan(a)); } template <typename Stream, BasicByte B, std::size_t N> void Unserialize(Stream& s, std::array<B, N>& a) { s.read(MakeWritableByteSpan(a)); }
template <typename Stream, BasicByte B, std::size_t N> void Unserialize(Stream& s, std::span<B, N> span) { s.read(std::as_writable_bytes(span)); } template <typename Stream, BasicByte B, std::size_t N> void Unserialize(Stream& s, std::span<B, N> span) { s.read(std::as_writable_bytes(span)); }
template <typename Stream, BasicByte B> void Unserialize(Stream& s, Span<B> span) { s.read(AsWritableBytes(span)); } template <typename Stream, BasicByte B> void Unserialize(Stream& s, std::span<B> span) { s.read(std::as_writable_bytes(span)); }
template <typename Stream> inline void Serialize(Stream& s, bool a) { uint8_t f = a; ser_writedata8(s, f); } template <typename Stream> inline void Serialize(Stream& s, bool a) { uint8_t f = a; ser_writedata8(s, f); }
template <typename Stream> inline void Unserialize(Stream& s, bool& a) { uint8_t f = ser_readdata8(s); a = f; } template <typename Stream> inline void Unserialize(Stream& s, bool& a) { uint8_t f = ser_readdata8(s); a = f; }
@ -536,10 +536,10 @@ struct CustomUintFormatter
if (v < 0 || v > MAX) throw std::ios_base::failure("CustomUintFormatter value out of range"); if (v < 0 || v > MAX) throw std::ios_base::failure("CustomUintFormatter value out of range");
if (BigEndian) { if (BigEndian) {
uint64_t raw = htobe64_internal(v); uint64_t raw = htobe64_internal(v);
s.write(AsBytes(Span{&raw, 1}).last(Bytes)); s.write(std::as_bytes(std::span{&raw, 1}).last(Bytes));
} else { } else {
uint64_t raw = htole64_internal(v); uint64_t raw = htole64_internal(v);
s.write(AsBytes(Span{&raw, 1}).first(Bytes)); s.write(std::as_bytes(std::span{&raw, 1}).first(Bytes));
} }
} }
@ -549,10 +549,10 @@ struct CustomUintFormatter
static_assert(std::numeric_limits<U>::max() >= MAX && std::numeric_limits<U>::min() <= 0, "Assigned type too small"); static_assert(std::numeric_limits<U>::max() >= MAX && std::numeric_limits<U>::min() <= 0, "Assigned type too small");
uint64_t raw = 0; uint64_t raw = 0;
if (BigEndian) { if (BigEndian) {
s.read(AsWritableBytes(Span{&raw, 1}).last(Bytes)); s.read(std::as_writable_bytes(std::span{&raw, 1}).last(Bytes));
v = static_cast<I>(be64toh_internal(raw)); v = static_cast<I>(be64toh_internal(raw));
} else { } else {
s.read(AsWritableBytes(Span{&raw, 1}).first(Bytes)); s.read(std::as_writable_bytes(std::span{&raw, 1}).first(Bytes));
v = static_cast<I>(le64toh_internal(raw)); v = static_cast<I>(le64toh_internal(raw));
} }
} }
@ -829,7 +829,7 @@ void Unserialize(Stream& is, prevector<N, T>& v)
while (i < nSize) { while (i < nSize) {
unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
v.resize_uninitialized(i + blk); v.resize_uninitialized(i + blk);
is.read(AsWritableBytes(Span{&v[i], blk})); is.read(std::as_writable_bytes(std::span{&v[i], blk}));
i += blk; i += blk;
} }
} else { } else {
@ -872,7 +872,7 @@ void Unserialize(Stream& is, std::vector<T, A>& v)
while (i < nSize) { while (i < nSize) {
unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
v.resize(i + blk); v.resize(i + blk);
is.read(AsWritableBytes(Span{&v[i], blk})); is.read(std::as_writable_bytes(std::span{&v[i], blk}));
i += blk; i += blk;
} }
} else { } else {
@ -1065,7 +1065,7 @@ protected:
public: public:
SizeComputer() = default; SizeComputer() = default;
void write(Span<const std::byte> src) void write(std::span<const std::byte> src)
{ {
this->nSize += src.size(); this->nSize += src.size();
} }
@ -1132,8 +1132,8 @@ public:
template <typename U> ParamsStream& operator<<(const U& obj) { ::Serialize(*this, obj); return *this; } template <typename U> ParamsStream& operator<<(const U& obj) { ::Serialize(*this, obj); return *this; }
template <typename U> ParamsStream& operator>>(U&& obj) { ::Unserialize(*this, obj); return *this; } template <typename U> ParamsStream& operator>>(U&& obj) { ::Unserialize(*this, obj); return *this; }
void write(Span<const std::byte> src) { GetStream().write(src); } void write(std::span<const std::byte> src) { GetStream().write(src); }
void read(Span<std::byte> dst) { GetStream().read(dst); } void read(std::span<std::byte> dst) { GetStream().read(dst); }
void ignore(size_t num) { GetStream().ignore(num); } void ignore(size_t num) { GetStream().ignore(num); }
bool eof() const { return GetStream().eof(); } bool eof() const { return GetStream().eof(); }
size_t size() const { return GetStream().size(); } size_t size() const { return GetStream().size(); }

View file

@ -1,4 +1,4 @@
// Copyright (c) 2019-2021 The Bitcoin Core developers // Copyright (c) 2019-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -28,7 +28,7 @@ static constexpr uint8_t SIGNET_HEADER[4] = {0xec, 0xc7, 0xda, 0xa2};
static constexpr unsigned int BLOCK_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_NULLDUMMY; static constexpr unsigned int BLOCK_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_NULLDUMMY;
static bool FetchAndClearCommitmentSection(const Span<const uint8_t> header, CScript& witness_commitment, std::vector<uint8_t>& result) static bool FetchAndClearCommitmentSection(const std::span<const uint8_t> header, CScript& witness_commitment, std::vector<uint8_t>& result)
{ {
CScript replacement; CScript replacement;
bool found_header = false; bool found_header = false;
@ -39,7 +39,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() > header.size() && std::ranges::equal(Span{pushdata}.first(header.size()), header)) { if (!found_header && pushdata.size() > header.size() && std::ranges::equal(std::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());

View file

@ -1,4 +1,4 @@
// Copyright (c) 2018-2022 The Bitcoin Core developers // Copyright (c) 2018-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -11,62 +11,38 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#ifdef DEBUG /** A span is an object that can refer to a contiguous sequence of objects.
#define CONSTEXPR_IF_NOT_DEBUG
#define ASSERT_IF_DEBUG(x) assert((x))
#else
#define CONSTEXPR_IF_NOT_DEBUG constexpr
#define ASSERT_IF_DEBUG(x)
#endif
#if defined(__clang__)
#if __has_attribute(lifetimebound)
#define SPAN_ATTR_LIFETIMEBOUND [[clang::lifetimebound]]
#else
#define SPAN_ATTR_LIFETIMEBOUND
#endif
#else
#define SPAN_ATTR_LIFETIMEBOUND
#endif
/** A Span is an object that can refer to a contiguous sequence of objects.
* *
* This file implements a subset of C++20's std::span. It can be considered * Things to be aware of when writing code that deals with spans:
* temporary compatibility code until C++20 and is designed to be a
* self-contained abstraction without depending on other project files. For this
* reason, Clang lifetimebound is defined here instead of including
* <attributes.h>, which also defines it.
* *
* Things to be aware of when writing code that deals with Spans: * - Similar to references themselves, spans are subject to reference lifetime
*
* - Similar to references themselves, Spans are subject to reference lifetime
* issues. The user is responsible for making sure the objects pointed to by * issues. The user is responsible for making sure the objects pointed to by
* a Span live as long as the Span is used. For example: * a span live as long as the span is used. For example:
* *
* std::vector<int> vec{1,2,3,4}; * std::vector<int> vec{1,2,3,4};
* Span<int> sp(vec); * std::span<int> sp(vec);
* vec.push_back(5); * vec.push_back(5);
* printf("%i\n", sp.front()); // UB! * printf("%i\n", sp.front()); // UB!
* *
* may exhibit undefined behavior, as increasing the size of a vector may * may exhibit undefined behavior, as increasing the size of a vector may
* invalidate references. * invalidate references.
* *
* - One particular pitfall is that Spans can be constructed from temporaries, * - One particular pitfall is that spans can be constructed from temporaries,
* but this is unsafe when the Span is stored in a variable, outliving the * but this is unsafe when the span is stored in a variable, outliving the
* temporary. For example, this will compile, but exhibits undefined behavior: * temporary. For example, this will compile, but exhibits undefined behavior:
* *
* Span<const int> sp(std::vector<int>{1, 2, 3}); * std::span<const int> sp(std::vector<int>{1, 2, 3});
* printf("%i\n", sp.front()); // UB! * printf("%i\n", sp.front()); // UB!
* *
* The lifetime of the vector ends when the statement it is created in ends. * The lifetime of the vector ends when the statement it is created in ends.
* Thus the Span is left with a dangling reference, and using it is undefined. * Thus the span is left with a dangling reference, and using it is undefined.
* *
* - Due to Span's automatic creation from range-like objects (arrays, and data * - Due to spans automatic creation from range-like objects (arrays, and data
* types that expose a data() and size() member function), functions that * types that expose a data() and size() member function), functions that
* accept a Span as input parameter can be called with any compatible * accept a span as input parameter can be called with any compatible
* range-like object. For example, this works: * range-like object. For example, this works:
* *
* void Foo(Span<const int> arg); * void Foo(std::span<const int> arg);
* *
* Foo(std::vector<int>{1, 2, 3}); // Works * Foo(std::vector<int>{1, 2, 3}); // Works
* *
@ -74,10 +50,10 @@
* container, and only about having exactly a range of elements. However it * container, and only about having exactly a range of elements. However it
* may also be surprising to see automatic conversions in this case. * may also be surprising to see automatic conversions in this case.
* *
* When a function accepts a Span with a mutable element type, it will not * When a function accepts a span with a mutable element type, it will not
* accept temporaries; only variables or other references. For example: * accept temporaries; only variables or other references. For example:
* *
* void FooMut(Span<int> arg); * void FooMut(std::span<int> arg);
* *
* FooMut(std::vector<int>{1, 2, 3}); // Does not compile * FooMut(std::vector<int>{1, 2, 3}); // Does not compile
* std::vector<int> baz{1, 2, 3}; * std::vector<int> baz{1, 2, 3};
@ -93,159 +69,10 @@
* result will be present in that variable after the call. Passing a temporary * result will be present in that variable after the call. Passing a temporary
* is useless in that context. * is useless in that context.
*/ */
template<typename C>
class Span
{
C* m_data;
std::size_t m_size{0};
template <class T>
struct is_Span_int : public std::false_type {};
template <class T>
struct is_Span_int<Span<T>> : public std::true_type {};
template <class T>
struct is_Span : public is_Span_int<typename std::remove_cv<T>::type>{};
public:
constexpr Span() noexcept : m_data(nullptr) {}
/** Construct a span from a begin pointer and a size.
*
* This implements a subset of the iterator-based std::span constructor in C++20,
* which is hard to implement without std::address_of.
*/
template <typename T, typename std::enable_if<std::is_convertible<T (*)[], C (*)[]>::value, int>::type = 0>
constexpr Span(T* begin, std::size_t size) noexcept : m_data(begin), m_size(size) {}
/** Construct a span from a begin and end pointer.
*
* This implements a subset of the iterator-based std::span constructor in C++20,
* which is hard to implement without std::address_of.
*/
template <typename T, typename std::enable_if<std::is_convertible<T (*)[], C (*)[]>::value, int>::type = 0>
CONSTEXPR_IF_NOT_DEBUG Span(T* begin, T* end) noexcept : m_data(begin), m_size(end - begin)
{
ASSERT_IF_DEBUG(end >= begin);
}
/** Implicit conversion of spans between compatible types.
*
* Specifically, if a pointer to an array of type O can be implicitly converted to a pointer to an array of type
* C, then permit implicit conversion of Span<O> to Span<C>. This matches the behavior of the corresponding
* C++20 std::span constructor.
*
* For example this means that a Span<T> can be converted into a Span<const T>.
*/
template <typename O, typename std::enable_if<std::is_convertible<O (*)[], C (*)[]>::value, int>::type = 0>
constexpr Span(const Span<O>& other) noexcept : m_data(other.m_data), m_size(other.m_size) {}
/** Default copy constructor. */
constexpr Span(const Span&) noexcept = default;
/** Default assignment operator. */
Span& operator=(const Span& other) noexcept = default;
/** Construct a Span from an array. This matches the corresponding C++20 std::span constructor. */
template <int N>
constexpr Span(C (&a)[N]) noexcept : m_data(a), m_size(N) {}
/** Construct a Span for objects with .data() and .size() (std::string, std::array, std::vector, ...).
*
* This implements a subset of the functionality provided by the C++20 std::span range-based constructor.
*
* To prevent surprises, only Spans for constant value types are supported when passing in temporaries.
* Note that this restriction does not exist when converting arrays or other Spans (see above).
*/
template <typename V>
constexpr Span(V& other SPAN_ATTR_LIFETIMEBOUND,
typename std::enable_if<!is_Span<V>::value &&
std::is_convertible<typename std::remove_pointer<decltype(std::declval<V&>().data())>::type (*)[], C (*)[]>::value &&
std::is_convertible<decltype(std::declval<V&>().size()), std::size_t>::value, std::nullptr_t>::type = nullptr)
: m_data(other.data()), m_size(other.size()){}
template <typename V>
constexpr Span(const V& other SPAN_ATTR_LIFETIMEBOUND,
typename std::enable_if<!is_Span<V>::value &&
std::is_convertible<typename std::remove_pointer<decltype(std::declval<const V&>().data())>::type (*)[], C (*)[]>::value &&
std::is_convertible<decltype(std::declval<const V&>().size()), std::size_t>::value, std::nullptr_t>::type = nullptr)
: m_data(other.data()), m_size(other.size()){}
constexpr C* data() const noexcept { return m_data; }
constexpr C* begin() const noexcept { return m_data; }
constexpr C* end() const noexcept { return m_data + m_size; }
CONSTEXPR_IF_NOT_DEBUG C& front() const noexcept
{
ASSERT_IF_DEBUG(size() > 0);
return m_data[0];
}
CONSTEXPR_IF_NOT_DEBUG C& back() const noexcept
{
ASSERT_IF_DEBUG(size() > 0);
return m_data[m_size - 1];
}
constexpr std::size_t size() const noexcept { return m_size; }
constexpr std::size_t size_bytes() const noexcept { return sizeof(C) * m_size; }
constexpr bool empty() const noexcept { return size() == 0; }
CONSTEXPR_IF_NOT_DEBUG C& operator[](std::size_t pos) const noexcept
{
ASSERT_IF_DEBUG(size() > pos);
return m_data[pos];
}
CONSTEXPR_IF_NOT_DEBUG Span<C> subspan(std::size_t offset) const noexcept
{
ASSERT_IF_DEBUG(size() >= offset);
return Span<C>(m_data + offset, m_size - offset);
}
CONSTEXPR_IF_NOT_DEBUG Span<C> subspan(std::size_t offset, std::size_t count) const noexcept
{
ASSERT_IF_DEBUG(size() >= offset + count);
return Span<C>(m_data + offset, count);
}
CONSTEXPR_IF_NOT_DEBUG Span<C> first(std::size_t count) const noexcept
{
ASSERT_IF_DEBUG(size() >= count);
return Span<C>(m_data, count);
}
CONSTEXPR_IF_NOT_DEBUG Span<C> last(std::size_t count) const noexcept
{
ASSERT_IF_DEBUG(size() >= count);
return Span<C>(m_data + m_size - count, count);
}
template <typename O> friend class Span;
};
// Return result of calling .data() method on type T. This is used to be able to
// write template deduction guides for the single-parameter Span constructor
// below that will work if the value that is passed has a .data() method, and if
// the data method does not return a void pointer.
//
// It is important to check for the void type specifically below, so the
// deduction guides can be used in SFINAE contexts to check whether objects can
// be converted to spans. If the deduction guides did not explicitly check for
// void, and an object was passed that returned void* from data (like
// std::vector<bool>), the template deduction would succeed, but the Span<void>
// object instantiation would fail, resulting in a hard error, rather than a
// SFINAE error.
// https://stackoverflow.com/questions/68759148/sfinae-to-detect-the-explicitness-of-a-ctad-deduction-guide
// https://stackoverflow.com/questions/16568986/what-happens-when-you-call-data-on-a-stdvectorbool
template<typename T>
using DataResult = std::remove_pointer_t<decltype(std::declval<T&>().data())>;
// 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> && !std::is_void_v<DataResult<T&&>>, const DataResult<T&&>>>;
// For (lvalue) references, supporting mutable output.
template <typename T> Span(T&) -> Span<std::enable_if_t<!std::is_void_v<DataResult<T&>>, DataResult<T&>>>;
/** 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>
T& SpanPopBack(Span<T>& span) T& SpanPopBack(std::span<T>& span)
{ {
size_t size = span.size(); size_t size = span.size();
T& back = span.back(); T& back = span.back();
@ -253,27 +80,15 @@ T& SpanPopBack(Span<T>& span)
return back; return back;
} }
// From C++20 as_bytes and as_writeable_bytes
template <typename T>
Span<const std::byte> AsBytes(Span<T> s) noexcept
{
return {reinterpret_cast<const std::byte*>(s.data()), s.size_bytes()};
}
template <typename T>
Span<std::byte> AsWritableBytes(Span<T> s) noexcept
{
return {reinterpret_cast<std::byte*>(s.data()), s.size_bytes()};
}
template <typename V> template <typename V>
Span<const std::byte> MakeByteSpan(V&& v) noexcept auto MakeByteSpan(const V& v) noexcept
{ {
return AsBytes(Span{std::forward<V>(v)}); return std::as_bytes(std::span{v});
} }
template <typename V> template <typename V>
Span<std::byte> MakeWritableByteSpan(V&& v) noexcept auto MakeWritableByteSpan(V&& v) noexcept
{ {
return AsWritableBytes(Span{std::forward<V>(v)}); return std::as_writable_bytes(std::span{std::forward<V>(v)});
} }
// Helper functions to safely cast basic byte pointers to unsigned char pointers. // Helper functions to safely cast basic byte pointers to unsigned char pointers.
@ -289,10 +104,11 @@ inline const unsigned char* UCharCast(const std::byte* c) { return reinterpret_c
template <typename B> template <typename B>
concept BasicByte = requires { UCharCast(std::span<B>{}.data()); }; concept BasicByte = requires { UCharCast(std::span<B>{}.data()); };
// 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, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; }
/** Like the Span constructor, but for (const) unsigned char member types only. Only works for (un)signed char containers. */ /** Like the std::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)}); } template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); }
template <typename V> constexpr auto MakeWritableUCharSpan(V&& v) -> decltype(UCharSpanCast(std::span{std::forward<V>(v)})) { return UCharSpanCast(std::span{std::forward<V>(v)}); }
#endif // BITCOIN_SPAN_H #endif // BITCOIN_SPAN_H

View file

@ -18,7 +18,7 @@ AutoFile::AutoFile(std::FILE* file, std::vector<std::byte> data_xor)
} }
} }
std::size_t AutoFile::detail_fread(Span<std::byte> dst) std::size_t AutoFile::detail_fread(std::span<std::byte> dst)
{ {
if (!m_file) throw std::ios_base::failure("AutoFile::read: file handle is nullptr"); if (!m_file) throw std::ios_base::failure("AutoFile::read: file handle is nullptr");
size_t ret = std::fread(dst.data(), 1, dst.size(), m_file); size_t ret = std::fread(dst.data(), 1, dst.size(), m_file);
@ -57,7 +57,7 @@ int64_t AutoFile::tell()
return *m_position; return *m_position;
} }
void AutoFile::read(Span<std::byte> dst) void AutoFile::read(std::span<std::byte> dst)
{ {
if (detail_fread(dst) != dst.size()) { if (detail_fread(dst) != dst.size()) {
throw std::ios_base::failure(feof() ? "AutoFile::read: end of file" : "AutoFile::read: fread failed"); throw std::ios_base::failure(feof() ? "AutoFile::read: end of file" : "AutoFile::read: fread failed");
@ -78,7 +78,7 @@ void AutoFile::ignore(size_t nSize)
} }
} }
void AutoFile::write(Span<const std::byte> src) void AutoFile::write(std::span<const std::byte> src)
{ {
if (!m_file) throw std::ios_base::failure("AutoFile::write: file handle is nullptr"); if (!m_file) throw std::ios_base::failure("AutoFile::write: file handle is nullptr");
if (m_xor.empty()) { if (m_xor.empty()) {
@ -90,7 +90,7 @@ void AutoFile::write(Span<const std::byte> src)
if (!m_position.has_value()) throw std::ios_base::failure("AutoFile::write: position unknown"); if (!m_position.has_value()) throw std::ios_base::failure("AutoFile::write: position unknown");
std::array<std::byte, 4096> buf; std::array<std::byte, 4096> buf;
while (src.size() > 0) { while (src.size() > 0) {
auto buf_now{Span{buf}.first(std::min<size_t>(src.size(), buf.size()))}; auto buf_now{std::span{buf}.first(std::min<size_t>(src.size(), buf.size()))};
std::copy(src.begin(), src.begin() + buf_now.size(), buf_now.begin()); std::copy(src.begin(), src.begin() + buf_now.size(), buf_now.begin());
util::Xor(buf_now, m_xor, *m_position); util::Xor(buf_now, m_xor, *m_position);
if (std::fwrite(buf_now.data(), 1, buf_now.size(), m_file) != buf_now.size()) { if (std::fwrite(buf_now.data(), 1, buf_now.size(), m_file) != buf_now.size()) {

View file

@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -25,7 +25,7 @@
#include <vector> #include <vector>
namespace util { namespace util {
inline void Xor(Span<std::byte> write, Span<const std::byte> key, size_t key_offset = 0) inline void Xor(std::span<std::byte> write, std::span<const std::byte> key, size_t key_offset = 0)
{ {
if (key.size() == 0) { if (key.size() == 0) {
return; return;
@ -71,7 +71,7 @@ public:
{ {
::SerializeMany(*this, std::forward<Args>(args)...); ::SerializeMany(*this, std::forward<Args>(args)...);
} }
void write(Span<const std::byte> src) void write(std::span<const std::byte> src)
{ {
assert(nPos <= vchData.size()); assert(nPos <= vchData.size());
size_t nOverwrite = std::min(src.size(), vchData.size() - nPos); size_t nOverwrite = std::min(src.size(), vchData.size() - nPos);
@ -95,18 +95,18 @@ private:
size_t nPos; size_t nPos;
}; };
/** Minimal stream for reading from an existing byte array by Span. /** Minimal stream for reading from an existing byte array by std::span.
*/ */
class SpanReader class SpanReader
{ {
private: private:
Span<const unsigned char> m_data; std::span<const unsigned char> m_data;
public: public:
/** /**
* @param[in] data Referenced byte vector to overwrite/append * @param[in] data Referenced byte vector to overwrite/append
*/ */
explicit SpanReader(Span<const unsigned char> data) : m_data{data} {} explicit SpanReader(std::span<const unsigned char> data) : m_data{data} {}
template<typename T> template<typename T>
SpanReader& operator>>(T&& obj) SpanReader& operator>>(T&& obj)
@ -118,7 +118,7 @@ public:
size_t size() const { return m_data.size(); } size_t size() const { return m_data.size(); }
bool empty() const { return m_data.empty(); } bool empty() const { return m_data.empty(); }
void read(Span<std::byte> dst) void read(std::span<std::byte> dst)
{ {
if (dst.size() == 0) { if (dst.size() == 0) {
return; return;
@ -162,8 +162,8 @@ public:
typedef vector_type::reverse_iterator reverse_iterator; typedef vector_type::reverse_iterator reverse_iterator;
explicit DataStream() = default; explicit DataStream() = default;
explicit DataStream(Span<const uint8_t> sp) : DataStream{AsBytes(sp)} {} explicit DataStream(std::span<const uint8_t> sp) : DataStream{std::as_bytes(sp)} {}
explicit DataStream(Span<const value_type> sp) : vch(sp.data(), sp.data() + sp.size()) {} explicit DataStream(std::span<const value_type> sp) : vch(sp.data(), sp.data() + sp.size()) {}
std::string str() const std::string str() const
{ {
@ -215,7 +215,7 @@ public:
bool eof() const { return size() == 0; } bool eof() const { return size() == 0; }
int in_avail() const { return size(); } int in_avail() const { return size(); }
void read(Span<value_type> dst) void read(std::span<value_type> dst)
{ {
if (dst.size() == 0) return; if (dst.size() == 0) return;
@ -248,7 +248,7 @@ public:
m_read_pos = next_read_pos.value(); m_read_pos = next_read_pos.value();
} }
void write(Span<const value_type> src) void write(std::span<const value_type> src)
{ {
// Write to the end of the buffer // Write to the end of the buffer
vch.insert(vch.end(), src.begin(), src.end()); vch.insert(vch.end(), src.begin(), src.end());
@ -431,7 +431,7 @@ public:
void SetXor(std::vector<std::byte> data_xor) { m_xor = data_xor; } void SetXor(std::vector<std::byte> data_xor) { m_xor = data_xor; }
/** Implementation detail, only used internally. */ /** Implementation detail, only used internally. */
std::size_t detail_fread(Span<std::byte> dst); std::size_t detail_fread(std::span<std::byte> dst);
/** Wrapper around fseek(). Will throw if seeking is not possible. */ /** Wrapper around fseek(). Will throw if seeking is not possible. */
void seek(int64_t offset, int origin); void seek(int64_t offset, int origin);
@ -448,9 +448,9 @@ public:
// //
// Stream subset // Stream subset
// //
void read(Span<std::byte> dst); void read(std::span<std::byte> dst);
void ignore(size_t nSize); void ignore(size_t nSize);
void write(Span<const std::byte> src); void write(std::span<const std::byte> src);
template <typename T> template <typename T>
AutoFile& operator<<(const T& obj) AutoFile& operator<<(const T& obj)
@ -492,7 +492,7 @@ private:
readNow = nAvail; readNow = nAvail;
if (readNow == 0) if (readNow == 0)
return false; return false;
size_t nBytes{m_src.detail_fread(Span{vchBuf}.subspan(pos, readNow))}; size_t nBytes{m_src.detail_fread(std::span{vchBuf}.subspan(pos, readNow))};
if (nBytes == 0) { if (nBytes == 0) {
throw std::ios_base::failure{m_src.feof() ? "BufferedFile::Fill: end of file" : "BufferedFile::Fill: fread failed"}; throw std::ios_base::failure{m_src.feof() ? "BufferedFile::Fill: end of file" : "BufferedFile::Fill: fread failed"};
} }
@ -536,7 +536,7 @@ public:
} }
//! read a number of bytes //! read a number of bytes
void read(Span<std::byte> dst) void read(std::span<std::byte> dst)
{ {
while (dst.size() > 0) { while (dst.size() > 0) {
auto [buffer_pointer, length]{AdvanceStream(dst.size())}; auto [buffer_pointer, length]{AdvanceStream(dst.size())};

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023 The Bitcoin Core developers // Copyright (c) 2023-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -91,7 +91,7 @@ void TestBIP324PacketVector(
BOOST_CHECK(out_ciphertext == ciphertext); BOOST_CHECK(out_ciphertext == ciphertext);
} else { } else {
BOOST_CHECK(ciphertext.size() >= out_ciphertext_endswith.size()); BOOST_CHECK(ciphertext.size() >= out_ciphertext_endswith.size());
BOOST_CHECK(std::ranges::equal(out_ciphertext_endswith, Span{ciphertext}.last(out_ciphertext_endswith.size()))); BOOST_CHECK(std::ranges::equal(out_ciphertext_endswith, std::span{ciphertext}.last(out_ciphertext_endswith.size())));
} }
for (unsigned error = 0; error <= 12; ++error) { for (unsigned error = 0; error <= 12; ++error) {
@ -121,8 +121,8 @@ void TestBIP324PacketVector(
for (uint32_t i = 0; i < dec_idx; ++i) { for (uint32_t i = 0; i < dec_idx; ++i) {
unsigned use_idx = i < in_idx ? i : 0; unsigned use_idx = i < in_idx ? i : 0;
bool dec_ignore{false}; bool dec_ignore{false};
dec_cipher.DecryptLength(Span{dummies[use_idx]}.first(cipher.LENGTH_LEN)); dec_cipher.DecryptLength(std::span{dummies[use_idx]}.first(cipher.LENGTH_LEN));
dec_cipher.Decrypt(Span{dummies[use_idx]}.subspan(cipher.LENGTH_LEN), {}, dec_ignore, {}); dec_cipher.Decrypt(std::span{dummies[use_idx]}.subspan(cipher.LENGTH_LEN), {}, dec_ignore, {});
} }
// Construct copied (and possibly damaged) copy of ciphertext. // Construct copied (and possibly damaged) copy of ciphertext.
@ -147,7 +147,7 @@ void TestBIP324PacketVector(
// Decrypt contents. // Decrypt contents.
std::vector<std::byte> decrypted(dec_len); std::vector<std::byte> decrypted(dec_len);
bool dec_ignore{false}; bool dec_ignore{false};
bool dec_ok = dec_cipher.Decrypt(Span{to_decrypt}.subspan(cipher.LENGTH_LEN), dec_aad, dec_ignore, decrypted); bool dec_ok = dec_cipher.Decrypt(std::span{to_decrypt}.subspan(cipher.LENGTH_LEN), dec_aad, dec_ignore, decrypted);
// Verify result. // Verify result.
BOOST_CHECK(dec_ok == !error); BOOST_CHECK(dec_ok == !error);

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2021 The Bitcoin Core developers // Copyright (c) 2014-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -176,9 +176,9 @@ void TestChaCha20(const std::string &hex_message, const std::string &hexkey, Cha
size_t pos = 0; size_t pos = 0;
for (int j = 0; j < 3; ++j) { for (int j = 0; j < 3; ++j) {
if (!hex_message.empty()) { if (!hex_message.empty()) {
rng.Crypt(Span{m}.subspan(pos, lens[j]), Span{outres}.subspan(pos, lens[j])); rng.Crypt(std::span{m}.subspan(pos, lens[j]), std::span{outres}.subspan(pos, lens[j]));
} else { } else {
rng.Keystream(Span{outres}.subspan(pos, lens[j])); rng.Keystream(std::span{outres}.subspan(pos, lens[j]));
} }
pos += lens[j]; pos += lens[j];
} }
@ -237,7 +237,7 @@ void TestPoly1305(const std::string &hexmessage, const std::string &hexkey, cons
// Test incremental interface // Test incremental interface
for (int splits = 0; splits < 10; ++splits) { for (int splits = 0; splits < 10; ++splits) {
for (int iter = 0; iter < 10; ++iter) { for (int iter = 0; iter < 10; ++iter) {
auto data = Span{m}; auto data = std::span{m};
Poly1305 poly1305{key}; Poly1305 poly1305{key};
for (int chunk = 0; chunk < splits; ++chunk) { for (int chunk = 0; chunk < splits; ++chunk) {
size_t now = m_rng.randrange(data.size() + 1); size_t now = m_rng.randrange(data.size() + 1);
@ -267,7 +267,7 @@ void TestChaCha20Poly1305(const std::string& plain_hex, const std::string& aad_h
if (i == 0) { if (i == 0) {
aead.Encrypt(plain, aad, nonce, cipher); aead.Encrypt(plain, aad, nonce, cipher);
} else { } else {
aead.Encrypt(Span{plain}.first(prefix), Span{plain}.subspan(prefix), aad, nonce, cipher); aead.Encrypt(std::span{plain}.first(prefix), std::span{plain}.subspan(prefix), aad, nonce, cipher);
} }
BOOST_CHECK(cipher == expected_cipher); BOOST_CHECK(cipher == expected_cipher);
@ -277,7 +277,7 @@ void TestChaCha20Poly1305(const std::string& plain_hex, const std::string& aad_h
if (i == 0) { if (i == 0) {
ret = aead.Decrypt(cipher, aad, nonce, decipher); ret = aead.Decrypt(cipher, aad, nonce, decipher);
} else { } else {
ret = aead.Decrypt(cipher, aad, nonce, Span{decipher}.first(prefix), Span{decipher}.subspan(prefix)); ret = aead.Decrypt(cipher, aad, nonce, std::span{decipher}.first(prefix), std::span{decipher}.subspan(prefix));
} }
BOOST_CHECK(ret); BOOST_CHECK(ret);
BOOST_CHECK(decipher == plain); BOOST_CHECK(decipher == plain);
@ -308,21 +308,21 @@ void TestFSChaCha20Poly1305(const std::string& plain_hex, const std::string& aad
// Do msg_idx dummy encryptions to seek to the correct packet. // Do msg_idx dummy encryptions to seek to the correct packet.
FSChaCha20Poly1305 enc_aead{key, 224}; FSChaCha20Poly1305 enc_aead{key, 224};
for (uint64_t i = 0; i < msg_idx; ++i) { for (uint64_t i = 0; i < msg_idx; ++i) {
enc_aead.Encrypt(Span{dummy_tag}.first(0), Span{dummy_tag}.first(0), dummy_tag); enc_aead.Encrypt(std::span{dummy_tag}.first(0), std::span{dummy_tag}.first(0), dummy_tag);
} }
// Invoke single-plain or plain1/plain2 Encrypt. // Invoke single-plain or plain1/plain2 Encrypt.
if (it == 0) { if (it == 0) {
enc_aead.Encrypt(plain, aad, cipher); enc_aead.Encrypt(plain, aad, cipher);
} else { } else {
enc_aead.Encrypt(Span{plain}.first(prefix), Span{plain}.subspan(prefix), aad, cipher); enc_aead.Encrypt(std::span{plain}.first(prefix), std::span{plain}.subspan(prefix), aad, cipher);
} }
BOOST_CHECK(cipher == expected_cipher); BOOST_CHECK(cipher == expected_cipher);
// Do msg_idx dummy decryptions to seek to the correct packet. // Do msg_idx dummy decryptions to seek to the correct packet.
FSChaCha20Poly1305 dec_aead{key, 224}; FSChaCha20Poly1305 dec_aead{key, 224};
for (uint64_t i = 0; i < msg_idx; ++i) { for (uint64_t i = 0; i < msg_idx; ++i) {
dec_aead.Decrypt(dummy_tag, Span{dummy_tag}.first(0), Span{dummy_tag}.first(0)); dec_aead.Decrypt(dummy_tag, std::span{dummy_tag}.first(0), std::span{dummy_tag}.first(0));
} }
// Invoke single-plain or plain1/plain2 Decrypt. // Invoke single-plain or plain1/plain2 Decrypt.
@ -331,7 +331,7 @@ void TestFSChaCha20Poly1305(const std::string& plain_hex, const std::string& aad
if (it == 0) { if (it == 0) {
ret = dec_aead.Decrypt(cipher, aad, decipher); ret = dec_aead.Decrypt(cipher, aad, decipher);
} else { } else {
ret = dec_aead.Decrypt(cipher, aad, Span{decipher}.first(prefix), Span{decipher}.subspan(prefix)); ret = dec_aead.Decrypt(cipher, aad, std::span{decipher}.first(prefix), std::span{decipher}.subspan(prefix));
} }
BOOST_CHECK(ret); BOOST_CHECK(ret);
BOOST_CHECK(decipher == plain); BOOST_CHECK(decipher == plain);
@ -843,9 +843,9 @@ BOOST_AUTO_TEST_CASE(chacha20_midblock)
c20.Keystream(b2); c20.Keystream(b2);
c20.Keystream(b3); c20.Keystream(b3);
BOOST_CHECK(std::ranges::equal(Span{block}.first(5), b1)); BOOST_CHECK(std::ranges::equal(std::span{block}.first(5), b1));
BOOST_CHECK(std::ranges::equal(Span{block}.subspan(5, 7), b2)); BOOST_CHECK(std::ranges::equal(std::span{block}.subspan(5, 7), b2));
BOOST_CHECK(std::ranges::equal(Span{block}.last(52), b3)); BOOST_CHECK(std::ranges::equal(std::span{block}.last(52), b3));
} }
BOOST_AUTO_TEST_CASE(poly1305_testvector) BOOST_AUTO_TEST_CASE(poly1305_testvector)
@ -1103,8 +1103,8 @@ void CryptoTest::TestSHA3_256(const std::string& input, const std::string& outpu
int s1 = m_rng.randrange(in_bytes.size() + 1); int s1 = m_rng.randrange(in_bytes.size() + 1);
int s2 = m_rng.randrange(in_bytes.size() + 1 - s1); int s2 = m_rng.randrange(in_bytes.size() + 1 - s1);
int s3 = in_bytes.size() - s1 - s2; int s3 = in_bytes.size() - s1 - s2;
sha.Write(Span{in_bytes}.first(s1)).Write(Span{in_bytes}.subspan(s1, s2)); sha.Write(std::span{in_bytes}.first(s1)).Write(std::span{in_bytes}.subspan(s1, s2));
sha.Write(Span{in_bytes}.last(s3)).Finalize(out); sha.Write(std::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));
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) 2018-2022 The Bitcoin Core developers // Copyright (c) 2018-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -481,13 +481,13 @@ void CheckInferDescriptor(const std::string& script_hex, const std::string& expe
if (!origin_str.empty()) { if (!origin_str.empty()) {
KeyOriginInfo info; KeyOriginInfo info;
Span<const char> origin_sp{origin_str}; std::span<const char> origin_sp{origin_str};
std::vector<Span<const char>> origin_split = Split(origin_sp, "/"); std::vector<std::span<const char>> origin_split = Split(origin_sp, "/");
std::string fpr_str(origin_split[0].begin(), origin_split[0].end()); std::string fpr_str(origin_split[0].begin(), origin_split[0].end());
auto fpr_bytes = ParseHex(fpr_str); auto fpr_bytes = ParseHex(fpr_str);
std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.fingerprint); std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.fingerprint);
for (size_t i = 1; i < origin_split.size(); ++i) { for (size_t i = 1; i < origin_split.size(); ++i) {
Span<const char> elem = origin_split[i]; std::span<const char> elem = origin_split[i];
bool hardened = false; bool hardened = false;
if (elem.size() > 0) { if (elem.size() > 0) {
const char last = elem[elem.size() - 1]; const char last = elem[elem.size() - 1];

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023 The Bitcoin Core developers // Copyright (c) 2023-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -106,7 +106,7 @@ FUZZ_TARGET(bip324_cipher_roundtrip, .init=Initialize)
} }
// Decrypt length // Decrypt length
uint32_t dec_length = receiver.DecryptLength(Span{ciphertext}.first(initiator.LENGTH_LEN)); uint32_t dec_length = receiver.DecryptLength(std::span{ciphertext}.first(initiator.LENGTH_LEN));
if (!damage) { if (!damage) {
assert(dec_length == length); assert(dec_length == length);
} else { } else {
@ -119,7 +119,7 @@ FUZZ_TARGET(bip324_cipher_roundtrip, .init=Initialize)
// Decrypt // Decrypt
std::vector<std::byte> decrypt(dec_length); std::vector<std::byte> decrypt(dec_length);
bool dec_ignore{false}; bool dec_ignore{false};
bool ok = receiver.Decrypt(Span{ciphertext}.subspan(initiator.LENGTH_LEN), aad, dec_ignore, decrypt); bool ok = receiver.Decrypt(std::span{ciphertext}.subspan(initiator.LENGTH_LEN), aad, dec_ignore, decrypt);
// Decryption *must* fail if the packet was damaged, and succeed if it wasn't. // Decryption *must* fail if the packet was damaged, and succeed if it wasn't.
assert(!ok == damage); assert(!ok == damage);
if (!ok) break; if (!ok) break;

View file

@ -1,4 +1,4 @@
// Copyright (c) 2020-2021 The Bitcoin Core developers // Copyright (c) 2020-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -108,9 +108,9 @@ void ChaCha20SplitFuzz(FuzzedDataProvider& provider)
// This tests that Keystream() has the same behavior as Crypt() applied // This tests that Keystream() has the same behavior as Crypt() applied
// to 0x00 input bytes. // to 0x00 input bytes.
if (UseCrypt || provider.ConsumeBool()) { if (UseCrypt || provider.ConsumeBool()) {
crypt2.Crypt(Span{data2}.subspan(bytes2, now), Span{data2}.subspan(bytes2, now)); crypt2.Crypt(std::span{data2}.subspan(bytes2, now), std::span{data2}.subspan(bytes2, now));
} else { } else {
crypt2.Keystream(Span{data2}.subspan(bytes2, now)); crypt2.Keystream(std::span{data2}.subspan(bytes2, now));
} }
bytes2 += now; bytes2 += now;
if (is_last) break; if (is_last) break;

View file

@ -1,4 +1,4 @@
// Copyright (c) 2020-2021 The Bitcoin Core developers // Copyright (c) 2020-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -18,9 +18,9 @@ constexpr static inline void crypt_till_rekey(FSChaCha20Poly1305& aead, int reke
for (int i = 0; i < rekey_interval; ++i) { for (int i = 0; i < rekey_interval; ++i) {
std::byte dummy_tag[FSChaCha20Poly1305::EXPANSION] = {{}}; std::byte dummy_tag[FSChaCha20Poly1305::EXPANSION] = {{}};
if (encrypt) { if (encrypt) {
aead.Encrypt(Span{dummy_tag}.first(0), Span{dummy_tag}.first(0), dummy_tag); aead.Encrypt(std::span{dummy_tag}.first(0), std::span{dummy_tag}.first(0), dummy_tag);
} else { } else {
aead.Decrypt(dummy_tag, Span{dummy_tag}.first(0), Span{dummy_tag}.first(0)); aead.Decrypt(dummy_tag, std::span{dummy_tag}.first(0), std::span{dummy_tag}.first(0));
} }
} }
} }
@ -62,7 +62,7 @@ FUZZ_TARGET(crypto_aeadchacha20poly1305)
if (use_splits && length > 0) { if (use_splits && length > 0) {
size_t split_index = provider.ConsumeIntegralInRange<size_t>(1, length); size_t split_index = provider.ConsumeIntegralInRange<size_t>(1, length);
aead.Encrypt(Span{plain}.first(split_index), Span{plain}.subspan(split_index), aad, nonce, cipher); aead.Encrypt(std::span{plain}.first(split_index), std::span{plain}.subspan(split_index), aad, nonce, cipher);
} else { } else {
aead.Encrypt(plain, aad, nonce, cipher); aead.Encrypt(plain, aad, nonce, cipher);
} }
@ -102,7 +102,7 @@ FUZZ_TARGET(crypto_aeadchacha20poly1305)
if (use_splits && length > 0) { if (use_splits && length > 0) {
size_t split_index = provider.ConsumeIntegralInRange<size_t>(1, length); size_t split_index = provider.ConsumeIntegralInRange<size_t>(1, length);
ok = aead.Decrypt(cipher, aad, nonce, Span{decrypted_contents}.first(split_index), Span{decrypted_contents}.subspan(split_index)); ok = aead.Decrypt(cipher, aad, nonce, std::span{decrypted_contents}.first(split_index), std::span{decrypted_contents}.subspan(split_index));
} else { } else {
ok = aead.Decrypt(cipher, aad, nonce, decrypted_contents); ok = aead.Decrypt(cipher, aad, nonce, decrypted_contents);
} }
@ -152,7 +152,7 @@ FUZZ_TARGET(crypto_fschacha20poly1305)
crypt_till_rekey(enc_aead, rekey_interval, true); crypt_till_rekey(enc_aead, rekey_interval, true);
if (use_splits && length > 0) { if (use_splits && length > 0) {
size_t split_index = provider.ConsumeIntegralInRange<size_t>(1, length); size_t split_index = provider.ConsumeIntegralInRange<size_t>(1, length);
enc_aead.Encrypt(Span{plain}.first(split_index), Span{plain}.subspan(split_index), aad, cipher); enc_aead.Encrypt(std::span{plain}.first(split_index), std::span{plain}.subspan(split_index), aad, cipher);
} else { } else {
enc_aead.Encrypt(plain, aad, cipher); enc_aead.Encrypt(plain, aad, cipher);
} }
@ -187,7 +187,7 @@ FUZZ_TARGET(crypto_fschacha20poly1305)
crypt_till_rekey(dec_aead, rekey_interval, false); crypt_till_rekey(dec_aead, rekey_interval, false);
if (use_splits && length > 0) { if (use_splits && length > 0) {
size_t split_index = provider.ConsumeIntegralInRange<size_t>(1, length); size_t split_index = provider.ConsumeIntegralInRange<size_t>(1, length);
ok = dec_aead.Decrypt(cipher, aad, Span{decrypted_contents}.first(split_index), Span{decrypted_contents}.subspan(split_index)); ok = dec_aead.Decrypt(cipher, aad, std::span{decrypted_contents}.first(split_index), std::span{decrypted_contents}.subspan(split_index));
} else { } else {
ok = dec_aead.Decrypt(cipher, aad, decrypted_contents); ok = dec_aead.Decrypt(cipher, aad, decrypted_contents);
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023 The Bitcoin Core developers // Copyright (c) 2023-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -17,7 +17,7 @@
namespace { namespace {
/** Takes the pre-computed and topologically-valid chunks and generates a fee diagram which starts at FeeFrac of (0, 0) */ /** Takes the pre-computed and topologically-valid chunks and generates a fee diagram which starts at FeeFrac of (0, 0) */
std::vector<FeeFrac> BuildDiagramFromChunks(const Span<const FeeFrac> chunks) std::vector<FeeFrac> BuildDiagramFromChunks(const std::span<const FeeFrac> chunks)
{ {
std::vector<FeeFrac> diagram; std::vector<FeeFrac> diagram;
diagram.reserve(chunks.size() + 1); diagram.reserve(chunks.size() + 1);
@ -34,7 +34,7 @@ std::vector<FeeFrac> BuildDiagramFromChunks(const Span<const FeeFrac> chunks)
* *
* Fees in diagram cannot exceed 2^32, as the returned evaluation could overflow * Fees in diagram cannot exceed 2^32, as the returned evaluation could overflow
* the FeeFrac::fee field in the result. */ * the FeeFrac::fee field in the result. */
FeeFrac EvaluateDiagram(int32_t size, Span<const FeeFrac> diagram) FeeFrac EvaluateDiagram(int32_t size, std::span<const FeeFrac> diagram)
{ {
assert(diagram.size() > 0); assert(diagram.size() > 0);
unsigned not_above = 0; unsigned not_above = 0;
@ -63,12 +63,12 @@ FeeFrac EvaluateDiagram(int32_t size, Span<const FeeFrac> diagram)
return {point_a.fee * dir_coef.size + dir_coef.fee * (size - point_a.size), dir_coef.size}; return {point_a.fee * dir_coef.size + dir_coef.fee * (size - point_a.size), dir_coef.size};
} }
std::weak_ordering CompareFeeFracWithDiagram(const FeeFrac& ff, Span<const FeeFrac> diagram) std::weak_ordering CompareFeeFracWithDiagram(const FeeFrac& ff, std::span<const FeeFrac> diagram)
{ {
return FeeRateCompare(FeeFrac{ff.fee, 1}, EvaluateDiagram(ff.size, diagram)); return FeeRateCompare(FeeFrac{ff.fee, 1}, EvaluateDiagram(ff.size, diagram));
} }
std::partial_ordering CompareDiagrams(Span<const FeeFrac> dia1, Span<const FeeFrac> dia2) std::partial_ordering CompareDiagrams(std::span<const FeeFrac> dia1, std::span<const FeeFrac> dia2)
{ {
bool all_ge = true; bool all_ge = true;
bool all_le = true; bool all_le = true;

View file

@ -1,4 +1,4 @@
// Copyright (c) 2019-2021 The Bitcoin Core developers // Copyright (c) 2019-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -23,7 +23,7 @@ FUZZ_TARGET(hex)
const std::string random_hex_string(buffer.begin(), buffer.end()); const std::string random_hex_string(buffer.begin(), buffer.end());
const std::vector<unsigned char> data = ParseHex(random_hex_string); const std::vector<unsigned char> data = ParseHex(random_hex_string);
const std::vector<std::byte> bytes{ParseHex<std::byte>(random_hex_string)}; const std::vector<std::byte> bytes{ParseHex<std::byte>(random_hex_string)};
assert(std::ranges::equal(AsBytes(Span{data}), bytes)); assert(std::ranges::equal(std::as_bytes(std::span{data}), bytes));
const std::string hex_data = HexStr(data); const std::string hex_data = HexStr(data);
if (IsHex(random_hex_string)) { if (IsHex(random_hex_string)) {
assert(ToLower(random_hex_string) == hex_data); assert(ToLower(random_hex_string) == hex_data);

View file

@ -1,4 +1,4 @@
// Copyright (c) 2021-2022 The Bitcoin Core developers // Copyright (c) 2021-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -129,7 +129,7 @@ struct ParserContext {
auto it = TEST_DATA.dummy_key_idx_map.find(key); auto it = TEST_DATA.dummy_key_idx_map.find(key);
if (it == TEST_DATA.dummy_key_idx_map.end()) return {}; if (it == TEST_DATA.dummy_key_idx_map.end()) return {};
uint8_t idx = it->second; uint8_t idx = it->second;
return HexStr(Span{&idx, 1}); return HexStr(std::span{&idx, 1});
} }
std::vector<unsigned char> ToPKBytes(const Key& key) const { std::vector<unsigned char> ToPKBytes(const Key& key) const {
@ -290,7 +290,7 @@ const struct CheckerContext: BaseSignatureChecker {
if (it == TEST_DATA.dummy_sigs.end()) return false; if (it == TEST_DATA.dummy_sigs.end()) return false;
return it->second.first == sig; return it->second.first == sig;
} }
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion, bool CheckSchnorrSignature(std::span<const unsigned char> sig, std::span<const unsigned char> pubkey, SigVersion,
ScriptExecutionData&, ScriptError*) const override { ScriptExecutionData&, ScriptError*) const override {
XOnlyPubKey pk{pubkey}; XOnlyPubKey pk{pubkey};
auto it = TEST_DATA.schnorr_sigs.find(pk); auto it = TEST_DATA.schnorr_sigs.find(pk);

View file

@ -1,4 +1,4 @@
// Copyright (c) 2020-2021 The Bitcoin Core developers // Copyright (c) 2020-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -25,7 +25,7 @@ public:
/** Construct an arith_uint6144 from any multiple of 4 bytes in LE notation, /** Construct an arith_uint6144 from any multiple of 4 bytes in LE notation,
* up to 768 bytes. */ * up to 768 bytes. */
arith_uint6144(Span<const uint8_t> bytes) : base_uint{} arith_uint6144(std::span<const uint8_t> bytes) : base_uint{}
{ {
assert(bytes.size() % 4 == 0); assert(bytes.size() % 4 == 0);
assert(bytes.size() <= 768); assert(bytes.size() <= 768);
@ -36,7 +36,7 @@ public:
/** Serialize an arithm_uint6144 to any multiply of 4 bytes in LE notation, /** Serialize an arithm_uint6144 to any multiply of 4 bytes in LE notation,
* on the condition that the represented number fits. */ * on the condition that the represented number fits. */
void Serialize(Span<uint8_t> bytes) { void Serialize(std::span<uint8_t> bytes) {
assert(bytes.size() % 4 == 0); assert(bytes.size() % 4 == 0);
assert(bytes.size() <= 768); assert(bytes.size() <= 768);
for (unsigned i = 0; i * 4 < bytes.size(); ++i) { for (unsigned i = 0; i * 4 < bytes.size(); ++i) {

View file

@ -1,4 +1,4 @@
// Copyright (c) 2019-2022 The Bitcoin Core developers // Copyright (c) 2019-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -72,7 +72,7 @@ FUZZ_TARGET(p2p_transport_serialization, .init = initialize_p2p_transport_serial
} }
mutable_msg_bytes.insert(mutable_msg_bytes.end(), payload_bytes.begin(), payload_bytes.end()); mutable_msg_bytes.insert(mutable_msg_bytes.end(), payload_bytes.begin(), payload_bytes.end());
Span<const uint8_t> msg_bytes{mutable_msg_bytes}; std::span<const uint8_t> msg_bytes{mutable_msg_bytes};
while (msg_bytes.size() > 0) { while (msg_bytes.size() > 0) {
if (!recv_transport.ReceivedBytes(msg_bytes)) { if (!recv_transport.ReceivedBytes(msg_bytes)) {
break; break;
@ -87,7 +87,7 @@ FUZZ_TARGET(p2p_transport_serialization, .init = initialize_p2p_transport_serial
assert(msg.m_time == m_time); assert(msg.m_time == m_time);
std::vector<unsigned char> header; std::vector<unsigned char> header;
auto msg2 = NetMsg::Make(msg.m_type, Span{msg.m_recv}); auto msg2 = NetMsg::Make(msg.m_type, std::span{msg.m_recv});
bool queued = send_transport.SetMessageToSend(msg2); bool queued = send_transport.SetMessageToSend(msg2);
assert(queued); assert(queued);
std::optional<bool> known_more; std::optional<bool> known_more;
@ -191,7 +191,7 @@ void SimulationTest(Transport& initiator, Transport& responder, R& rng, FuzzedDa
if (more_nonext) assert(more_next); if (more_nonext) assert(more_next);
// Compare with previously reported output. // Compare with previously reported output.
assert(to_send[side].size() <= bytes.size()); assert(to_send[side].size() <= bytes.size());
assert(std::ranges::equal(to_send[side], Span{bytes}.first(to_send[side].size()))); assert(std::ranges::equal(to_send[side], std::span{bytes}.first(to_send[side].size())));
to_send[side].resize(bytes.size()); to_send[side].resize(bytes.size());
std::copy(bytes.begin(), bytes.end(), to_send[side].begin()); std::copy(bytes.begin(), bytes.end(), to_send[side].begin());
// Remember 'more' results. // Remember 'more' results.
@ -252,7 +252,7 @@ void SimulationTest(Transport& initiator, Transport& responder, R& rng, FuzzedDa
// Decide span to receive // Decide span to receive
size_t to_recv_len = in_flight[side].size(); size_t to_recv_len = in_flight[side].size();
if (!everything) to_recv_len = provider.ConsumeIntegralInRange<size_t>(0, to_recv_len); if (!everything) to_recv_len = provider.ConsumeIntegralInRange<size_t>(0, to_recv_len);
Span<const uint8_t> to_recv = Span{in_flight[side]}.first(to_recv_len); std::span<const uint8_t> to_recv = std::span{in_flight[side]}.first(to_recv_len);
// Process those bytes // Process those bytes
while (!to_recv.empty()) { while (!to_recv.empty()) {
size_t old_len = to_recv.size(); size_t old_len = to_recv.size();

View file

@ -1,4 +1,4 @@
// Copyright (c) 2022 The Bitcoin Core developers // Copyright (c) 2022-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -25,11 +25,11 @@ class PoolResourceFuzzer
size_t m_total_allocated{}; size_t m_total_allocated{};
struct Entry { struct Entry {
Span<std::byte> span; std::span<std::byte> span;
size_t alignment; size_t alignment;
uint64_t seed; uint64_t seed;
Entry(Span<std::byte> s, size_t a, uint64_t se) : span(s), alignment(a), seed(se) {} Entry(std::span<std::byte> s, size_t a, uint64_t se) : span(s), alignment(a), seed(se) {}
}; };
std::vector<Entry> m_entries; std::vector<Entry> m_entries;
@ -48,7 +48,7 @@ public:
assert((alignment & (alignment - 1)) == 0); // Alignment must be power of 2. assert((alignment & (alignment - 1)) == 0); // Alignment must be power of 2.
assert((size & (alignment - 1)) == 0); // Size must be a multiple of alignment. assert((size & (alignment - 1)) == 0); // Size must be a multiple of alignment.
auto span = Span(static_cast<std::byte*>(m_test_resource.Allocate(size, alignment)), size); auto span = std::span(static_cast<std::byte*>(m_test_resource.Allocate(size, alignment)), size);
m_total_allocated += size; m_total_allocated += size;
auto ptr_val = reinterpret_cast<std::uintptr_t>(span.data()); auto ptr_val = reinterpret_cast<std::uintptr_t>(span.data());

View file

@ -1,4 +1,4 @@
// Copyright (c) 2019-2020 The Bitcoin Core developers // Copyright (c) 2019-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -15,9 +15,9 @@ FUZZ_TARGET(script_parsing)
const size_t query_size = fuzzed_data_provider.ConsumeIntegral<size_t>(); const size_t query_size = fuzzed_data_provider.ConsumeIntegral<size_t>();
const std::string query = fuzzed_data_provider.ConsumeBytesAsString(std::min<size_t>(query_size, 1024 * 1024)); const std::string query = fuzzed_data_provider.ConsumeBytesAsString(std::min<size_t>(query_size, 1024 * 1024));
const std::string span_str = fuzzed_data_provider.ConsumeRemainingBytesAsString(); const std::string span_str = fuzzed_data_provider.ConsumeRemainingBytesAsString();
const Span<const char> const_span{span_str}; const std::span<const char> const_span{span_str};
Span<const char> mut_span = const_span; std::span<const char> mut_span = const_span;
(void)script::Const(query, mut_span); (void)script::Const(query, mut_span);
mut_span = const_span; mut_span = const_span;

View file

@ -1,4 +1,4 @@
// Copyright (c) 2009-2022 The Bitcoin Core developers // Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -29,7 +29,7 @@ public:
return m_fuzzed_data_provider.ConsumeBool(); return m_fuzzed_data_provider.ConsumeBool();
} }
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override bool CheckSchnorrSignature(std::span<const unsigned char> sig, std::span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override
{ {
return m_fuzzed_data_provider.ConsumeBool(); return m_fuzzed_data_provider.ConsumeBool();
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) 2020 The Bitcoin Core developers // Copyright (c) 2020-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -18,7 +18,7 @@ FUZZ_TARGET(span)
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
std::string str = fuzzed_data_provider.ConsumeBytesAsString(32); std::string str = fuzzed_data_provider.ConsumeBytesAsString(32);
const Span<const char> span{str}; const std::span<const char> span{str};
(void)span.data(); (void)span.data();
(void)span.begin(); (void)span.begin();
(void)span.end(); (void)span.end();

View file

@ -13,7 +13,7 @@
#include <memory> #include <memory>
std::vector<uint8_t> ConstructPubKeyBytes(FuzzedDataProvider& fuzzed_data_provider, Span<const uint8_t> byte_data, const bool compressed) noexcept std::vector<uint8_t> ConstructPubKeyBytes(FuzzedDataProvider& fuzzed_data_provider, std::span<const uint8_t> byte_data, const bool compressed) noexcept
{ {
uint8_t pk_type; uint8_t pk_type;
if (compressed) { if (compressed) {

View file

@ -87,7 +87,7 @@ void utxo_snapshot_fuzz(FuzzBufferType buffer)
// Metadata // Metadata
if (fuzzed_data_provider.ConsumeBool()) { if (fuzzed_data_provider.ConsumeBool()) {
std::vector<uint8_t> metadata{ConsumeRandomLengthByteVector(fuzzed_data_provider)}; std::vector<uint8_t> metadata{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
outfile << Span{metadata}; outfile << std::span{metadata};
} else { } else {
auto msg_start = chainman.GetParams().MessageStart(); auto msg_start = chainman.GetParams().MessageStart();
int base_blockheight{fuzzed_data_provider.ConsumeIntegralInRange<int>(1, 2 * COINBASE_MATURITY)}; int base_blockheight{fuzzed_data_provider.ConsumeIntegralInRange<int>(1, 2 * COINBASE_MATURITY)};
@ -99,7 +99,7 @@ void utxo_snapshot_fuzz(FuzzBufferType buffer)
// Coins // Coins
if (fuzzed_data_provider.ConsumeBool()) { if (fuzzed_data_provider.ConsumeBool()) {
std::vector<uint8_t> file_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)}; std::vector<uint8_t> file_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
outfile << Span{file_data}; outfile << std::span{file_data};
} else { } else {
int height{0}; int height{0};
for (const auto& block : *g_chain) { for (const auto& block : *g_chain) {

View file

@ -24,7 +24,7 @@ static constexpr size_t MAX_OPERATIONS{1024};
* T must be constructible from a uint64_t seed, comparable to other T, copyable, and movable. * T must be constructible from a uint64_t seed, comparable to other T, copyable, and movable.
*/ */
template<typename T, bool CheckNoneLeft> template<typename T, bool CheckNoneLeft>
void TestType(Span<const uint8_t> buffer, uint64_t rng_tweak) void TestType(std::span<const uint8_t> buffer, uint64_t rng_tweak)
{ {
FuzzedDataProvider provider(buffer.data(), buffer.size()); FuzzedDataProvider provider(buffer.data(), buffer.size());
// Local RNG, only used for the seeds to initialize T objects with. // Local RNG, only used for the seeds to initialize T objects with.

View file

@ -1,4 +1,4 @@
// Copyright (c) 2013-2021 The Bitcoin Core developers // Copyright (c) 2013-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -111,7 +111,7 @@ BOOST_AUTO_TEST_CASE(siphash)
for (uint8_t x=0; x<std::size(siphash_4_2_testvec); ++x) for (uint8_t x=0; x<std::size(siphash_4_2_testvec); ++x)
{ {
BOOST_CHECK_EQUAL(hasher2.Finalize(), siphash_4_2_testvec[x]); BOOST_CHECK_EQUAL(hasher2.Finalize(), siphash_4_2_testvec[x]);
hasher2.Write(Span{&x, 1}); hasher2.Write(std::span{&x, 1});
} }
// Check test vectors from spec, eight bytes at a time // Check test vectors from spec, eight bytes at a time
CSipHasher hasher3(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL); CSipHasher hasher3(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL);

View file

@ -1,4 +1,4 @@
// Copyright (c) 2012-2022 The Bitcoin Core developers // Copyright (c) 2012-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -341,7 +341,7 @@ BOOST_AUTO_TEST_CASE(key_ellswift)
BOOST_CHECK(key.IsValid()); BOOST_CHECK(key.IsValid());
uint256 ent32 = m_rng.rand256(); uint256 ent32 = m_rng.rand256();
auto ellswift = key.EllSwiftCreate(AsBytes(Span{ent32})); auto ellswift = key.EllSwiftCreate(std::as_bytes(std::span{ent32}));
CPubKey decoded_pubkey = ellswift.Decode(); CPubKey decoded_pubkey = ellswift.Decode();
if (!key.IsCompressed()) { if (!key.IsCompressed()) {

View file

@ -1,4 +1,4 @@
// Copyright (c) 2019-2022 The Bitcoin Core developers // Copyright (c) 2019-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -272,7 +272,7 @@ public:
return sig == it->second; return sig == it->second;
} }
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion, bool CheckSchnorrSignature(std::span<const unsigned char> sig, std::span<const unsigned char> pubkey, SigVersion,
ScriptExecutionData&, ScriptError*) const override { ScriptExecutionData&, ScriptError*) const override {
XOnlyPubKey pk{pubkey}; XOnlyPubKey pk{pubkey};
auto it = g_testdata->schnorr_signatures.find(pk); auto it = g_testdata->schnorr_signatures.find(pk);

View file

@ -1,4 +1,4 @@
// Copyright (c) 2012-2022 The Bitcoin Core developers // Copyright (c) 2012-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -861,7 +861,7 @@ BOOST_AUTO_TEST_CASE(initial_advertise_from_version_message)
const auto CaptureMessageOrig = CaptureMessage; const auto CaptureMessageOrig = CaptureMessage;
CaptureMessage = [&sent, &expected](const CAddress& addr, CaptureMessage = [&sent, &expected](const CAddress& addr,
const std::string& msg_type, const std::string& msg_type,
Span<const unsigned char> data, std::span<const unsigned char> data,
bool is_incoming) -> void { bool is_incoming) -> void {
if (!is_incoming && msg_type == "addr") { if (!is_incoming && msg_type == "addr") {
DataStream s{data}; DataStream s{data};
@ -1054,7 +1054,7 @@ public:
bool progress{false}; bool progress{false};
// Send bytes from m_to_send to the transport. // Send bytes from m_to_send to the transport.
if (!m_to_send.empty()) { if (!m_to_send.empty()) {
Span<const uint8_t> to_send = Span{m_to_send}.first(1 + m_rng.randrange(m_to_send.size())); std::span<const uint8_t> to_send = std::span{m_to_send}.first(1 + m_rng.randrange(m_to_send.size()));
size_t old_len = to_send.size(); size_t old_len = to_send.size();
if (!m_transport.ReceivedBytes(to_send)) { if (!m_transport.ReceivedBytes(to_send)) {
return std::nullopt; // transport error occurred return std::nullopt; // transport error occurred
@ -1099,7 +1099,7 @@ public:
BIP324Cipher& GetCipher() { return m_cipher; } BIP324Cipher& GetCipher() { return m_cipher; }
/** Schedule bytes to be sent to the transport. */ /** Schedule bytes to be sent to the transport. */
void Send(Span<const uint8_t> data) void Send(std::span<const uint8_t> data)
{ {
m_to_send.insert(m_to_send.end(), data.begin(), data.end()); m_to_send.insert(m_to_send.end(), data.begin(), data.end());
} }
@ -1114,13 +1114,13 @@ public:
} }
/** Schedule bytes to be sent to the transport. */ /** Schedule bytes to be sent to the transport. */
void Send(Span<const std::byte> data) { Send(MakeUCharSpan(data)); } void Send(std::span<const std::byte> data) { Send(MakeUCharSpan(data)); }
/** Schedule our ellswift key to be sent to the transport. */ /** Schedule our ellswift key to be sent to the transport. */
void SendKey() { Send(m_cipher.GetOurPubKey()); } void SendKey() { Send(m_cipher.GetOurPubKey()); }
/** Schedule specified garbage to be sent to the transport. */ /** Schedule specified garbage to be sent to the transport. */
void SendGarbage(Span<const uint8_t> garbage) void SendGarbage(std::span<const uint8_t> garbage)
{ {
// Remember the specified garbage (so we can use it as AAD). // Remember the specified garbage (so we can use it as AAD).
m_sent_garbage.assign(garbage.begin(), garbage.end()); m_sent_garbage.assign(garbage.begin(), garbage.end());
@ -1167,7 +1167,7 @@ public:
/** Schedule an encrypted packet with specified content/aad/ignore to be sent to transport /** Schedule an encrypted packet with specified content/aad/ignore to be sent to transport
* (only after ReceiveKey). */ * (only after ReceiveKey). */
void SendPacket(Span<const uint8_t> content, Span<const uint8_t> aad = {}, bool ignore = false) void SendPacket(std::span<const uint8_t> content, std::span<const uint8_t> aad = {}, bool ignore = false)
{ {
// Use cipher to construct ciphertext. // Use cipher to construct ciphertext.
std::vector<std::byte> ciphertext; std::vector<std::byte> ciphertext;
@ -1189,9 +1189,9 @@ public:
} }
/** Schedule version packet to be sent to the transport (only after ReceiveKey). */ /** Schedule version packet to be sent to the transport (only after ReceiveKey). */
void SendVersion(Span<const uint8_t> version_data = {}, bool vers_ignore = false) void SendVersion(std::span<const uint8_t> version_data = {}, bool vers_ignore = false)
{ {
Span<const std::uint8_t> aad; std::span<const std::uint8_t> aad;
// Set AAD to garbage only for first packet. // Set AAD to garbage only for first packet.
if (!m_sent_aad) aad = m_sent_garbage; if (!m_sent_aad) aad = m_sent_garbage;
SendPacket(/*content=*/version_data, /*aad=*/aad, /*ignore=*/vers_ignore); SendPacket(/*content=*/version_data, /*aad=*/aad, /*ignore=*/vers_ignore);
@ -1201,7 +1201,7 @@ public:
/** Expect a packet to have been received from transport, process it, and return its contents /** Expect a packet to have been received from transport, process it, and return its contents
* (only after ReceiveKey). Decoys are skipped. Optional associated authenticated data (AAD) is * (only after ReceiveKey). Decoys are skipped. Optional associated authenticated data (AAD) is
* expected in the first received packet, no matter if that is a decoy or not. */ * expected in the first received packet, no matter if that is a decoy or not. */
std::vector<uint8_t> ReceivePacket(Span<const std::byte> aad = {}) std::vector<uint8_t> ReceivePacket(std::span<const std::byte> aad = {})
{ {
std::vector<uint8_t> contents; std::vector<uint8_t> contents;
// Loop as long as there are ignored packets that are to be skipped. // Loop as long as there are ignored packets that are to be skipped.
@ -1209,7 +1209,7 @@ public:
// When processing a packet, at least enough bytes for its length descriptor must be received. // When processing a packet, at least enough bytes for its length descriptor must be received.
BOOST_REQUIRE(m_received.size() >= BIP324Cipher::LENGTH_LEN); BOOST_REQUIRE(m_received.size() >= BIP324Cipher::LENGTH_LEN);
// Decrypt the content length. // Decrypt the content length.
size_t size = m_cipher.DecryptLength(MakeByteSpan(Span{m_received}.first(BIP324Cipher::LENGTH_LEN))); size_t size = m_cipher.DecryptLength(MakeByteSpan(std::span{m_received}.first(BIP324Cipher::LENGTH_LEN)));
// Check that the full packet is in the receive buffer. // Check that the full packet is in the receive buffer.
BOOST_REQUIRE(m_received.size() >= size + BIP324Cipher::EXPANSION); BOOST_REQUIRE(m_received.size() >= size + BIP324Cipher::EXPANSION);
// Decrypt the packet contents. // Decrypt the packet contents.
@ -1217,7 +1217,7 @@ public:
bool ignore{false}; bool ignore{false};
bool ret = m_cipher.Decrypt( bool ret = m_cipher.Decrypt(
/*input=*/MakeByteSpan( /*input=*/MakeByteSpan(
Span{m_received}.first(size + BIP324Cipher::EXPANSION).subspan(BIP324Cipher::LENGTH_LEN)), std::span{m_received}.first(size + BIP324Cipher::EXPANSION).subspan(BIP324Cipher::LENGTH_LEN)),
/*aad=*/aad, /*aad=*/aad,
/*ignore=*/ignore, /*ignore=*/ignore,
/*contents=*/MakeWritableByteSpan(contents)); /*contents=*/MakeWritableByteSpan(contents));
@ -1240,7 +1240,7 @@ public:
size_t garblen; size_t garblen;
for (garblen = 0; garblen <= V2Transport::MAX_GARBAGE_LEN; ++garblen) { for (garblen = 0; garblen <= V2Transport::MAX_GARBAGE_LEN; ++garblen) {
BOOST_REQUIRE(m_received.size() >= garblen + BIP324Cipher::GARBAGE_TERMINATOR_LEN); BOOST_REQUIRE(m_received.size() >= garblen + BIP324Cipher::GARBAGE_TERMINATOR_LEN);
auto term_span = MakeByteSpan(Span{m_received}.subspan(garblen, BIP324Cipher::GARBAGE_TERMINATOR_LEN)); auto term_span = MakeByteSpan(std::span{m_received}.subspan(garblen, BIP324Cipher::GARBAGE_TERMINATOR_LEN));
if (std::ranges::equal(term_span, m_cipher.GetReceiveGarbageTerminator())) break; if (std::ranges::equal(term_span, m_cipher.GetReceiveGarbageTerminator())) break;
} }
// Copy the garbage to a buffer. // Copy the garbage to a buffer.
@ -1261,17 +1261,17 @@ public:
/** Expect application packet to have been received, with specified short id and payload. /** Expect application packet to have been received, with specified short id and payload.
* (only after ReceiveKey). */ * (only after ReceiveKey). */
void ReceiveMessage(uint8_t short_id, Span<const uint8_t> payload) void ReceiveMessage(uint8_t short_id, std::span<const uint8_t> payload)
{ {
auto ret = ReceivePacket(); auto ret = ReceivePacket();
BOOST_CHECK(ret.size() == payload.size() + 1); BOOST_CHECK(ret.size() == payload.size() + 1);
BOOST_CHECK(ret[0] == short_id); BOOST_CHECK(ret[0] == short_id);
BOOST_CHECK(std::ranges::equal(Span{ret}.subspan(1), payload)); BOOST_CHECK(std::ranges::equal(std::span{ret}.subspan(1), payload));
} }
/** Expect application packet to have been received, with specified 12-char message type and /** Expect application packet to have been received, with specified 12-char message type and
* payload (only after ReceiveKey). */ * payload (only after ReceiveKey). */
void ReceiveMessage(const std::string& m_type, Span<const uint8_t> payload) void ReceiveMessage(const std::string& m_type, std::span<const uint8_t> payload)
{ {
auto ret = ReceivePacket(); auto ret = ReceivePacket();
BOOST_REQUIRE(ret.size() == payload.size() + 1 + CMessageHeader::MESSAGE_TYPE_SIZE); BOOST_REQUIRE(ret.size() == payload.size() + 1 + CMessageHeader::MESSAGE_TYPE_SIZE);
@ -1283,12 +1283,12 @@ public:
BOOST_CHECK(ret[1 + i] == 0); BOOST_CHECK(ret[1 + i] == 0);
} }
} }
BOOST_CHECK(std::ranges::equal(Span{ret}.subspan(1 + CMessageHeader::MESSAGE_TYPE_SIZE), payload)); BOOST_CHECK(std::ranges::equal(std::span{ret}.subspan(1 + CMessageHeader::MESSAGE_TYPE_SIZE), payload));
} }
/** Schedule an encrypted packet with specified message type and payload to be sent to /** Schedule an encrypted packet with specified message type and payload to be sent to
* transport (only after ReceiveKey). */ * transport (only after ReceiveKey). */
void SendMessage(std::string mtype, Span<const uint8_t> payload) void SendMessage(std::string mtype, std::span<const uint8_t> payload)
{ {
// Construct contents consisting of 0x00 + 12-byte message type + payload. // Construct contents consisting of 0x00 + 12-byte message type + payload.
std::vector<uint8_t> contents(1 + CMessageHeader::MESSAGE_TYPE_SIZE + payload.size()); std::vector<uint8_t> contents(1 + CMessageHeader::MESSAGE_TYPE_SIZE + payload.size());
@ -1300,7 +1300,7 @@ public:
/** Schedule an encrypted packet with specified short message id and payload to be sent to /** Schedule an encrypted packet with specified short message id and payload to be sent to
* transport (only after ReceiveKey). */ * transport (only after ReceiveKey). */
void SendMessage(uint8_t short_id, Span<const uint8_t> payload) void SendMessage(uint8_t short_id, std::span<const uint8_t> payload)
{ {
// Construct contents consisting of short_id + payload. // Construct contents consisting of short_id + payload.
std::vector<uint8_t> contents(1 + payload.size()); std::vector<uint8_t> contents(1 + payload.size());

View file

@ -1,4 +1,4 @@
// Copyright (c) 2024 The Bitcoin Core developers // Copyright (c) 2024-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -101,7 +101,7 @@ public:
ssize_t Send(const void* data, size_t len, int) const override { ssize_t Send(const void* data, size_t len, int) const override {
if (!m_connected) return -1; if (!m_connected) return -1;
Span in_pkt = Span(static_cast<const uint8_t*>(data), len); std::span in_pkt = std::span(static_cast<const uint8_t*>(data), len);
if (AtEndOfScript() || CurOp().op != TestOp::SEND) { if (AtEndOfScript() || CurOp().op != TestOp::SEND) {
// Ignore sends after end of script, or sends when we expect a receive. // Ignore sends after end of script, or sends when we expect a receive.
FailScript(); FailScript();

View file

@ -1,4 +1,4 @@
// Copyright (c) 2022 The Bitcoin Core developers // Copyright (c) 2022-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(allocate_any_byte)
uint8_t num_allocs = 200; uint8_t num_allocs = 200;
auto data = std::vector<Span<uint8_t>>(); auto data = std::vector<std::span<uint8_t>>();
// allocate an increasing number of bytes // allocate an increasing number of bytes
for (uint8_t num_bytes = 0; num_bytes < num_allocs; ++num_bytes) { for (uint8_t num_bytes = 0; num_bytes < num_allocs; ++num_bytes) {

View file

@ -1,4 +1,4 @@
// Copyright (c) 2011-2022 The Bitcoin Core developers // Copyright (c) 2011-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -258,7 +258,7 @@ public:
CScript scriptPubKey = script; CScript scriptPubKey = script;
if (wm == WitnessMode::PKH) { if (wm == WitnessMode::PKH) {
uint160 hash; uint160 hash;
CHash160().Write(Span{script}.subspan(1)).Finalize(hash); CHash160().Write(std::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) {
@ -1719,8 +1719,8 @@ BOOST_AUTO_TEST_CASE(compute_tapleaf)
constexpr uint256 tlc0{"edbc10c272a1215dcdcc11d605b9027b5ad6ed97cd45521203f136767b5b9c06"}; constexpr uint256 tlc0{"edbc10c272a1215dcdcc11d605b9027b5ad6ed97cd45521203f136767b5b9c06"};
constexpr uint256 tlc2{"8b5c4f90ae6bf76e259dbef5d8a59df06359c391b59263741b25eca76451b27a"}; constexpr uint256 tlc2{"8b5c4f90ae6bf76e259dbef5d8a59df06359c391b59263741b25eca76451b27a"};
BOOST_CHECK_EQUAL(ComputeTapleafHash(0xc0, Span(script)), tlc0); BOOST_CHECK_EQUAL(ComputeTapleafHash(0xc0, std::span(script)), tlc0);
BOOST_CHECK_EQUAL(ComputeTapleafHash(0xc2, Span(script)), tlc2); BOOST_CHECK_EQUAL(ComputeTapleafHash(0xc2, std::span(script)), tlc2);
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View file

@ -1,4 +1,4 @@
// Copyright (c) 2012-2022 The Bitcoin Core developers // Copyright (c) 2012-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -211,32 +211,32 @@ BOOST_AUTO_TEST_CASE(noncanonical)
std::vector<char>::size_type n; std::vector<char>::size_type n;
// zero encoded with three bytes: // zero encoded with three bytes:
ss << Span{"\xfd\x00\x00"}.first(3); ss << std::span{"\xfd\x00\x00"}.first(3);
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
// 0xfc encoded with three bytes: // 0xfc encoded with three bytes:
ss << Span{"\xfd\xfc\x00"}.first(3); ss << std::span{"\xfd\xfc\x00"}.first(3);
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
// 0xfd encoded with three bytes is OK: // 0xfd encoded with three bytes is OK:
ss << Span{"\xfd\xfd\x00"}.first(3); ss << std::span{"\xfd\xfd\x00"}.first(3);
n = ReadCompactSize(ss); n = ReadCompactSize(ss);
BOOST_CHECK(n == 0xfd); BOOST_CHECK(n == 0xfd);
// zero encoded with five bytes: // zero encoded with five bytes:
ss << Span{"\xfe\x00\x00\x00\x00"}.first(5); ss << std::span{"\xfe\x00\x00\x00\x00"}.first(5);
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
// 0xffff encoded with five bytes: // 0xffff encoded with five bytes:
ss << Span{"\xfe\xff\xff\x00\x00"}.first(5); ss << std::span{"\xfe\xff\xff\x00\x00"}.first(5);
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
// zero encoded with nine bytes: // zero encoded with nine bytes:
ss << Span{"\xff\x00\x00\x00\x00\x00\x00\x00\x00"}.first(9); ss << std::span{"\xff\x00\x00\x00\x00\x00\x00\x00\x00"}.first(9);
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
// 0x01ffffff encoded with nine bytes: // 0x01ffffff encoded with nine bytes:
ss << Span{"\xff\xff\xff\xff\x01\x00\x00\x00\x00"}.first(9); ss << std::span{"\xff\xff\xff\xff\x01\x00\x00\x00\x00"}.first(9);
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
} }
@ -269,10 +269,10 @@ BOOST_AUTO_TEST_CASE(class_methods)
{ {
DataStream ds; DataStream ds;
const std::string in{"ab"}; const std::string in{"ab"};
ds << Span{in} << std::byte{'c'}; ds << std::span{in} << std::byte{'c'};
std::array<std::byte, 2> out; std::array<std::byte, 2> out;
std::byte out_3; std::byte out_3;
ds >> Span{out} >> out_3; ds >> std::span{out} >> out_3;
BOOST_CHECK_EQUAL(out.at(0), std::byte{'a'}); BOOST_CHECK_EQUAL(out.at(0), std::byte{'a'});
BOOST_CHECK_EQUAL(out.at(1), std::byte{'b'}); BOOST_CHECK_EQUAL(out.at(1), std::byte{'b'});
BOOST_CHECK_EQUAL(out_3, std::byte{'c'}); BOOST_CHECK_EQUAL(out_3, std::byte{'c'});
@ -304,7 +304,7 @@ public:
if (s.template GetParams<BaseFormat>().m_base_format == BaseFormat::RAW) { if (s.template GetParams<BaseFormat>().m_base_format == BaseFormat::RAW) {
s << m_base_data; s << m_base_data;
} else { } else {
s << std::span<const char>{HexStr(Span{&m_base_data, 1})}; s << std::span<const char>{HexStr(std::span{&m_base_data, 1})};
} }
} }
@ -315,7 +315,7 @@ public:
s >> m_base_data; s >> m_base_data;
} else { } else {
std::string hex{"aa"}; std::string hex{"aa"};
s >> Span{hex}.first(hex.size()); s >> std::span{hex}.first(hex.size());
m_base_data = TryParseHex<uint8_t>(hex).value().at(0); m_base_data = TryParseHex<uint8_t>(hex).value().at(0);
} }
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023 The Bitcoin Core developers // Copyright (c) 2023-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -9,13 +9,13 @@
#include <set> #include <set>
#include <vector> #include <vector>
namespace { namespace spannable {
struct Ignore struct Ignore
{ {
template<typename T> Ignore(T&&) {} template<typename T> Ignore(T&&) {}
}; };
template<typename T> template<typename T>
bool Spannable(T&& value, decltype(Span{value})* enable = nullptr) bool Spannable(T&& value, decltype(std::span{value})* enable = nullptr)
{ {
return true; return true;
} }
@ -24,47 +24,36 @@ bool Spannable(Ignore)
return false; return false;
} }
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunneeded-member-function"
# pragma clang diagnostic ignored "-Wunused-member-function"
#endif
struct SpannableYes struct SpannableYes
{ {
int* data(); int* data();
int* begin();
int* end();
size_t size(); size_t size();
}; };
struct SpannableNo struct SpannableNo
{ {
void* data(); void data();
size_t size(); size_t size();
}; };
#if defined(__clang__) } // namespace spannable
# pragma clang diagnostic pop
#endif using namespace spannable;
} // namespace
BOOST_AUTO_TEST_SUITE(span_tests) BOOST_AUTO_TEST_SUITE(span_tests)
// Make sure template Span template deduction guides accurately enable calls to // Make sure template std::span template deduction guides accurately enable calls to
// Span constructor overloads that work, and disable calls to constructor overloads that // std::span constructor overloads that work, and disable calls to constructor overloads that
// don't work. This makes it is possible to use the Span constructor in a SFINAE // don't work. This makes it possible to use the std::span constructor in a SFINAE
// contexts like in the Spannable function above to detect whether types are or // contexts like in the Spannable function above to detect whether types are or
// aren't compatible with Spans at compile time. // aren't compatible with std::span at compile time.
//
// Previously there was a bug where writing a SFINAE check for vector<bool> was
// not possible, because in libstdc++ vector<bool> has a data() member
// returning void*, and the Span template guide ignored the data() return value,
// so the template substitution would succeed, but the constructor would fail,
// resulting in a fatal compile error, rather than a SFINAE error that could be
// handled.
BOOST_AUTO_TEST_CASE(span_constructor_sfinae) BOOST_AUTO_TEST_CASE(span_constructor_sfinae)
{ {
BOOST_CHECK(Spannable(std::vector<int>{})); BOOST_CHECK(Spannable(std::vector<int>{}));
BOOST_CHECK(!Spannable(std::set<int>{})); BOOST_CHECK(!Spannable(std::set<int>{}));
BOOST_CHECK(!Spannable(std::vector<bool>{})); BOOST_CHECK(!Spannable(std::vector<bool>{}));
BOOST_CHECK(Spannable(std::array<int, 3>{})); BOOST_CHECK(Spannable(std::array<int, 3>{}));
BOOST_CHECK(Spannable(Span<int>{})); BOOST_CHECK(Spannable(std::span<int>{}));
BOOST_CHECK(Spannable("char array")); BOOST_CHECK(Spannable("char array"));
BOOST_CHECK(Spannable(SpannableYes{})); BOOST_CHECK(Spannable(SpannableYes{}));
BOOST_CHECK(!Spannable(SpannableNo{})); BOOST_CHECK(!Spannable(SpannableNo{}));

View file

@ -1,4 +1,4 @@
// Copyright (c) 2012-2022 The Bitcoin Core developers // Copyright (c) 2012-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -42,7 +42,7 @@ BOOST_AUTO_TEST_CASE(xor_file)
// Read raw from disk // Read raw from disk
AutoFile non_xor_file{raw_file("rb")}; AutoFile non_xor_file{raw_file("rb")};
std::vector<std::byte> raw(7); std::vector<std::byte> raw(7);
non_xor_file >> Span{raw}; non_xor_file >> std::span{raw};
BOOST_CHECK_EQUAL(HexStr(raw), "fc01fd03fd04fa"); BOOST_CHECK_EQUAL(HexStr(raw), "fc01fd03fd04fa");
// Check that no padding exists // Check that no padding exists
BOOST_CHECK_EXCEPTION(non_xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: end of file"}); BOOST_CHECK_EXCEPTION(non_xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: end of file"});

View file

@ -392,7 +392,7 @@ void SanityCheck(const DepGraph<SetType>& depgraph)
/** Perform a sanity check on a linearization. */ /** Perform a sanity check on a linearization. */
template<typename SetType> template<typename SetType>
void SanityCheck(const DepGraph<SetType>& depgraph, Span<const ClusterIndex> linearization) void SanityCheck(const DepGraph<SetType>& depgraph, std::span<const ClusterIndex> linearization)
{ {
// Check completeness. // Check completeness.
assert(linearization.size() == depgraph.TxCount()); assert(linearization.size() == depgraph.TxCount());

View file

@ -1,4 +1,4 @@
// Copyright (c) 2020-2022 The Bitcoin Core developers // Copyright (c) 2020-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -71,7 +71,7 @@ void ConnmanTestMsg::Handshake(CNode& node,
} }
} }
void ConnmanTestMsg::NodeReceiveMsgBytes(CNode& node, Span<const uint8_t> msg_bytes, bool& complete) const void ConnmanTestMsg::NodeReceiveMsgBytes(CNode& node, std::span<const uint8_t> msg_bytes, bool& complete) const
{ {
assert(node.ReceiveMsgBytes(msg_bytes, complete)); assert(node.ReceiveMsgBytes(msg_bytes, complete));
if (complete) { if (complete) {
@ -279,7 +279,7 @@ std::optional<CNetMessage> DynSock::Pipe::GetNetMsg()
} }
for (;;) { for (;;) {
Span<const uint8_t> s{m_data}; std::span<const uint8_t> s{m_data};
if (!transport.ReceivedBytes(s)) { // Consumed bytes are removed from the front of s. if (!transport.ReceivedBytes(s)) { // Consumed bytes are removed from the front of s.
return std::nullopt; return std::nullopt;
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) 2020-2022 The Bitcoin Core developers // Copyright (c) 2020-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -81,7 +81,7 @@ struct ConnmanTestMsg : public CConnman {
return m_msgproc->ProcessMessages(&node, flagInterruptMsgProc); return m_msgproc->ProcessMessages(&node, flagInterruptMsgProc);
} }
void NodeReceiveMsgBytes(CNode& node, Span<const uint8_t> msg_bytes, bool& complete) const; void NodeReceiveMsgBytes(CNode& node, std::span<const uint8_t> msg_bytes, bool& complete) const;
bool ReceiveMsgFrom(CNode& node, CSerializedNetMsg&& ser_msg) const; bool ReceiveMsgFrom(CNode& node, CSerializedNetMsg&& ser_msg) const;
void FlushSendBuffer(CNode& node) const; void FlushSendBuffer(CNode& node) const;

View file

@ -160,8 +160,8 @@ BOOST_AUTO_TEST_CASE(parse_hex)
BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_span.begin(), hex_literal_span.end(), expected.begin(), expected.end()); BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_span.begin(), hex_literal_span.end(), expected.begin(), expected.end());
const std::vector<std::byte> hex_literal_vector{operator""_hex_v<util::detail::Hex(HEX_PARSE_INPUT)>()}; const std::vector<std::byte> hex_literal_vector{operator""_hex_v<util::detail::Hex(HEX_PARSE_INPUT)>()};
hex_literal_span = MakeUCharSpan(hex_literal_vector); auto hex_literal_vec_span = MakeUCharSpan(hex_literal_vector);
BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_span.begin(), hex_literal_span.end(), expected.begin(), expected.end()); BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_vec_span.begin(), hex_literal_vec_span.end(), expected.begin(), expected.end());
constexpr std::array<uint8_t, 65> hex_literal_array_uint8{operator""_hex_u8<util::detail::Hex(HEX_PARSE_INPUT)>()}; constexpr std::array<uint8_t, 65> hex_literal_array_uint8{operator""_hex_u8<util::detail::Hex(HEX_PARSE_INPUT)>()};
BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_array_uint8.begin(), hex_literal_array_uint8.end(), expected.begin(), expected.end()); BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_array_uint8.begin(), hex_literal_array_uint8.end(), expected.begin(), expected.end());
@ -236,14 +236,14 @@ BOOST_AUTO_TEST_CASE(consteval_hex_digit)
BOOST_AUTO_TEST_CASE(util_HexStr) BOOST_AUTO_TEST_CASE(util_HexStr)
{ {
BOOST_CHECK_EQUAL(HexStr(HEX_PARSE_OUTPUT), HEX_PARSE_INPUT); BOOST_CHECK_EQUAL(HexStr(HEX_PARSE_OUTPUT), HEX_PARSE_INPUT);
BOOST_CHECK_EQUAL(HexStr(Span{HEX_PARSE_OUTPUT}.last(0)), ""); BOOST_CHECK_EQUAL(HexStr(std::span{HEX_PARSE_OUTPUT}.last(0)), "");
BOOST_CHECK_EQUAL(HexStr(Span{HEX_PARSE_OUTPUT}.first(0)), ""); BOOST_CHECK_EQUAL(HexStr(std::span{HEX_PARSE_OUTPUT}.first(0)), "");
{ {
constexpr std::string_view out_exp{"04678afdb0"}; constexpr std::string_view out_exp{"04678afdb0"};
constexpr std::span in_s{HEX_PARSE_OUTPUT, out_exp.size() / 2}; constexpr std::span in_s{HEX_PARSE_OUTPUT, out_exp.size() / 2};
const Span<const uint8_t> in_u{MakeUCharSpan(in_s)}; const std::span<const uint8_t> in_u{MakeUCharSpan(in_s)};
const Span<const std::byte> in_b{MakeByteSpan(in_s)}; const std::span<const std::byte> in_b{MakeByteSpan(in_s)};
BOOST_CHECK_EQUAL(HexStr(in_u), out_exp); BOOST_CHECK_EQUAL(HexStr(in_u), out_exp);
BOOST_CHECK_EQUAL(HexStr(in_s), out_exp); BOOST_CHECK_EQUAL(HexStr(in_s), out_exp);
@ -1335,7 +1335,7 @@ BOOST_AUTO_TEST_CASE(test_Capitalize)
BOOST_CHECK_EQUAL(Capitalize("\x00\xfe\xff"), "\x00\xfe\xff"); BOOST_CHECK_EQUAL(Capitalize("\x00\xfe\xff"), "\x00\xfe\xff");
} }
static std::string SpanToStr(const Span<const char>& span) static std::string SpanToStr(const std::span<const char>& span)
{ {
return std::string(span.begin(), span.end()); return std::string(span.begin(), span.end());
} }
@ -1344,7 +1344,7 @@ BOOST_AUTO_TEST_CASE(test_script_parsing)
{ {
using namespace script; using namespace script;
std::string input; std::string input;
Span<const char> sp; std::span<const char> sp;
bool success; bool success;
// Const(...): parse a constant, update span to skip it if successful // Const(...): parse a constant, update span to skip it if successful
@ -1394,7 +1394,7 @@ BOOST_AUTO_TEST_CASE(test_script_parsing)
BOOST_CHECK(!success); BOOST_CHECK(!success);
// Expr(...): return expression that span begins with, update span to skip it // Expr(...): return expression that span begins with, update span to skip it
Span<const char> result; std::span<const char> result;
input = "(n*(n-1))/2"; input = "(n*(n-1))/2";
sp = input; sp = input;
@ -1427,7 +1427,7 @@ BOOST_AUTO_TEST_CASE(test_script_parsing)
BOOST_CHECK_EQUAL(SpanToStr(sp), ",xxx"); BOOST_CHECK_EQUAL(SpanToStr(sp), ",xxx");
// Split(...): split a string on every instance of sep, return vector // Split(...): split a string on every instance of sep, return vector
std::vector<Span<const char>> results; std::vector<std::span<const char>> results;
input = "xxx"; input = "xxx";
results = Split(input, 'x'); results = Split(input, 'x');

View file

@ -37,7 +37,7 @@ public:
/* constructor for constants between 1 and 255 */ /* constructor for constants between 1 and 255 */
constexpr explicit base_blob(uint8_t v) : m_data{v} {} constexpr explicit base_blob(uint8_t v) : m_data{v} {}
constexpr explicit base_blob(Span<const unsigned char> vch) constexpr explicit base_blob(std::span<const unsigned char> vch)
{ {
assert(vch.size() == WIDTH); assert(vch.size() == WIDTH);
std::copy(vch.begin(), vch.end(), m_data.begin()); std::copy(vch.begin(), vch.end(), m_data.begin());
@ -125,7 +125,7 @@ public:
template<typename Stream> template<typename Stream>
void Serialize(Stream& s) const void Serialize(Stream& s) const
{ {
s << Span(m_data); s << std::span(m_data);
} }
template<typename Stream> template<typename Stream>
@ -190,7 +190,7 @@ class uint160 : public base_blob<160> {
public: public:
static std::optional<uint160> FromHex(std::string_view str) { return detail::FromHex<uint160>(str); } static std::optional<uint160> FromHex(std::string_view str) { return detail::FromHex<uint160>(str); }
constexpr uint160() = default; constexpr uint160() = default;
constexpr explicit uint160(Span<const unsigned char> vch) : base_blob<160>(vch) {} constexpr explicit uint160(std::span<const unsigned char> vch) : base_blob<160>(vch) {}
}; };
/** 256-bit opaque blob. /** 256-bit opaque blob.
@ -205,7 +205,7 @@ public:
constexpr uint256() = default; constexpr uint256() = default;
consteval explicit uint256(std::string_view hex_str) : base_blob<256>(hex_str) {} consteval explicit uint256(std::string_view hex_str) : base_blob<256>(hex_str) {}
constexpr explicit uint256(uint8_t v) : base_blob<256>(v) {} constexpr explicit uint256(uint8_t v) : base_blob<256>(v) {}
constexpr explicit uint256(Span<const unsigned char> vch) : base_blob<256>(vch) {} constexpr explicit uint256(std::span<const unsigned char> vch) : base_blob<256>(vch) {}
static const uint256 ZERO; static const uint256 ZERO;
static const uint256 ONE; static const uint256 ONE;
}; };

View file

@ -7,10 +7,10 @@
#include <array> #include <array>
#include <vector> #include <vector>
std::partial_ordering CompareChunks(Span<const FeeFrac> chunks0, Span<const FeeFrac> chunks1) std::partial_ordering CompareChunks(std::span<const FeeFrac> chunks0, std::span<const FeeFrac> chunks1)
{ {
/** Array to allow indexed access to input diagrams. */ /** Array to allow indexed access to input diagrams. */
const std::array<Span<const FeeFrac>, 2> chunk = {chunks0, chunks1}; const std::array<std::span<const FeeFrac>, 2> chunk = {chunks0, chunks1};
/** How many elements we have processed in each input. */ /** How many elements we have processed in each input. */
size_t next_index[2] = {0, 0}; size_t next_index[2] = {0, 0};
/** Accumulated fee/sizes in diagrams, up to next_index[i] - 1. */ /** Accumulated fee/sizes in diagrams, up to next_index[i] - 1. */

View file

@ -154,6 +154,6 @@ struct FeeFrac
* The caller must guarantee that the sum of the FeeFracs in either of the chunks' data set do not * The caller must guarantee that the sum of the FeeFracs in either of the chunks' data set do not
* overflow (so sum fees < 2^63, and sum sizes < 2^31). * overflow (so sum fees < 2^63, and sum sizes < 2^31).
*/ */
std::partial_ordering CompareChunks(Span<const FeeFrac> chunks0, Span<const FeeFrac> chunks1); std::partial_ordering CompareChunks(std::span<const FeeFrac> chunks0, std::span<const FeeFrac> chunks1);
#endif // BITCOIN_UTIL_FEEFRAC_H #endif // BITCOIN_UTIL_FEEFRAC_H

View file

@ -1,4 +1,4 @@
// Copyright (c) 2019-2022 The Bitcoin Core developers // Copyright (c) 2019-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -20,7 +20,7 @@ SaltedSipHasher::SaltedSipHasher() :
m_k0{FastRandomContext().rand64()}, m_k0{FastRandomContext().rand64()},
m_k1{FastRandomContext().rand64()} {} m_k1{FastRandomContext().rand64()} {}
size_t SaltedSipHasher::operator()(const Span<const unsigned char>& script) const size_t SaltedSipHasher::operator()(const std::span<const unsigned char>& script) const
{ {
return CSipHasher(m_k0, m_k1).Write(script).Finalize(); return CSipHasher(m_k0, m_k1).Write(script).Finalize();
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) 2019-2022 The Bitcoin Core developers // Copyright (c) 2019-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -94,7 +94,7 @@ private:
public: public:
SaltedSipHasher(); SaltedSipHasher();
size_t operator()(const Span<const unsigned char>& script) const; size_t operator()(const std::span<const unsigned char>& script) const;
}; };
#endif // BITCOIN_UTIL_HASHER_H #endif // BITCOIN_UTIL_HASHER_H

Some files were not shown because too many files have changed in this diff Show more