mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-17 21:32:00 +01:00
Compare commits
20 Commits
0cfd2dedbe
...
d2e95b76ff
Author | SHA1 | Date | |
---|---|---|---|
|
d2e95b76ff | ||
|
5f4422d68d | ||
|
a9d311c54e | ||
|
3301d2cbe8 | ||
|
8c32737387 | ||
|
bca9f5e0b6 | ||
|
635ec43592 | ||
|
8d0d507e28 | ||
|
d2859806bf | ||
|
6c47e4fe15 | ||
|
73ff390b08 | ||
|
06a4d404ab | ||
|
1488d227a4 | ||
|
f782b9bb20 | ||
|
afb8d60c49 | ||
|
417ef26e93 | ||
|
4219523d57 | ||
|
8a67a27473 | ||
|
9bfb0d75ba | ||
|
7ac281c19c |
@ -856,14 +856,14 @@ class A
|
||||
- *Rationale*: Easier to understand what is happening, thus easier to spot mistakes, even for those
|
||||
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)
|
||||
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).
|
||||
|
||||
```cpp
|
||||
void Foo(Span<const int> data);
|
||||
void Foo(std::span<const int> data);
|
||||
|
||||
std::vector<int> vec{1,2,3};
|
||||
Foo(vec);
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -86,7 +86,7 @@ static const int8_t mapBase58[256] = {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string EncodeBase58(Span<const unsigned char> input)
|
||||
std::string EncodeBase58(std::span<const unsigned char> input)
|
||||
{
|
||||
// Skip & count leading zeroes.
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
std::vector<unsigned char> vch(input.begin(), input.end());
|
||||
@ -151,7 +151,7 @@ std::string EncodeBase58Check(Span<const unsigned char> input)
|
||||
return false;
|
||||
}
|
||||
// re-calculate the checksum, ensure it matches the included 4-byte checksum
|
||||
uint256 hash = Hash(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) {
|
||||
vchRet.clear();
|
||||
return false;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
/**
|
||||
* 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).
|
||||
@ -33,7 +33,7 @@ std::string EncodeBase58(Span<const unsigned char> input);
|
||||
/**
|
||||
* 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
|
||||
|
@ -21,15 +21,38 @@
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
static void SizeComputerBlock(benchmark::Bench& bench) {
|
||||
CBlock block;
|
||||
DataStream(benchmark::data::block413567) >> TX_WITH_WITNESS(block);
|
||||
|
||||
bench.unit("block").run([&] {
|
||||
SizeComputer size_computer;
|
||||
size_computer << TX_WITH_WITNESS(block);
|
||||
assert(size_computer.size() == benchmark::data::block413567.size());
|
||||
});
|
||||
}
|
||||
|
||||
static void SerializeBlock(benchmark::Bench& bench) {
|
||||
CBlock block;
|
||||
DataStream(benchmark::data::block413567) >> TX_WITH_WITNESS(block);
|
||||
|
||||
// Create output stream and verify first serialization matches input
|
||||
bench.unit("block").run([&] {
|
||||
DataStream output_stream(benchmark::data::block413567.size());
|
||||
output_stream << TX_WITH_WITNESS(block);
|
||||
assert(output_stream.size() == benchmark::data::block413567.size());
|
||||
});
|
||||
}
|
||||
|
||||
// These are the two major time-sinks which happen after we have fully received
|
||||
// a block off the wire, but before we can relay the block on to peers using
|
||||
// compact block relay.
|
||||
|
||||
static void DeserializeBlockTest(benchmark::Bench& bench)
|
||||
static void DeserializeBlock(benchmark::Bench& bench)
|
||||
{
|
||||
DataStream stream(benchmark::data::block413567);
|
||||
std::byte a{0};
|
||||
stream.write({&a, 1}); // Prevent compaction
|
||||
stream.write(std::span{&a, 1}); // Prevent compaction
|
||||
|
||||
bench.unit("block").run([&] {
|
||||
CBlock block;
|
||||
@ -39,11 +62,11 @@ static void DeserializeBlockTest(benchmark::Bench& bench)
|
||||
});
|
||||
}
|
||||
|
||||
static void DeserializeAndCheckBlockTest(benchmark::Bench& bench)
|
||||
static void DeserializeAndCheckBlock(benchmark::Bench& bench)
|
||||
{
|
||||
DataStream stream(benchmark::data::block413567);
|
||||
std::byte a{0};
|
||||
stream.write({&a, 1}); // Prevent compaction
|
||||
stream.write(std::span{&a, 1}); // Prevent compaction
|
||||
|
||||
ArgsManager bench_args;
|
||||
const auto chainParams = CreateChainParams(bench_args, ChainType::MAIN);
|
||||
@ -60,5 +83,7 @@ static void DeserializeAndCheckBlockTest(benchmark::Bench& bench)
|
||||
});
|
||||
}
|
||||
|
||||
BENCHMARK(DeserializeBlockTest, benchmark::PriorityLevel::HIGH);
|
||||
BENCHMARK(DeserializeAndCheckBlockTest, benchmark::PriorityLevel::HIGH);
|
||||
BENCHMARK(SizeComputerBlock, benchmark::PriorityLevel::HIGH);
|
||||
BENCHMARK(SerializeBlock, benchmark::PriorityLevel::HIGH);
|
||||
BENCHMARK(DeserializeBlock, benchmark::PriorityLevel::HIGH);
|
||||
BENCHMARK(DeserializeAndCheckBlock, benchmark::PriorityLevel::HIGH);
|
||||
|
@ -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
|
||||
// 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()};
|
||||
ss << params.MessageStart();
|
||||
ss << static_cast<uint32_t>(benchmark::data::block413567.size());
|
||||
// We can't use the streaming serialization (ss << benchmark::data::block413567)
|
||||
// because that first writes a compact size.
|
||||
ss << Span{benchmark::data::block413567};
|
||||
// Use span-serialization to avoid writing the size first.
|
||||
ss << std::span{benchmark::data::block413567};
|
||||
|
||||
// Create the test file.
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ struct TestBlockAndIndex {
|
||||
{
|
||||
DataStream stream{benchmark::data::block413567};
|
||||
std::byte a{0};
|
||||
stream.write({&a, 1}); // Prevent compaction
|
||||
stream.write(std::span{&a, 1}); // Prevent compaction
|
||||
|
||||
stream >> TX_WITH_WITNESS(block);
|
||||
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -22,8 +22,8 @@
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
BIP324Cipher::BIP324Cipher(const CKey& key, Span<const std::byte> ent32) noexcept :
|
||||
m_key(key)
|
||||
BIP324Cipher::BIP324Cipher(const CKey& key, std::span<const std::byte> ent32) noexcept
|
||||
: m_key(key)
|
||||
{
|
||||
m_our_pubkey = m_key.EllSwiftCreate(ent32);
|
||||
}
|
||||
@ -70,7 +70,7 @@ void BIP324Cipher::Initialize(const EllSwiftPubKey& their_pubkey, bool initiator
|
||||
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);
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
16
src/bip324.h
16
src/bip324.h
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -45,7 +45,7 @@ public:
|
||||
BIP324Cipher() = delete;
|
||||
|
||||
/** 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). */
|
||||
BIP324Cipher(const CKey& key, const EllSwiftPubKey& pubkey) noexcept;
|
||||
@ -68,29 +68,29 @@ public:
|
||||
*
|
||||
* 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().
|
||||
*
|
||||
* 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().
|
||||
*
|
||||
* It must hold that input.size() + LENGTH_LEN == contents.size() + EXPANSION.
|
||||
* 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(). */
|
||||
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(). */
|
||||
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(). */
|
||||
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
|
||||
|
@ -75,7 +75,7 @@ public:
|
||||
*
|
||||
* @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
|
||||
* depgraph.PositionRange(). The value of mapping[i] is ignored if
|
||||
* 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().
|
||||
*/
|
||||
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((pos_range == 0) == (depgraph.TxCount() == 0));
|
||||
@ -371,7 +371,7 @@ struct SetInfo
|
||||
|
||||
/** Compute the feerates of the chunks of linearization. */
|
||||
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;
|
||||
for (ClusterIndex i : linearization) {
|
||||
@ -396,7 +396,7 @@ class LinearizationChunking
|
||||
const DepGraph<SetType>& m_depgraph;
|
||||
|
||||
/** 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. */
|
||||
std::vector<SetInfo<SetType>> m_chunks;
|
||||
@ -437,7 +437,7 @@ class LinearizationChunking
|
||||
|
||||
public:
|
||||
/** 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)
|
||||
{
|
||||
// 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().
|
||||
*/
|
||||
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());
|
||||
if (depgraph.TxCount() == 0) return {{}, true};
|
||||
@ -1110,7 +1110,7 @@ std::pair<std::vector<ClusterIndex>, bool> Linearize(const DepGraph<SetType>& de
|
||||
* postlinearize" process.
|
||||
*/
|
||||
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
|
||||
// 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.
|
||||
*/
|
||||
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(lin2.size() == depgraph.TxCount());
|
||||
|
@ -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
|
||||
// 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.
|
||||
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)
|
||||
return;
|
||||
@ -65,7 +65,7 @@ void CBloomFilter::insert(const COutPoint& outpoint)
|
||||
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)
|
||||
return true;
|
||||
@ -187,12 +187,12 @@ CRollingBloomFilter::CRollingBloomFilter(const unsigned int nElements, const dou
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
void CRollingBloomFilter::insert(Span<const unsigned char> vKey)
|
||||
void CRollingBloomFilter::insert(std::span<const unsigned char> vKey)
|
||||
{
|
||||
if (nEntriesThisGeneration == nEntriesPerGeneration) {
|
||||
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++) {
|
||||
uint32_t h = RollingBloomHash(n, nTweak, vKey);
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -49,7 +49,7 @@ private:
|
||||
unsigned int nTweak;
|
||||
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:
|
||||
/**
|
||||
@ -66,10 +66,10 @@ public:
|
||||
|
||||
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);
|
||||
|
||||
bool contains(Span<const unsigned char> vKey) const;
|
||||
bool contains(std::span<const unsigned char> vKey) 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
|
||||
@ -110,8 +110,8 @@ class CRollingBloomFilter
|
||||
public:
|
||||
CRollingBloomFilter(const unsigned int nElements, const double nFPRate);
|
||||
|
||||
void insert(Span<const unsigned char> vKey);
|
||||
bool contains(Span<const unsigned char> vKey) const;
|
||||
void insert(std::span<const unsigned char> vKey);
|
||||
bool contains(std::span<const unsigned char> vKey) const;
|
||||
|
||||
void reset();
|
||||
|
||||
|
@ -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
|
||||
// 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.
|
||||
[[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);
|
||||
if (addr.IsIPv4()) {
|
||||
@ -200,7 +200,7 @@ std::string PCPResultString(uint8_t result_code)
|
||||
}
|
||||
|
||||
//! 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);
|
||||
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.
|
||||
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::function<bool(Span<const uint8_t>)> check_packet)
|
||||
std::function<bool(std::span<const uint8_t>)> check_packet)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
// 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()));
|
||||
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.
|
||||
break;
|
||||
}
|
||||
@ -309,7 +309,7 @@ std::variant<MappingResult, MappingError> NATPMPRequestPortMap(const CNetAddr &g
|
||||
request[NATPMP_HDR_OP_OFS] = NATPMP_REQUEST | NATPMP_OP_GETEXTERNAL;
|
||||
|
||||
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) {
|
||||
LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "natpmp: Response too small\n");
|
||||
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);
|
||||
|
||||
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) {
|
||||
LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "natpmp: Response too small\n");
|
||||
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_OP_OFS] = PCP_REQUEST | PCP_OP_MAP;
|
||||
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;
|
||||
|
||||
@ -449,7 +449,7 @@ std::variant<MappingResult, MappingError> PCPRequestPortMap(const PCPMappingNonc
|
||||
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_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;
|
||||
Assume(ofs == request.size());
|
||||
@ -457,7 +457,7 @@ std::variant<MappingResult, MappingError> PCPRequestPortMap(const PCPMappingNonc
|
||||
// Receive loop.
|
||||
bool is_natpmp = false;
|
||||
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.
|
||||
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;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -65,12 +65,12 @@ struct ScriptCompression
|
||||
void Ser(Stream &s, const CScript& script) {
|
||||
CompressedScript compr;
|
||||
if (CompressScript(script, compr)) {
|
||||
s << Span{compr};
|
||||
s << std::span{compr};
|
||||
return;
|
||||
}
|
||||
unsigned int nSize = script.size() + nSpecialScripts;
|
||||
s << VARINT(nSize);
|
||||
s << Span{script};
|
||||
s << std::span{script};
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
@ -79,7 +79,7 @@ struct ScriptCompression
|
||||
s >> VARINT(nSize);
|
||||
if (nSize < nSpecialScripts) {
|
||||
CompressedScript vch(GetSpecialScriptSize(nSize), 0x00);
|
||||
s >> Span{vch};
|
||||
s >> std::span{vch};
|
||||
DecompressScript(script, nSize, vch);
|
||||
return;
|
||||
}
|
||||
@ -90,7 +90,7 @@ struct ScriptCompression
|
||||
s.ignore(nSize);
|
||||
} else {
|
||||
script.resize(nSize);
|
||||
s >> Span{script};
|
||||
s >> std::span{script};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#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);
|
||||
input[0] = ReadLE32(key.data() + 0);
|
||||
@ -44,7 +44,7 @@ ChaCha20Aligned::~ChaCha20Aligned()
|
||||
memory_cleanse(input, sizeof(input));
|
||||
}
|
||||
|
||||
ChaCha20Aligned::ChaCha20Aligned(Span<const std::byte> key) noexcept
|
||||
ChaCha20Aligned::ChaCha20Aligned(std::span<const std::byte> key) noexcept
|
||||
{
|
||||
SetKey(key);
|
||||
}
|
||||
@ -57,7 +57,7 @@ void ChaCha20Aligned::Seek(Nonce96 nonce, uint32_t block_counter) noexcept
|
||||
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();
|
||||
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());
|
||||
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 (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());
|
||||
|
||||
@ -334,20 +334,20 @@ ChaCha20::~ChaCha20()
|
||||
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_bufleft = 0;
|
||||
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)
|
||||
{
|
||||
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());
|
||||
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -38,13 +38,13 @@ public:
|
||||
ChaCha20Aligned() noexcept = delete;
|
||||
|
||||
/** 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. */
|
||||
~ChaCha20Aligned();
|
||||
|
||||
/** 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.
|
||||
*
|
||||
@ -64,13 +64,13 @@ public:
|
||||
void Seek(Nonce96 nonce, uint32_t block_counter) noexcept;
|
||||
|
||||
/** 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>
|
||||
*
|
||||
* 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. */
|
||||
@ -89,13 +89,13 @@ public:
|
||||
ChaCha20() noexcept = delete;
|
||||
|
||||
/** 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. */
|
||||
~ChaCha20();
|
||||
|
||||
/** 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. */
|
||||
using Nonce96 = ChaCha20Aligned::Nonce96;
|
||||
@ -111,10 +111,10 @@ public:
|
||||
*
|
||||
* 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. */
|
||||
void Keystream(Span<std::byte> out) noexcept;
|
||||
void Keystream(std::span<std::byte> out) noexcept;
|
||||
};
|
||||
|
||||
/** Forward-secure ChaCha20
|
||||
@ -150,10 +150,10 @@ public:
|
||||
FSChaCha20& operator=(FSChaCha20&&) = delete;
|
||||
|
||||
/** 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. */
|
||||
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
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -13,12 +13,12 @@
|
||||
#include <assert.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
void AEADChaCha20Poly1305::SetKey(Span<const std::byte> key) noexcept
|
||||
void AEADChaCha20Poly1305::SetKey(std::span<const std::byte> key) noexcept
|
||||
{
|
||||
assert(key.size() == KEYLEN);
|
||||
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. */
|
||||
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] = {{}};
|
||||
|
||||
@ -45,15 +45,15 @@ void ComputeTag(ChaCha20& chacha20, Span<const std::byte> aad, Span<const std::b
|
||||
chacha20.Keystream(first_block);
|
||||
|
||||
// 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:
|
||||
// - Process the padded AAD with Poly1305.
|
||||
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.
|
||||
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.
|
||||
std::byte length_desc[Poly1305::TAGLEN];
|
||||
WriteLE64(length_desc, aad.size());
|
||||
@ -66,7 +66,7 @@ void ComputeTag(ChaCha20& chacha20, Span<const std::byte> aad, Span<const std::b
|
||||
|
||||
} // 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);
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -96,7 +96,7 @@ bool AEADChaCha20Poly1305::Decrypt(Span<const std::byte> cipher, Span<const std:
|
||||
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.
|
||||
m_chacha20.Seek(nonce, 1);
|
||||
@ -111,7 +111,7 @@ void FSChaCha20Poly1305::NextPacket() noexcept
|
||||
std::byte one_block[ChaCha20Aligned::BLOCKLEN];
|
||||
m_aead.Keystream({0xFFFFFFFF, m_rekey_counter}, one_block);
|
||||
// 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
|
||||
// once it cycles again, or is destroyed).
|
||||
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);
|
||||
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);
|
||||
NextPacket();
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -26,10 +26,10 @@ public:
|
||||
static constexpr unsigned EXPANSION = Poly1305::TAGLEN;
|
||||
|
||||
/** 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. */
|
||||
void SetKey(Span<const std::byte> key) noexcept;
|
||||
void SetKey(std::span<const std::byte> key) noexcept;
|
||||
|
||||
/** 96-bit nonce type. */
|
||||
using Nonce96 = ChaCha20::Nonce96;
|
||||
@ -38,7 +38,7 @@ public:
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
@ -47,13 +47,13 @@ public:
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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, {});
|
||||
}
|
||||
@ -62,14 +62,14 @@ public:
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This is equivalent to Encrypt() with plain set to that many zero bytes, and dropping the
|
||||
* 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.
|
||||
@ -111,14 +111,14 @@ public:
|
||||
FSChaCha20Poly1305& operator=(FSChaCha20Poly1305&&) = delete;
|
||||
|
||||
/** 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) {}
|
||||
|
||||
/** Encrypt a message with a specified aad.
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
@ -127,13 +127,13 @@ public:
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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, {});
|
||||
}
|
||||
@ -142,7 +142,7 @@ public:
|
||||
*
|
||||
* 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
|
||||
|
@ -26,7 +26,7 @@ constexpr std::array<ByteAsHex, 256> CreateByteToHexMap()
|
||||
|
||||
} // 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');
|
||||
static constexpr auto byte_to_hex = CreateByteToHexMap();
|
||||
|
@ -14,9 +14,9 @@
|
||||
/**
|
||||
* Convert a span of bytes to a lower-case hexadecimal string.
|
||||
*/
|
||||
std::string HexStr(const Span<const uint8_t> s);
|
||||
inline std::string HexStr(const Span<const char> s) { return HexStr(MakeUCharSpan(s)); }
|
||||
inline std::string HexStr(const Span<const std::byte> s) { return HexStr(MakeUCharSpan(s)); }
|
||||
std::string HexStr(const std::span<const uint8_t> s);
|
||||
inline std::string HexStr(const std::span<const char> 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);
|
||||
|
||||
|
@ -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
|
||||
// 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];
|
||||
|
||||
uint256 hashed_in{(HashWriter{} << in).GetSHA256()};
|
||||
@ -543,7 +543,7 @@ Num3072 MuHash3072::ToNum3072(Span<const unsigned char> in) {
|
||||
return out;
|
||||
}
|
||||
|
||||
MuHash3072::MuHash3072(Span<const unsigned char> in) noexcept
|
||||
MuHash3072::MuHash3072(std::span<const unsigned char> in) noexcept
|
||||
{
|
||||
m_numerator = ToNum3072(in);
|
||||
}
|
||||
@ -573,12 +573,12 @@ MuHash3072& MuHash3072::operator/=(const MuHash3072& div) noexcept
|
||||
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));
|
||||
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));
|
||||
return *this;
|
||||
}
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -102,20 +102,20 @@ private:
|
||||
Num3072 m_numerator;
|
||||
Num3072 m_denominator;
|
||||
|
||||
Num3072 ToNum3072(Span<const unsigned char> in);
|
||||
Num3072 ToNum3072(std::span<const unsigned char> in);
|
||||
|
||||
public:
|
||||
/* The empty set. */
|
||||
MuHash3072() noexcept = default;
|
||||
|
||||
/* 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. */
|
||||
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. */
|
||||
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) */
|
||||
MuHash3072& operator*=(const MuHash3072& mul) noexcept;
|
||||
|
@ -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
|
||||
// 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
|
||||
|
||||
/** C++ wrapper with std::byte Span interface around poly1305_donna code. */
|
||||
/** C++ wrapper with std::byte span interface around poly1305_donna code. */
|
||||
class Poly1305
|
||||
{
|
||||
poly1305_donna::poly1305_context m_ctx;
|
||||
@ -46,21 +46,21 @@ public:
|
||||
static constexpr unsigned KEYLEN{32};
|
||||
|
||||
/** 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);
|
||||
poly1305_donna::poly1305_init(&m_ctx, UCharCast(key.data()));
|
||||
}
|
||||
|
||||
/** 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());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** 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);
|
||||
poly1305_donna::poly1305_finish(&m_ctx, UCharCast(out.data()));
|
||||
|
@ -723,6 +723,21 @@ CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
CSHA256& CSHA256::Write(unsigned char data)
|
||||
{
|
||||
size_t bufsize = bytes % 64;
|
||||
|
||||
// Add the single byte to the buffer
|
||||
buf[bufsize] = data;
|
||||
bytes += 1;
|
||||
|
||||
if (bufsize == 63) {
|
||||
// Process the buffer if full
|
||||
Transform(s, buf, 1);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
|
||||
{
|
||||
|
@ -22,6 +22,7 @@ public:
|
||||
|
||||
CSHA256();
|
||||
CSHA256& Write(const unsigned char* data, size_t len);
|
||||
CSHA256& Write(unsigned char data);
|
||||
void Finalize(unsigned char hash[OUTPUT_SIZE]);
|
||||
CSHA256& Reset();
|
||||
};
|
||||
|
@ -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
|
||||
// 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) {
|
||||
// Fill the buffer and process it.
|
||||
@ -133,7 +133,7 @@ SHA3_256& SHA3_256::Write(Span<const unsigned char> data)
|
||||
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);
|
||||
std::fill(m_buffer + m_bufsize, m_buffer + sizeof(m_buffer), 0);
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -33,8 +33,8 @@ public:
|
||||
static constexpr size_t OUTPUT_SIZE = 32;
|
||||
|
||||
SHA3_256() = default;
|
||||
SHA3_256& Write(Span<const unsigned char> data);
|
||||
SHA3_256& Finalize(Span<unsigned char> output);
|
||||
SHA3_256& Write(std::span<const unsigned char> data);
|
||||
SHA3_256& Finalize(std::span<unsigned char> output);
|
||||
SHA3_256& Reset();
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -45,7 +45,7 @@ CSipHasher& CSipHasher::Write(uint64_t data)
|
||||
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 t = tmp;
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -27,7 +27,7 @@ public:
|
||||
*/
|
||||
CSipHasher& Write(uint64_t data);
|
||||
/** 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. */
|
||||
uint64_t Finalize() const;
|
||||
};
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -168,7 +168,7 @@ void CDBBatch::Clear()
|
||||
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());
|
||||
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();
|
||||
}
|
||||
|
||||
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());
|
||||
m_impl_batch->batch.Delete(slKey);
|
||||
@ -336,7 +336,7 @@ std::vector<unsigned char> CDBWrapper::CreateObfuscateKey() const
|
||||
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());
|
||||
std::string strValue;
|
||||
@ -350,7 +350,7 @@ std::optional<std::string> CDBWrapper::ReadImpl(Span<const std::byte> key) const
|
||||
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());
|
||||
|
||||
@ -365,7 +365,7 @@ bool CDBWrapper::ExistsImpl(Span<const std::byte> key) const
|
||||
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 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))};
|
||||
}
|
||||
|
||||
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());
|
||||
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());
|
||||
}
|
||||
|
||||
Span<const std::byte> CDBIterator::GetValueImpl() const
|
||||
std::span<const std::byte> CDBIterator::GetValueImpl() const
|
||||
{
|
||||
return MakeByteSpan(m_impl_iter->iter->value());
|
||||
}
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -85,8 +85,8 @@ private:
|
||||
|
||||
size_t size_estimate{0};
|
||||
|
||||
void WriteImpl(Span<const std::byte> key, DataStream& ssValue);
|
||||
void EraseImpl(Span<const std::byte> key);
|
||||
void WriteImpl(std::span<const std::byte> key, DataStream& ssValue);
|
||||
void EraseImpl(std::span<const std::byte> key);
|
||||
|
||||
public:
|
||||
/**
|
||||
@ -129,9 +129,9 @@ private:
|
||||
const CDBWrapper &parent;
|
||||
const std::unique_ptr<IteratorImpl> m_impl_iter;
|
||||
|
||||
void SeekImpl(Span<const std::byte> key);
|
||||
Span<const std::byte> GetKeyImpl() const;
|
||||
Span<const std::byte> GetValueImpl() const;
|
||||
void SeekImpl(std::span<const std::byte> key);
|
||||
std::span<const std::byte> GetKeyImpl() const;
|
||||
std::span<const std::byte> GetValueImpl() const;
|
||||
|
||||
public:
|
||||
|
||||
@ -206,9 +206,9 @@ private:
|
||||
//! whether or not the database resides in memory
|
||||
bool m_is_memory;
|
||||
|
||||
std::optional<std::string> ReadImpl(Span<const std::byte> key) const;
|
||||
bool ExistsImpl(Span<const std::byte> key) const;
|
||||
size_t EstimateSizeImpl(Span<const std::byte> key1, Span<const std::byte> key2) const;
|
||||
std::optional<std::string> ReadImpl(std::span<const std::byte> key) const;
|
||||
bool ExistsImpl(std::span<const std::byte> key) 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); }
|
||||
|
||||
public:
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
#include <bit>
|
||||
#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
|
||||
uint32_t h1 = nHashSeed;
|
||||
|
44
src/hash.h
44
src/hash.h
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -27,17 +27,21 @@ private:
|
||||
public:
|
||||
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);
|
||||
unsigned char buf[CSHA256::OUTPUT_SIZE];
|
||||
sha.Finalize(buf);
|
||||
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());
|
||||
return *this;
|
||||
}
|
||||
CHash256& Write(std::span<const unsigned char, 1> input) {
|
||||
sha.Write(input[0]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CHash256& Reset() {
|
||||
sha.Reset();
|
||||
@ -52,17 +56,21 @@ private:
|
||||
public:
|
||||
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);
|
||||
unsigned char buf[CSHA256::OUTPUT_SIZE];
|
||||
sha.Finalize(buf);
|
||||
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());
|
||||
return *this;
|
||||
}
|
||||
CHash160& Write(std::span<const unsigned char, 1> input) {
|
||||
sha.Write(input[0]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CHash160& Reset() {
|
||||
sha.Reset();
|
||||
@ -103,10 +111,14 @@ private:
|
||||
CSHA256 ctx;
|
||||
|
||||
public:
|
||||
void write(Span<const std::byte> src)
|
||||
void write(std::span<const std::byte> src)
|
||||
{
|
||||
ctx.Write(UCharCast(src.data()), src.size());
|
||||
}
|
||||
void write(std::span<const std::byte, 1> src)
|
||||
{
|
||||
ctx.Write(*UCharCast(&src[0]));
|
||||
}
|
||||
|
||||
/** Compute the double-SHA256 hash of all data written to this object.
|
||||
*
|
||||
@ -155,18 +167,23 @@ private:
|
||||
public:
|
||||
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);
|
||||
this->write(dst);
|
||||
}
|
||||
void read(std::span<std::byte, 1> dst)
|
||||
{
|
||||
m_source.read(dst);
|
||||
this->write(std::span<const std::byte, 1>{dst});
|
||||
}
|
||||
|
||||
void ignore(size_t num_bytes)
|
||||
{
|
||||
std::byte data[1024];
|
||||
while (num_bytes > 0) {
|
||||
size_t now = std::min<size_t>(num_bytes, 1024);
|
||||
read({data, now});
|
||||
read(std::span{data, now});
|
||||
num_bytes -= now;
|
||||
}
|
||||
}
|
||||
@ -189,7 +206,12 @@ private:
|
||||
public:
|
||||
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);
|
||||
HashWriter::write(src);
|
||||
}
|
||||
void write(std::span<const std::byte, 1> src)
|
||||
{
|
||||
m_source.write(src);
|
||||
HashWriter::write(src);
|
||||
@ -206,7 +228,7 @@ public:
|
||||
/** Single-SHA256 a 32-byte input (represented as uint256). */
|
||||
[[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]);
|
||||
|
||||
@ -219,7 +241,7 @@ void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char he
|
||||
HashWriter TaggedHash(const std::string& tag);
|
||||
|
||||
/** 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;
|
||||
CRIPEMD160().Write(data.data(), data.size()).Finalize(result.begin());
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <ranges>
|
||||
#include <stdexcept>
|
||||
#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);
|
||||
|
||||
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()) {
|
||||
reply.keys.emplace(std::string{kv.begin(), pos}, std::string{pos + 1, kv.end()});
|
||||
} else {
|
||||
|
10
src/key.cpp
10
src/key.cpp
@ -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
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// 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;
|
||||
}
|
||||
|
||||
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);
|
||||
return kp.SignSchnorr(hash, sig, aux);
|
||||
@ -308,7 +308,7 @@ bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const
|
||||
return ret;
|
||||
}
|
||||
|
||||
EllSwiftPubKey CKey::EllSwiftCreate(Span<const std::byte> ent32) const
|
||||
EllSwiftPubKey CKey::EllSwiftCreate(std::span<const std::byte> ent32) const
|
||||
{
|
||||
assert(keydata);
|
||||
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);
|
||||
}
|
||||
|
||||
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'};
|
||||
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();
|
||||
}
|
||||
|
||||
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);
|
||||
if (!IsValid()) return false;
|
||||
|
10
src/key.h
10
src/key.h
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// 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
|
||||
* 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.
|
||||
[[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
|
||||
* 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.
|
||||
*
|
||||
@ -250,7 +250,7 @@ struct CExtKey {
|
||||
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
|
||||
[[nodiscard]] bool Derive(CExtKey& out, unsigned int nChild) const;
|
||||
CExtPubKey Neuter() const;
|
||||
void SetSeed(Span<const std::byte> seed);
|
||||
void SetSeed(std::span<const std::byte> seed);
|
||||
};
|
||||
|
||||
/** KeyPair
|
||||
@ -286,7 +286,7 @@ public:
|
||||
KeyPair(const KeyPair& other) { *this = other; }
|
||||
|
||||
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.
|
||||
bool IsValid() const { return !!m_keypair; }
|
||||
|
38
src/net.cpp
38
src/net.cpp
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -663,7 +663,7 @@ void CNode::CopyStats(CNodeStats& stats)
|
||||
}
|
||||
#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;
|
||||
const auto time = GetTime<std::chrono::microseconds>();
|
||||
@ -731,7 +731,7 @@ Transport::Info V1Transport::GetInfo() const noexcept
|
||||
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);
|
||||
// copy data to temporary parsing buffer
|
||||
@ -772,7 +772,7 @@ int V1Transport::readHeader(Span<const uint8_t> msg_bytes)
|
||||
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);
|
||||
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) {
|
||||
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,
|
||||
HexStr(Span{hash}.first(CMessageHeader::CHECKSUM_SIZE)),
|
||||
HexStr(std::span{hash}.first(CMessageHeader::CHECKSUM_SIZE)),
|
||||
HexStr(hdr.pchChecksum),
|
||||
m_node_id);
|
||||
reject_message = true;
|
||||
@ -868,14 +868,14 @@ Transport::BytesToSend V1Transport::GetBytesToSend(bool have_next_message) const
|
||||
AssertLockNotHeld(m_send_mutex);
|
||||
LOCK(m_send_mutex);
|
||||
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
|
||||
// is a next message after that.
|
||||
have_next_message || !m_message_to_send.data.empty(),
|
||||
m_message_to_send.m_type
|
||||
};
|
||||
} 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
|
||||
// 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.
|
||||
}
|
||||
|
||||
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_v1_fallback{nodeid},
|
||||
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()) {
|
||||
// Full match with the v1 prefix, so fall back to v1 behavior.
|
||||
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
|
||||
// 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);
|
||||
@ -1132,7 +1132,7 @@ bool V2Transport::ProcessReceivedKeyBytes() noexcept
|
||||
if (!m_initiating && m_recv_buffer.size() >= OFFSET + MATCH.size()) {
|
||||
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",
|
||||
HexStr(Span(m_recv_buffer).first(OFFSET)));
|
||||
HexStr(std::span(m_recv_buffer).first(OFFSET)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1319,7 +1319,7 @@ size_t V2Transport::GetMaxBytesToProcess() noexcept
|
||||
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);
|
||||
/** 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;
|
||||
}
|
||||
|
||||
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
|
||||
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);
|
||||
|
||||
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);
|
||||
CNetMessage msg{DataStream{}};
|
||||
// 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());
|
||||
Assume(m_send_pos <= m_send_buffer.size());
|
||||
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)
|
||||
// message to be sent, and we're capable of sending packets. */
|
||||
have_next_message && m_send_state == SendState::READY,
|
||||
@ -2050,7 +2050,7 @@ bool CConnman::InactivityCheck(const CNode& node) const
|
||||
return false;
|
||||
}
|
||||
|
||||
Sock::EventsPerSock CConnman::GenerateWaitSockets(Span<CNode* const> nodes)
|
||||
Sock::EventsPerSock CConnman::GenerateWaitSockets(std::span<CNode* const> nodes)
|
||||
{
|
||||
Sock::EventsPerSock events_per_sock;
|
||||
|
||||
@ -2511,7 +2511,7 @@ bool CConnman::MaybePickPreferredNetwork(std::optional<Network>& network)
|
||||
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_reconnections_mutex);
|
||||
@ -3982,7 +3982,7 @@ void CConnman::ASMapHealthCheck()
|
||||
// Dump binary message to file, with timestamp.
|
||||
static void CaptureMessageToFile(const CAddress& addr,
|
||||
const std::string& msg_type,
|
||||
Span<const unsigned char> data,
|
||||
std::span<const unsigned char> data,
|
||||
bool is_incoming)
|
||||
{
|
||||
// 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")};
|
||||
|
||||
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) {
|
||||
f << uint8_t{'\0'};
|
||||
}
|
||||
@ -4013,6 +4013,6 @@ static void CaptureMessageToFile(const CAddress& addr,
|
||||
|
||||
std::function<void(const CAddress& addr,
|
||||
const std::string& msg_type,
|
||||
Span<const unsigned char> data,
|
||||
std::span<const unsigned char> data,
|
||||
bool is_incoming)>
|
||||
CaptureMessage = CaptureMessageToFile;
|
||||
|
28
src/net.h
28
src/net.h
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// 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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@ -298,14 +298,14 @@ public:
|
||||
virtual bool SetMessageToSend(CSerializedNetMsg& msg) noexcept = 0;
|
||||
|
||||
/** 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
|
||||
* all sent (as signaled by MarkBytesSent()).
|
||||
* - 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).
|
||||
*/
|
||||
using BytesToSend = std::tuple<
|
||||
Span<const uint8_t> /*to_send*/,
|
||||
std::span<const uint8_t> /*to_send*/,
|
||||
bool /*more*/,
|
||||
const std::string& /*m_type*/
|
||||
>;
|
||||
@ -380,8 +380,8 @@ private:
|
||||
unsigned int nDataPos GUARDED_BY(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 readData(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(std::span<const uint8_t> msg_bytes) EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex);
|
||||
|
||||
void Reset() EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex) {
|
||||
AssertLockHeld(m_recv_mutex);
|
||||
@ -424,7 +424,7 @@ public:
|
||||
|
||||
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);
|
||||
LOCK(m_recv_mutex);
|
||||
@ -616,7 +616,7 @@ private:
|
||||
/** Change the send state. */
|
||||
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. */
|
||||
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). */
|
||||
size_t GetMaxBytesToProcess() noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex);
|
||||
/** Put our public key + garbage in the send buffer. */
|
||||
@ -641,11 +641,11 @@ public:
|
||||
V2Transport(NodeId nodeid, bool initiating) noexcept;
|
||||
|
||||
/** 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.
|
||||
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);
|
||||
|
||||
// Send side functions.
|
||||
@ -914,7 +914,7 @@ public:
|
||||
* @return True if the peer should stay connected,
|
||||
* 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)
|
||||
{
|
||||
@ -1297,7 +1297,7 @@ private:
|
||||
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 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 ThreadI2PAcceptIncoming();
|
||||
void AcceptConnection(const ListenSocket& hListenSocket);
|
||||
@ -1325,7 +1325,7 @@ private:
|
||||
* @param[in] nodes Select from these nodes' sockets.
|
||||
* @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.
|
||||
@ -1679,7 +1679,7 @@ private:
|
||||
/** Defaults to `CaptureMessageToFile()`, but can be overridden by unit tests. */
|
||||
extern std::function<void(const CAddress& addr,
|
||||
const std::string& msg_type,
|
||||
Span<const unsigned char> data,
|
||||
std::span<const unsigned char> data,
|
||||
bool is_incoming)>
|
||||
CaptureMessage;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// 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;
|
||||
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
|
||||
} else {
|
||||
// Send block from disk
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// 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;
|
||||
}
|
||||
|
||||
void CNetAddr::SetLegacyIPv6(Span<const uint8_t> ipv6)
|
||||
void CNetAddr::SetLegacyIPv6(std::span<const uint8_t> ipv6)
|
||||
{
|
||||
assert(ipv6.size() == ADDR_IPV6_SIZE);
|
||||
|
||||
@ -187,7 +187,7 @@ static constexpr size_t CHECKSUM_LEN = 2;
|
||||
static const unsigned char VERSION[] = {3};
|
||||
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]
|
||||
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;
|
||||
|
||||
hasher.Write(Span{prefix}.first(prefix_len));
|
||||
hasher.Write(std::span{prefix}.first(prefix_len));
|
||||
hasher.Write(addr_pubkey);
|
||||
hasher.Write(VERSION);
|
||||
|
||||
@ -241,9 +241,9 @@ bool CNetAddr::SetTor(const std::string& addr)
|
||||
}
|
||||
|
||||
if (input->size() == torv3::TOTAL_LEN) {
|
||||
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};
|
||||
Span<const uint8_t> input_version{input->data() + ADDR_TORV3_SIZE + torv3::CHECKSUM_LEN, sizeof(torv3::VERSION)};
|
||||
std::span<const uint8_t> input_pubkey{input->data(), ADDR_TORV3_SIZE};
|
||||
std::span<const uint8_t> input_checksum{input->data() + ADDR_TORV3_SIZE, torv3::CHECKSUM_LEN};
|
||||
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)) {
|
||||
return false;
|
||||
@ -508,14 +508,14 @@ enum Network CNetAddr::GetNetwork() const
|
||||
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 an IPv6 address text representation with zero compression as described in RFC 5952
|
||||
// ("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);
|
||||
const std::array groups{
|
||||
@ -570,7 +570,7 @@ static std::string IPv6ToString(Span<const uint8_t> a, uint32_t scope_id)
|
||||
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];
|
||||
torv3::Checksum(addr, checksum);
|
||||
@ -664,13 +664,13 @@ uint32_t CNetAddr::GetLinkedIPv4() const
|
||||
return ReadBE32(m_addr.data());
|
||||
} else if (IsRFC6052() || IsRFC6145()) {
|
||||
// mapped IPv4, SIIT translated IPv4: the IPv4 address is the last 4 bytes of the address
|
||||
return ReadBE32(Span{m_addr}.last(ADDR_IPV4_SIZE).data());
|
||||
return ReadBE32(std::span{m_addr}.last(ADDR_IPV4_SIZE).data());
|
||||
} else if (IsRFC3964()) {
|
||||
// 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()) {
|
||||
// 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);
|
||||
}
|
||||
|
@ -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
|
||||
// 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.
|
||||
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.
|
||||
@ -139,7 +139,7 @@ public:
|
||||
* (e.g. IPv4) disguised as IPv6. This encoding is used in the legacy
|
||||
* `addr` encoding.
|
||||
*/
|
||||
void SetLegacyIPv6(Span<const uint8_t> ipv6);
|
||||
void SetLegacyIPv6(std::span<const uint8_t> ipv6);
|
||||
|
||||
bool SetInternal(const std::string& name);
|
||||
|
||||
@ -437,7 +437,7 @@ private:
|
||||
|
||||
if (SetNetFromBIP155Network(bip155_net, address_size)) {
|
||||
m_addr.resize(address_size);
|
||||
s >> Span{m_addr};
|
||||
s >> std::span{m_addr};
|
||||
|
||||
if (m_net != NET_IPV6) {
|
||||
return;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// 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
|
||||
if (witnessversion == 1 && witnessprogram.size() == WITNESS_V1_TAPROOT_SIZE && !p2sh) {
|
||||
// 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) {
|
||||
// Annexes are nonstandard as long as no semantics are defined for them.
|
||||
return false;
|
||||
|
@ -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
|
||||
// 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);
|
||||
}
|
||||
|
||||
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};
|
||||
try {
|
||||
|
24
src/psbt.h
24
src/psbt.h
@ -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
|
||||
// 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()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -242,7 +242,7 @@ struct PSBTInput
|
||||
if (final_script_sig.empty() && final_script_witness.IsNull()) {
|
||||
// Write any partial signatures
|
||||
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;
|
||||
}
|
||||
|
||||
@ -269,25 +269,25 @@ struct PSBTInput
|
||||
|
||||
// Write any ripemd160 preimage
|
||||
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;
|
||||
}
|
||||
|
||||
// Write any sha256 preimage
|
||||
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;
|
||||
}
|
||||
|
||||
// Write any hash160 preimage
|
||||
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;
|
||||
}
|
||||
|
||||
// Write any hash256 preimage
|
||||
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;
|
||||
}
|
||||
|
||||
@ -308,7 +308,7 @@ struct PSBTInput
|
||||
for (const auto& [leaf, control_blocks] : m_tap_scripts) {
|
||||
const auto& [script, leaf_ver] = leaf;
|
||||
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());
|
||||
value_v.push_back((uint8_t)leaf_ver);
|
||||
s << value_v;
|
||||
@ -594,7 +594,7 @@ struct PSBTInput
|
||||
} else if (key.size() != 65) {
|
||||
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;
|
||||
uint256 hash;
|
||||
s_key >> xonly;
|
||||
@ -636,7 +636,7 @@ struct PSBTInput
|
||||
} else if (key.size() != 33) {
|
||||
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;
|
||||
s_key >> xonly;
|
||||
std::set<uint256> leaf_hashes;
|
||||
@ -893,7 +893,7 @@ struct PSBTOutput
|
||||
} else if (key.size() != 33) {
|
||||
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;
|
||||
uint64_t value_len = ReadCompactSize(s);
|
||||
size_t before_hashes = s.size();
|
||||
@ -1279,6 +1279,6 @@ bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransacti
|
||||
//! Decode a base64ed PSBT into a PartiallySignedTransaction
|
||||
[[nodiscard]] bool DecodeBase64PSBT(PartiallySignedTransaction& decoded_psbt, const std::string& base64_psbt, std::string& error);
|
||||
//! 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
|
||||
|
@ -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
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// 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());
|
||||
}
|
||||
|
||||
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);
|
||||
secp256k1_xonly_pubkey pubkey;
|
||||
@ -353,7 +353,7 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChi
|
||||
return true;
|
||||
}
|
||||
|
||||
EllSwiftPubKey::EllSwiftPubKey(Span<const std::byte> ellswift) noexcept
|
||||
EllSwiftPubKey::EllSwiftPubKey(std::span<const std::byte> ellswift) noexcept
|
||||
{
|
||||
assert(ellswift.size() == SIZE);
|
||||
std::copy(ellswift.begin(), ellswift.end(), m_pubkey.begin());
|
||||
|
18
src/pubkey.h
18
src/pubkey.h
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
@ -103,7 +103,7 @@ public:
|
||||
}
|
||||
|
||||
//! 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());
|
||||
}
|
||||
@ -142,14 +142,14 @@ public:
|
||||
{
|
||||
unsigned int len = size();
|
||||
::WriteCompactSize(s, len);
|
||||
s << Span{vch, len};
|
||||
s << std::span{vch, len};
|
||||
}
|
||||
template <typename Stream>
|
||||
void Unserialize(Stream& s)
|
||||
{
|
||||
const unsigned int len(::ReadCompactSize(s));
|
||||
if (len <= SIZE) {
|
||||
s >> Span{vch, len};
|
||||
s >> std::span{vch, len};
|
||||
if (len != size()) {
|
||||
Invalidate();
|
||||
}
|
||||
@ -163,13 +163,13 @@ public:
|
||||
//! Get the KeyID of this public key (hash of its serialization)
|
||||
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.
|
||||
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} {}
|
||||
|
||||
/** 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.
|
||||
*
|
||||
* 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
|
||||
* key:
|
||||
@ -317,7 +317,7 @@ public:
|
||||
EllSwiftPubKey() noexcept = default;
|
||||
|
||||
/** 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). */
|
||||
CPubKey Decode() const;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -505,7 +505,7 @@ public:
|
||||
// Handle requests for deterministic randomness.
|
||||
if (!always_use_real_rng && m_deterministic_prng.has_value()) [[unlikely]] {
|
||||
// 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.
|
||||
ret = true;
|
||||
}
|
||||
@ -673,13 +673,13 @@ void MakeRandDeterministicDANGEROUS(const uint256& seed) noexcept
|
||||
}
|
||||
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;
|
||||
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);
|
||||
}
|
||||
@ -698,7 +698,7 @@ void FastRandomContext::RandomSeed() noexcept
|
||||
requires_seed = false;
|
||||
}
|
||||
|
||||
void FastRandomContext::fillrand(Span<std::byte> output) noexcept
|
||||
void FastRandomContext::fillrand(std::span<std::byte> output) noexcept
|
||||
{
|
||||
if (requires_seed) RandomSeed();
|
||||
rng.Keystream(output);
|
||||
|
16
src/random.h
16
src/random.h
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// 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.
|
||||
*/
|
||||
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
|
||||
@ -126,7 +126,7 @@ void GetRandBytes(Span<unsigned char> bytes) noexcept;
|
||||
*
|
||||
* Thread-safe.
|
||||
*/
|
||||
void GetStrongRandBytes(Span<unsigned char> bytes) noexcept;
|
||||
void GetStrongRandBytes(std::span<unsigned char> bytes) noexcept;
|
||||
|
||||
|
||||
/* ============================= RANDOM NUMBER GENERATION CLASSES =============================
|
||||
@ -144,7 +144,7 @@ class RandomMixin;
|
||||
|
||||
/** A concept for RandomMixin-based random number generators. */
|
||||
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().
|
||||
{ rng.rand64() } noexcept -> std::same_as<uint64_t>;
|
||||
// A random number generator must derive from RandomMixin, which adds other rand* functions.
|
||||
@ -263,8 +263,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/** Fill a Span with random bytes. */
|
||||
void fillrand(Span<std::byte> span) noexcept
|
||||
/** Fill a span with random bytes. */
|
||||
void fillrand(std::span<std::byte> span) noexcept
|
||||
{
|
||||
while (span.size() >= 8) {
|
||||
uint64_t gen = Impl().rand64();
|
||||
@ -400,8 +400,8 @@ public:
|
||||
return ReadLE64(buf.data());
|
||||
}
|
||||
|
||||
/** Fill a byte Span with random bytes. This overrides the RandomMixin version. */
|
||||
void fillrand(Span<std::byte> output) noexcept;
|
||||
/** Fill a byte span with random bytes. This overrides the RandomMixin version. */
|
||||
void fillrand(std::span<std::byte> output) noexcept;
|
||||
};
|
||||
|
||||
/** xoroshiro128++ PRNG. Extremely fast, not appropriate for cryptographic purposes.
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -1074,7 +1074,7 @@ static RPCHelpMan decodepsbt()
|
||||
|
||||
UniValue keypath(UniValue::VOBJ);
|
||||
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));
|
||||
global_xpubs.push_back(std::move(keypath));
|
||||
}
|
||||
|
@ -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
|
||||
// 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;
|
||||
}
|
||||
|
||||
std::string DescriptorChecksum(const Span<const char>& span)
|
||||
std::string DescriptorChecksum(const std::span<const char>& span)
|
||||
{
|
||||
/** A character set designed such that:
|
||||
* - 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.
|
||||
* @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:
|
||||
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)));
|
||||
}
|
||||
|
||||
output_scripts = MakeScripts(pubkeys, Span{subscripts}, out);
|
||||
output_scripts = MakeScripts(pubkeys, std::span{subscripts}, out);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -790,7 +790,7 @@ class AddressDescriptor final : public DescriptorImpl
|
||||
const CTxDestination m_destination;
|
||||
protected:
|
||||
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:
|
||||
AddressDescriptor(CTxDestination destination) : DescriptorImpl({}, "addr"), m_destination(std::move(destination)) {}
|
||||
bool IsSolvable() const final { return false; }
|
||||
@ -815,7 +815,7 @@ class RawDescriptor final : public DescriptorImpl
|
||||
const CScript m_script;
|
||||
protected:
|
||||
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:
|
||||
RawDescriptor(CScript script) : DescriptorImpl({}, "raw"), m_script(std::move(script)) {}
|
||||
bool IsSolvable() const final { return false; }
|
||||
@ -843,7 +843,7 @@ class PKDescriptor final : public DescriptorImpl
|
||||
private:
|
||||
const bool m_xonly;
|
||||
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) {
|
||||
CScript script = CScript() << ToByteVector(XOnlyPubKey(keys[0])) << OP_CHECKSIG;
|
||||
@ -881,7 +881,7 @@ public:
|
||||
class PKHDescriptor final : public DescriptorImpl
|
||||
{
|
||||
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();
|
||||
out.pubkeys.emplace(id, keys[0]);
|
||||
@ -915,7 +915,7 @@ public:
|
||||
class WPKHDescriptor final : public DescriptorImpl
|
||||
{
|
||||
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();
|
||||
out.pubkeys.emplace(id, keys[0]);
|
||||
@ -949,7 +949,7 @@ public:
|
||||
class ComboDescriptor final : public DescriptorImpl
|
||||
{
|
||||
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;
|
||||
CKeyID id = keys[0].GetID();
|
||||
@ -980,7 +980,7 @@ class MultisigDescriptor final : public DescriptorImpl
|
||||
const bool m_sorted;
|
||||
protected:
|
||||
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) {
|
||||
std::vector<CPubKey> sorted_keys(keys);
|
||||
std::sort(sorted_keys.begin(), sorted_keys.end());
|
||||
@ -1026,7 +1026,7 @@ class MultiADescriptor final : public DescriptorImpl
|
||||
const bool m_sorted;
|
||||
protected:
|
||||
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;
|
||||
std::vector<XOnlyPubKey> xkeys;
|
||||
xkeys.reserve(keys.size());
|
||||
@ -1069,7 +1069,7 @@ public:
|
||||
class SHDescriptor final : public DescriptorImpl
|
||||
{
|
||||
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])));
|
||||
if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]);
|
||||
@ -1119,7 +1119,7 @@ public:
|
||||
class WSHDescriptor final : public DescriptorImpl
|
||||
{
|
||||
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])));
|
||||
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;
|
||||
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;
|
||||
assert(m_depths.size() == scripts.size());
|
||||
@ -1304,7 +1304,7 @@ private:
|
||||
miniscript::NodeRef<uint32_t> m_node;
|
||||
|
||||
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
|
||||
{
|
||||
const auto script_ctx{m_node->GetMsCtx()};
|
||||
@ -1361,7 +1361,7 @@ public:
|
||||
class RawTRDescriptor final : public DescriptorImpl
|
||||
{
|
||||
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);
|
||||
XOnlyPubKey xpk(keys[0]);
|
||||
@ -1404,7 +1404,7 @@ enum class ParseScriptContext {
|
||||
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;
|
||||
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
|
||||
* @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;
|
||||
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;
|
||||
|
||||
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
|
||||
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
|
||||
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) {
|
||||
error = "Multipath key path specifiers must have at least two items";
|
||||
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. */
|
||||
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;
|
||||
bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
|
||||
@ -1558,11 +1558,11 @@ std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner(uint32_t key_exp_i
|
||||
}
|
||||
std::vector<KeyPath> paths;
|
||||
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();
|
||||
type = DeriveType::UNHARDENED;
|
||||
} else if (std::ranges::equal(split.back(), Span{"*'"}.first(2)) || std::ranges::equal(split.back(), Span{"*h"}.first(2))) {
|
||||
apostrophe = std::ranges::equal(split.back(), Span{"*'"}.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(), std::span{"*'"}.first(2));
|
||||
split.pop_back();
|
||||
type = DeriveType::HARDENED;
|
||||
}
|
||||
@ -1578,7 +1578,7 @@ std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner(uint32_t key_exp_i
|
||||
}
|
||||
|
||||
/** 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;
|
||||
auto origin_split = Split(sp, ']');
|
||||
@ -1751,7 +1751,7 @@ struct KeyParser {
|
||||
|
||||
/** Parse a script in a particular context. */
|
||||
// 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;
|
||||
Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
|
||||
@ -2178,7 +2178,7 @@ std::unique_ptr<DescriptorImpl> InferMultiA(const CScript& script, ParseScriptCo
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -2321,7 +2321,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
|
||||
} // namespace
|
||||
|
||||
/** 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, '#');
|
||||
if (check_split.size() > 2) {
|
||||
@ -2356,7 +2356,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)
|
||||
{
|
||||
Span<const char> sp{descriptor};
|
||||
std::span<const char> sp{descriptor};
|
||||
if (!CheckChecksum(sp, require_checksum, error)) return {};
|
||||
uint32_t key_exp_index = 0;
|
||||
auto ret = ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error);
|
||||
@ -2375,7 +2375,7 @@ std::string GetDescriptorChecksum(const std::string& descriptor)
|
||||
{
|
||||
std::string ret;
|
||||
std::string error;
|
||||
Span<const char> sp{descriptor};
|
||||
std::span<const char> sp{descriptor};
|
||||
if (!CheckChecksum(sp, false, error, &ret)) return "";
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -1278,12 +1278,12 @@ public:
|
||||
it = itBegin;
|
||||
while (scriptCode.GetOp(it, opcode)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
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 */
|
||||
@ -1639,7 +1639,7 @@ bool GenericTransactionSignatureChecker<T>::VerifyECDSASignature(const std::vect
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@ -1670,7 +1670,7 @@ bool GenericTransactionSignatureChecker<T>::CheckECDSASignature(const std::vecto
|
||||
}
|
||||
|
||||
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);
|
||||
// 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<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()};
|
||||
|
||||
@ -1825,12 +1825,12 @@ static bool ExecuteWitnessScript(const Span<const valtype>& stack_span, const CS
|
||||
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();
|
||||
}
|
||||
|
||||
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};
|
||||
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();
|
||||
}
|
||||
|
||||
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_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;
|
||||
uint256 k = tapleaf_hash;
|
||||
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);
|
||||
}
|
||||
return k;
|
||||
@ -1861,7 +1861,7 @@ static bool VerifyTaprootCommitment(const std::vector<unsigned char>& control, c
|
||||
assert(control.size() >= TAPROOT_CONTROL_BASE_SIZE);
|
||||
assert(program.size() >= uint256::size());
|
||||
//! 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).
|
||||
const XOnlyPubKey q{program};
|
||||
// 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)
|
||||
{
|
||||
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;
|
||||
|
||||
if (witversion == 0) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -250,7 +250,7 @@ public:
|
||||
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;
|
||||
}
|
||||
@ -292,13 +292,13 @@ private:
|
||||
|
||||
protected:
|
||||
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:
|
||||
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) {}
|
||||
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 CheckSequence(const CScriptNum& nSequence) const override;
|
||||
};
|
||||
@ -319,7 +319,7 @@ public:
|
||||
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);
|
||||
}
|
||||
@ -335,13 +335,13 @@ public:
|
||||
};
|
||||
|
||||
/** 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.
|
||||
* 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.
|
||||
* 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, ScriptError* error = nullptr);
|
||||
|
@ -419,7 +419,7 @@ std::optional<int64_t> ParseScriptNumber(const Opcode& in) {
|
||||
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) {
|
||||
if (sp[i] == m) return i;
|
||||
|
@ -531,7 +531,7 @@ struct Node {
|
||||
NodeRef<Key> Clone() const
|
||||
{
|
||||
// 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;
|
||||
for (auto child = children.begin(); child != children.end(); ++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
|
||||
* child. It can modify the state. Children of a given node will have downfn()
|
||||
* called in order.
|
||||
* - upfn is a callable (State&&, const Node&, Span<Result>) -> std::optional<Result>,
|
||||
* which given a node, its state, and a Span of the results of its children,
|
||||
* - 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,
|
||||
* computes the result of the node. If std::nullopt is returned by upfn,
|
||||
* TreeEvalMaybe() immediately returns std::nullopt.
|
||||
* 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.
|
||||
assert(results.size() >= node.subs.size());
|
||||
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 (!result) return {};
|
||||
// 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.
|
||||
* 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>
|
||||
std::optional<Result> TreeEvalMaybe(UpFn upfn) const
|
||||
{
|
||||
struct DummyState {};
|
||||
return TreeEvalMaybe<Result>(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);
|
||||
}
|
||||
);
|
||||
@ -685,7 +685,7 @@ private:
|
||||
// unconditionally dereference the result (it cannot be std::nullopt).
|
||||
return std::move(*TreeEvalMaybe<Result>(std::move(root_state),
|
||||
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)};
|
||||
return std::optional<Result>(std::move(res));
|
||||
}
|
||||
@ -693,14 +693,14 @@ private:
|
||||
}
|
||||
|
||||
/** 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>
|
||||
Result TreeEval(UpFn upfn) const
|
||||
{
|
||||
struct DummyState {};
|
||||
return std::move(*TreeEvalMaybe<Result>(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)};
|
||||
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
|
||||
// and the CScripts of its child nodes, the CScript of the node.
|
||||
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) {
|
||||
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);
|
||||
@ -842,7 +842,7 @@ public:
|
||||
// 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.
|
||||
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 ? ":" : "";
|
||||
|
||||
switch (node.fragment) {
|
||||
@ -1189,7 +1189,7 @@ private:
|
||||
|
||||
// Internal function which is invoked for every tree node, constructing satisfaction/dissatisfactions
|
||||
// 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) {
|
||||
case Fragment::PK_K: {
|
||||
std::vector<unsigned char> sig;
|
||||
@ -1385,7 +1385,7 @@ private:
|
||||
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);
|
||||
|
||||
// Do a consistency check between the satisfaction code and the type checker
|
||||
@ -1453,7 +1453,7 @@ public:
|
||||
using keyset = std::set<Key, Comp>;
|
||||
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 (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.
|
||||
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;
|
||||
if (!node.IsSaneSubexpression()) return &node;
|
||||
return nullptr;
|
||||
@ -1574,7 +1574,7 @@ public:
|
||||
bool IsSatisfiable(F fn) const
|
||||
{
|
||||
// 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) {
|
||||
case Fragment::JUST_0:
|
||||
return false;
|
||||
@ -1744,11 +1744,11 @@ enum class ParseContext {
|
||||
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. */
|
||||
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, ')');
|
||||
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. */
|
||||
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)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
|
||||
@ -1814,7 +1814,7 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
|
||||
to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1);
|
||||
|
||||
// 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 required_ctx{is_multi_a ? MiniscriptContext::TAPSCRIPT : MiniscriptContext::P2WSH};
|
||||
if (ctx.MsContext() != required_ctx) return false;
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
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())) {
|
||||
sp = sp.subspan(str.size());
|
||||
@ -21,7 +21,7 @@ bool Const(const std::string& str, Span<const char>& sp)
|
||||
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())) {
|
||||
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;
|
||||
}
|
||||
|
||||
Span<const char> Expr(Span<const char>& sp)
|
||||
std::span<const char> Expr(std::span<const char>& sp)
|
||||
{
|
||||
int level = 0;
|
||||
auto it = sp.begin();
|
||||
@ -44,7 +44,7 @@ Span<const char> Expr(Span<const char>& sp)
|
||||
}
|
||||
++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());
|
||||
return ret;
|
||||
}
|
||||
|
@ -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
|
||||
// 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.
|
||||
* 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.
|
||||
*
|
||||
@ -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
|
||||
* 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.
|
||||
*
|
||||
@ -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
|
||||
* 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
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// 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());
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
m_signature_cache.ComputeEntrySchnorr(entry, sighash, sig, pubkey);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// 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 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);
|
||||
|
||||
@ -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) {}
|
||||
|
||||
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
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// 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.
|
||||
if (leaf_version != TAPROOT_LEAF_TAPSCRIPT) return false;
|
||||
@ -701,7 +701,7 @@ class DummySignatureChecker final : public BaseSignatureChecker
|
||||
public:
|
||||
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 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 CheckSequence(const CScriptNum& nSequence) const override { return true; }
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// 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]);
|
||||
}
|
||||
|
||||
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);
|
||||
if (!IsValid()) return *this;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// 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
|
||||
* in depth-first traversal order of binary tree. If track is true, it will be included in
|
||||
* 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. */
|
||||
TaprootBuilder& AddOmitted(int depth, const uint256& hash);
|
||||
/** Finalize the construction. Can only be called when IsComplete() is true.
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// 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());
|
||||
}
|
||||
|
||||
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.
|
||||
if (script.size() == 0 || script[0] != 32 || script.back() != OP_NUMEQUAL) return {};
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// 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.
|
||||
* 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. */
|
||||
CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys);
|
||||
|
222
src/serialize.h
222
src/serialize.h
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -48,78 +48,75 @@ static const unsigned int MAX_VECTOR_ALLOCATE = 5000000;
|
||||
struct deserialize_type {};
|
||||
constexpr deserialize_type deserialize {};
|
||||
|
||||
class SizeComputer;
|
||||
|
||||
//! Check if type contains a stream by seeing if it has a GetStream() method.
|
||||
template<typename T>
|
||||
concept ContainsStream = requires(T t) { t.GetStream(); };
|
||||
|
||||
template<typename T>
|
||||
concept ContainsSizeComputer = ContainsStream<T> &&
|
||||
std::is_same_v<std::remove_reference_t<decltype(std::declval<T>().GetStream())>, SizeComputer>;
|
||||
|
||||
/*
|
||||
* Lowest-level serialization and conversion.
|
||||
*/
|
||||
template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
|
||||
template<typename Stream> void ser_writedata8(Stream &s, uint8_t obj)
|
||||
{
|
||||
s.write(AsBytes(Span{&obj, 1}));
|
||||
s.write(std::as_bytes(std::span<uint8_t, 1>{&obj, 1}));
|
||||
}
|
||||
template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
|
||||
template<typename Stream> void ser_writedata16(Stream &s, uint16_t obj)
|
||||
{
|
||||
obj = htole16_internal(obj);
|
||||
s.write(AsBytes(Span{&obj, 1}));
|
||||
s.write(std::as_bytes(std::span<uint16_t, 1>{&obj, 1}));
|
||||
}
|
||||
template<typename Stream> inline void ser_writedata16be(Stream &s, uint16_t obj)
|
||||
{
|
||||
obj = htobe16_internal(obj);
|
||||
s.write(AsBytes(Span{&obj, 1}));
|
||||
}
|
||||
template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
|
||||
template<typename Stream> void ser_writedata32(Stream &s, uint32_t obj)
|
||||
{
|
||||
obj = htole32_internal(obj);
|
||||
s.write(AsBytes(Span{&obj, 1}));
|
||||
s.write(std::as_bytes(std::span<uint32_t, 1>{&obj, 1}));
|
||||
}
|
||||
template<typename Stream> inline void ser_writedata32be(Stream &s, uint32_t obj)
|
||||
template<typename Stream> void ser_writedata32be(Stream &s, uint32_t obj)
|
||||
{
|
||||
obj = htobe32_internal(obj);
|
||||
s.write(AsBytes(Span{&obj, 1}));
|
||||
s.write(std::as_bytes(std::span<uint32_t, 1>{&obj, 1}));
|
||||
}
|
||||
template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
|
||||
template<typename Stream> void ser_writedata64(Stream &s, uint64_t obj)
|
||||
{
|
||||
obj = htole64_internal(obj);
|
||||
s.write(AsBytes(Span{&obj, 1}));
|
||||
s.write(std::as_bytes(std::span<uint64_t, 1>{&obj, 1}));
|
||||
}
|
||||
template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
|
||||
template<typename Stream> uint8_t ser_readdata8(Stream &s)
|
||||
{
|
||||
uint8_t obj;
|
||||
s.read(AsWritableBytes(Span{&obj, 1}));
|
||||
s.read(std::as_writable_bytes(std::span<uint8_t, 1>{&obj, 1}));
|
||||
return obj;
|
||||
}
|
||||
template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
|
||||
template<typename Stream> uint16_t ser_readdata16(Stream &s)
|
||||
{
|
||||
uint16_t obj;
|
||||
s.read(AsWritableBytes(Span{&obj, 1}));
|
||||
s.read(std::as_writable_bytes(std::span<uint16_t, 1>{&obj, 1}));
|
||||
return le16toh_internal(obj);
|
||||
}
|
||||
template<typename Stream> inline uint16_t ser_readdata16be(Stream &s)
|
||||
{
|
||||
uint16_t obj;
|
||||
s.read(AsWritableBytes(Span{&obj, 1}));
|
||||
return be16toh_internal(obj);
|
||||
}
|
||||
template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
|
||||
template<typename Stream> uint32_t ser_readdata32(Stream &s)
|
||||
{
|
||||
uint32_t obj;
|
||||
s.read(AsWritableBytes(Span{&obj, 1}));
|
||||
s.read(std::as_writable_bytes(std::span<uint32_t, 1>{&obj, 1}));
|
||||
return le32toh_internal(obj);
|
||||
}
|
||||
template<typename Stream> inline uint32_t ser_readdata32be(Stream &s)
|
||||
template<typename Stream> uint32_t ser_readdata32be(Stream &s)
|
||||
{
|
||||
uint32_t obj;
|
||||
s.read(AsWritableBytes(Span{&obj, 1}));
|
||||
s.read(std::as_writable_bytes(std::span<uint32_t, 1>{&obj, 1}));
|
||||
return be32toh_internal(obj);
|
||||
}
|
||||
template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
|
||||
template<typename Stream> uint64_t ser_readdata64(Stream &s)
|
||||
{
|
||||
uint64_t obj;
|
||||
s.read(AsWritableBytes(Span{&obj, 1}));
|
||||
s.read(std::as_writable_bytes(std::span<uint64_t, 1>{&obj, 1}));
|
||||
return le64toh_internal(obj);
|
||||
}
|
||||
|
||||
|
||||
class SizeComputer;
|
||||
|
||||
/**
|
||||
* Convert any argument to a reference to X, maintaining constness.
|
||||
*
|
||||
@ -242,7 +239,7 @@ const Out& AsBase(const In& x)
|
||||
FORMATTER_METHODS(cls, obj)
|
||||
|
||||
// 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
|
||||
|
||||
@ -252,38 +249,76 @@ const Out& AsBase(const In& x)
|
||||
template<class T>
|
||||
concept CharNotInt8 = std::same_as<T, char> && !std::same_as<T, int8_t>;
|
||||
|
||||
template <typename T>
|
||||
concept ByteOrIntegral = std::is_same_v<T, std::byte> ||
|
||||
(std::is_integral_v<T> && !std::is_same_v<T, char>);
|
||||
|
||||
template <typename Stream, CharNotInt8 V> void Serialize(Stream&, V) = delete; // char serialization forbidden. Use uint8_t or int8_t
|
||||
template <typename Stream> void Serialize(Stream& s, std::byte a) { ser_writedata8(s, uint8_t(a)); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, int8_t a ) { ser_writedata8(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, uint8_t a ) { ser_writedata8(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, int16_t a ) { ser_writedata16(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, uint16_t a) { ser_writedata16(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, int32_t a ) { ser_writedata32(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, uint32_t a) { ser_writedata32(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, int64_t a ) { ser_writedata64(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, uint64_t a) { ser_writedata64(s, 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, 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, ByteOrIntegral T> void Serialize(Stream& s, T a)
|
||||
{
|
||||
if constexpr (ContainsSizeComputer<Stream>) {
|
||||
s.GetStream().seek(sizeof(T));
|
||||
} else if constexpr (sizeof(T) == 1) {
|
||||
ser_writedata8(s, static_cast<uint8_t>(a)); // (u)int8_t or std::byte or bool
|
||||
} else if constexpr (sizeof(T) == 2) {
|
||||
ser_writedata16(s, static_cast<uint16_t>(a)); // (u)int16_t
|
||||
} else if constexpr (sizeof(T) == 4) {
|
||||
ser_writedata32(s, static_cast<uint32_t>(a)); // (u)int32_t
|
||||
} else {
|
||||
static_assert(sizeof(T) == 8);
|
||||
ser_writedata64(s, static_cast<uint64_t>(a)); // (u)int64_t
|
||||
}
|
||||
}
|
||||
template <typename Stream, BasicByte B, int N> void Serialize(Stream& s, const B (&a)[N])
|
||||
{
|
||||
if constexpr (ContainsSizeComputer<Stream>) {
|
||||
s.GetStream().seek(N);
|
||||
} else {
|
||||
s.write(MakeByteSpan(a));
|
||||
}
|
||||
}
|
||||
template <typename Stream, BasicByte B, std::size_t N> void Serialize(Stream& s, const std::array<B, N>& a)
|
||||
{
|
||||
if constexpr (ContainsSizeComputer<Stream>) {
|
||||
s.GetStream().seek(N);
|
||||
} else {
|
||||
s.write(MakeByteSpan(a));
|
||||
}
|
||||
}
|
||||
template <typename Stream, BasicByte B, std::size_t N> void Serialize(Stream& s, std::span<B, N> span)
|
||||
{
|
||||
if constexpr (ContainsSizeComputer<Stream>) {
|
||||
s.GetStream().seek(N);
|
||||
} else {
|
||||
s.write(std::as_bytes(span));
|
||||
}
|
||||
}
|
||||
template <typename Stream, BasicByte B> void Serialize(Stream& s, std::span<B> span)
|
||||
{
|
||||
if constexpr (ContainsSizeComputer<Stream>) {
|
||||
s.GetStream().seek(span.size());
|
||||
} else {
|
||||
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> void Unserialize(Stream& s, std::byte& a) { a = std::byte{ser_readdata8(s)}; }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, int8_t& a ) { a = ser_readdata8(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a ) { a = ser_readdata8(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, int16_t& a ) { a = ser_readdata16(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a) { a = ser_readdata16(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, int32_t& a ) { a = ser_readdata32(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a) { a = ser_readdata32(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, int64_t& a ) { a = ser_readdata64(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); }
|
||||
template <typename Stream, ByteOrIntegral T> void Unserialize(Stream& s, T& a)
|
||||
{
|
||||
if constexpr (sizeof(T) == 1) {
|
||||
a = static_cast<T>(ser_readdata8(s)); // (u)int8_t or std::byte or bool
|
||||
} else if constexpr (sizeof(T) == 2) {
|
||||
a = static_cast<T>(ser_readdata16(s)); // (u)int16_t
|
||||
} else if constexpr (sizeof(T) == 4) {
|
||||
a = static_cast<T>(ser_readdata32(s)); // (u)int32_t
|
||||
} else {
|
||||
static_assert(sizeof(T) == 8);
|
||||
a = static_cast<T>(ser_readdata64(s)); // (u)int64_t
|
||||
}
|
||||
}
|
||||
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::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> 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; }
|
||||
// clang-format on
|
||||
|
||||
|
||||
@ -302,12 +337,14 @@ constexpr inline unsigned int GetSizeOfCompactSize(uint64_t nSize)
|
||||
else return sizeof(unsigned char) + sizeof(uint64_t);
|
||||
}
|
||||
|
||||
inline void WriteCompactSize(SizeComputer& os, uint64_t nSize);
|
||||
|
||||
template<typename Stream>
|
||||
void WriteCompactSize(Stream& os, uint64_t nSize)
|
||||
{
|
||||
if (nSize < 253)
|
||||
if constexpr (ContainsSizeComputer<Stream>)
|
||||
{
|
||||
os.GetStream().seek(GetSizeOfCompactSize(nSize));
|
||||
}
|
||||
else if (nSize < 253)
|
||||
{
|
||||
ser_writedata8(os, nSize);
|
||||
}
|
||||
@ -414,7 +451,7 @@ struct CheckVarIntMode {
|
||||
};
|
||||
|
||||
template<VarIntMode Mode, typename I>
|
||||
inline unsigned int GetSizeOfVarInt(I n)
|
||||
constexpr unsigned int GetSizeOfVarInt(I n)
|
||||
{
|
||||
CheckVarIntMode<Mode, I>();
|
||||
int nRet = 0;
|
||||
@ -427,12 +464,12 @@ inline unsigned int GetSizeOfVarInt(I n)
|
||||
return nRet;
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
inline void WriteVarInt(SizeComputer& os, I n);
|
||||
|
||||
template<typename Stream, VarIntMode Mode, typename I>
|
||||
void WriteVarInt(Stream& os, I n)
|
||||
{
|
||||
if constexpr (ContainsSizeComputer<Stream>) {
|
||||
os.GetStream().seek(GetSizeOfVarInt<Mode, I>(n));
|
||||
} else {
|
||||
CheckVarIntMode<Mode, I>();
|
||||
unsigned char tmp[(sizeof(n)*8+6)/7];
|
||||
int len=0;
|
||||
@ -446,6 +483,7 @@ void WriteVarInt(Stream& os, I n)
|
||||
do {
|
||||
ser_writedata8(os, tmp[len]);
|
||||
} while(len--);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Stream, VarIntMode Mode, typename I>
|
||||
@ -489,7 +527,7 @@ public:
|
||||
* serialization, and Unser(stream, object&) for deserialization. Serialization routines (inside
|
||||
* READWRITE, or directly with << and >> operators), can then use Using<Formatter>(object).
|
||||
*
|
||||
* This works by constructing a Wrapper<Formatter, T>-wrapped version of object, where T is
|
||||
* This works by constructing a Wrapper<Formatter, T&>-wrapped version of object, where T is
|
||||
* const during serialization, and non-const during deserialization, which maintains const
|
||||
* correctness.
|
||||
*/
|
||||
@ -534,12 +572,14 @@ struct CustomUintFormatter
|
||||
template <typename Stream, typename I> void Ser(Stream& s, I v)
|
||||
{
|
||||
if (v < 0 || v > MAX) throw std::ios_base::failure("CustomUintFormatter value out of range");
|
||||
if (BigEndian) {
|
||||
if constexpr (ContainsSizeComputer<Stream>) {
|
||||
s.GetStream().seek(Bytes);
|
||||
} else if (BigEndian) {
|
||||
uint64_t raw = htobe64_internal(v);
|
||||
s.write(AsBytes(Span{&raw, 1}).last(Bytes));
|
||||
s.write(std::as_bytes(std::span{&raw, 1}).template last<Bytes>());
|
||||
} else {
|
||||
uint64_t raw = htole64_internal(v);
|
||||
s.write(AsBytes(Span{&raw, 1}).first(Bytes));
|
||||
s.write(std::as_bytes(std::span{&raw, 1}).template first<Bytes>());
|
||||
}
|
||||
}
|
||||
|
||||
@ -549,10 +589,10 @@ struct CustomUintFormatter
|
||||
static_assert(std::numeric_limits<U>::max() >= MAX && std::numeric_limits<U>::min() <= 0, "Assigned type too small");
|
||||
uint64_t raw = 0;
|
||||
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));
|
||||
} 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));
|
||||
}
|
||||
}
|
||||
@ -829,7 +869,7 @@ void Unserialize(Stream& is, prevector<N, T>& v)
|
||||
while (i < nSize) {
|
||||
unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
@ -872,7 +912,7 @@ void Unserialize(Stream& is, std::vector<T, A>& v)
|
||||
while (i < nSize) {
|
||||
unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
|
||||
v.resize(i + blk);
|
||||
is.read(AsWritableBytes(Span{&v[i], blk}));
|
||||
is.read(std::as_writable_bytes(std::span{&v[i], blk}));
|
||||
i += blk;
|
||||
}
|
||||
} else {
|
||||
@ -1065,10 +1105,17 @@ protected:
|
||||
public:
|
||||
SizeComputer() = default;
|
||||
|
||||
void write(Span<const std::byte> src)
|
||||
SizeComputer& GetStream() { return *this; }
|
||||
const SizeComputer& GetStream() const { return *this; };
|
||||
|
||||
void write(std::span<const std::byte> src)
|
||||
{
|
||||
this->nSize += src.size();
|
||||
}
|
||||
void write(std::span<const std::byte, 1>)
|
||||
{
|
||||
this->nSize += 1;
|
||||
}
|
||||
|
||||
/** Pretend _nSize bytes are written, without specifying them. */
|
||||
void seek(size_t _nSize)
|
||||
@ -1088,27 +1135,12 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<typename I>
|
||||
inline void WriteVarInt(SizeComputer &s, I n)
|
||||
{
|
||||
s.seek(GetSizeOfVarInt<I>(n));
|
||||
}
|
||||
|
||||
inline void WriteCompactSize(SizeComputer &s, uint64_t nSize)
|
||||
{
|
||||
s.seek(GetSizeOfCompactSize(nSize));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t GetSerializeSize(const T& t)
|
||||
{
|
||||
return (SizeComputer() << t).size();
|
||||
}
|
||||
|
||||
//! Check if type contains a stream by seeing if has a GetStream() method.
|
||||
template<typename T>
|
||||
concept ContainsStream = requires(T t) { t.GetStream(); };
|
||||
|
||||
/** Wrapper that overrides the GetParams() function of a stream. */
|
||||
template <typename SubStream, typename Params>
|
||||
class ParamsStream
|
||||
@ -1132,8 +1164,10 @@ public:
|
||||
|
||||
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; }
|
||||
void write(Span<const std::byte> src) { GetStream().write(src); }
|
||||
void read(Span<std::byte> dst) { GetStream().read(dst); }
|
||||
void write(std::span<const std::byte> src) { GetStream().write(src); }
|
||||
void write(std::span<const std::byte, 1> src) { GetStream().write(src); }
|
||||
void read(std::span<std::byte> dst) { GetStream().read(dst); }
|
||||
void read(std::span<std::byte, 1> dst) { GetStream().read(dst); }
|
||||
void ignore(size_t num) { GetStream().ignore(num); }
|
||||
bool eof() const { return GetStream().eof(); }
|
||||
size_t size() const { return GetStream().size(); }
|
||||
|
@ -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
|
||||
// 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 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;
|
||||
bool found_header = false;
|
||||
@ -39,7 +39,7 @@ static bool FetchAndClearCommitmentSection(const Span<const uint8_t> header, CSc
|
||||
std::vector<uint8_t> pushdata;
|
||||
while (witness_commitment.GetOp(pc, opcode, pushdata)) {
|
||||
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
|
||||
result.insert(result.end(), pushdata.begin() + header.size(), pushdata.end());
|
||||
pushdata.erase(pushdata.begin() + header.size(), pushdata.end());
|
||||
|
234
src/span.h
234
src/span.h
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -11,62 +11,38 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#ifdef DEBUG
|
||||
#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.
|
||||
/** 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
|
||||
* 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:
|
||||
*
|
||||
* 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
|
||||
* 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};
|
||||
* Span<int> sp(vec);
|
||||
* std::span<int> sp(vec);
|
||||
* vec.push_back(5);
|
||||
* printf("%i\n", sp.front()); // UB!
|
||||
*
|
||||
* may exhibit undefined behavior, as increasing the size of a vector may
|
||||
* invalidate references.
|
||||
*
|
||||
* - 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
|
||||
* - 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
|
||||
* 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!
|
||||
*
|
||||
* 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
|
||||
* 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:
|
||||
*
|
||||
* void Foo(Span<const int> arg);
|
||||
* void Foo(std::span<const int> arg);
|
||||
*
|
||||
* Foo(std::vector<int>{1, 2, 3}); // Works
|
||||
*
|
||||
@ -74,10 +50,10 @@
|
||||
* container, and only about having exactly a range of elements. However it
|
||||
* 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:
|
||||
*
|
||||
* void FooMut(Span<int> arg);
|
||||
* void FooMut(std::span<int> arg);
|
||||
*
|
||||
* FooMut(std::vector<int>{1, 2, 3}); // Does not compile
|
||||
* std::vector<int> baz{1, 2, 3};
|
||||
@ -93,159 +69,10 @@
|
||||
* result will be present in that variable after the call. Passing a temporary
|
||||
* 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. */
|
||||
template <typename T>
|
||||
T& SpanPopBack(Span<T>& span)
|
||||
T& SpanPopBack(std::span<T>& span)
|
||||
{
|
||||
size_t size = span.size();
|
||||
T& back = span.back();
|
||||
@ -253,27 +80,15 @@ T& SpanPopBack(Span<T>& span)
|
||||
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>
|
||||
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>
|
||||
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.
|
||||
@ -289,10 +104,11 @@ inline const unsigned char* UCharCast(const std::byte* c) { return reinterpret_c
|
||||
template <typename B>
|
||||
concept BasicByte = requires { UCharCast(std::span<B>{}.data()); };
|
||||
|
||||
// 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()}; }
|
||||
// Helper function to safely convert a span to a span<[const] unsigned char>.
|
||||
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. */
|
||||
template <typename V> constexpr auto MakeUCharSpan(V&& v) -> decltype(UCharSpanCast(Span{std::forward<V>(v)})) { return UCharSpanCast(Span{std::forward<V>(v)}); }
|
||||
/** 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(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
|
||||
|
@ -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");
|
||||
size_t ret = std::fread(dst.data(), 1, dst.size(), m_file);
|
||||
@ -57,12 +57,18 @@ int64_t AutoFile::tell()
|
||||
return *m_position;
|
||||
}
|
||||
|
||||
void AutoFile::read(Span<std::byte> dst)
|
||||
void AutoFile::read(std::span<std::byte> dst)
|
||||
{
|
||||
if (detail_fread(dst) != dst.size()) {
|
||||
throw std::ios_base::failure(feof() ? "AutoFile::read: end of file" : "AutoFile::read: fread failed");
|
||||
}
|
||||
}
|
||||
void AutoFile::read(std::span<std::byte, 1> dst)
|
||||
{
|
||||
if (detail_fread(dst) != 1) {
|
||||
throw std::ios_base::failure(feof() ? "AutoFile::read: end of file" : "AutoFile::read: fread failed");
|
||||
}
|
||||
}
|
||||
|
||||
void AutoFile::ignore(size_t nSize)
|
||||
{
|
||||
@ -78,7 +84,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_xor.empty()) {
|
||||
@ -90,7 +96,7 @@ void AutoFile::write(Span<const std::byte> src)
|
||||
if (!m_position.has_value()) throw std::ios_base::failure("AutoFile::write: position unknown");
|
||||
std::array<std::byte, 4096> buf;
|
||||
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());
|
||||
util::Xor(buf_now, m_xor, *m_position);
|
||||
if (std::fwrite(buf_now.data(), 1, buf_now.size(), m_file) != buf_now.size()) {
|
||||
@ -101,6 +107,25 @@ void AutoFile::write(Span<const std::byte> src)
|
||||
}
|
||||
}
|
||||
}
|
||||
void AutoFile::write(std::span<const std::byte, 1> src)
|
||||
{
|
||||
if (!m_file) throw std::ios_base::failure("AutoFile::write: file handle is nullptr");
|
||||
if (m_xor.empty()) {
|
||||
if (std::fwrite(src.data(), 1, 1, m_file) != 1) {
|
||||
throw std::ios_base::failure("AutoFile::write: write failed");
|
||||
}
|
||||
if (m_position.has_value()) *m_position += 1;
|
||||
} else {
|
||||
if (!m_position.has_value()) throw std::ios_base::failure("AutoFile::write: position unknown");
|
||||
std::byte temp_byte = src[0];
|
||||
std::span val(&temp_byte, 1);
|
||||
util::Xor(val, m_xor, *m_position);
|
||||
if (fwrite(val.data(), 1, 1, m_file) != 1) {
|
||||
throw std::ios_base::failure{"XorFile::write: failed"};
|
||||
}
|
||||
*m_position += 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool AutoFile::Commit()
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
#include <vector>
|
||||
|
||||
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) {
|
||||
return;
|
||||
@ -71,7 +71,7 @@ public:
|
||||
{
|
||||
::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());
|
||||
size_t nOverwrite = std::min(src.size(), vchData.size() - nPos);
|
||||
@ -83,6 +83,17 @@ public:
|
||||
}
|
||||
nPos += src.size();
|
||||
}
|
||||
void write(std::span<const std::byte, 1> src)
|
||||
{
|
||||
assert(nPos <= vchData.size());
|
||||
const auto byte{*UCharCast(&src[0])};
|
||||
if (nPos < vchData.size()) {
|
||||
vchData[nPos] = byte;
|
||||
} else {
|
||||
vchData.push_back(byte);
|
||||
}
|
||||
nPos += 1;
|
||||
}
|
||||
template <typename T>
|
||||
VectorWriter& operator<<(const T& obj)
|
||||
{
|
||||
@ -95,18 +106,18 @@ private:
|
||||
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
|
||||
{
|
||||
private:
|
||||
Span<const unsigned char> m_data;
|
||||
std::span<const unsigned char> m_data;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @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>
|
||||
SpanReader& operator>>(T&& obj)
|
||||
@ -118,7 +129,7 @@ public:
|
||||
size_t size() const { return m_data.size(); }
|
||||
bool empty() const { return m_data.empty(); }
|
||||
|
||||
void read(Span<std::byte> dst)
|
||||
void read(std::span<std::byte> dst)
|
||||
{
|
||||
if (dst.size() == 0) {
|
||||
return;
|
||||
@ -162,8 +173,9 @@ public:
|
||||
typedef vector_type::reverse_iterator reverse_iterator;
|
||||
|
||||
explicit DataStream() = default;
|
||||
explicit DataStream(Span<const uint8_t> sp) : DataStream{AsBytes(sp)} {}
|
||||
explicit DataStream(Span<const value_type> sp) : vch(sp.data(), sp.data() + sp.size()) {}
|
||||
explicit DataStream(size_type n) { reserve(n); }
|
||||
explicit DataStream(std::span<const uint8_t> sp) : DataStream{std::as_bytes(sp)} {}
|
||||
explicit DataStream(std::span<const value_type> sp) : vch(sp.data(), sp.data() + sp.size()) {}
|
||||
|
||||
std::string str() const
|
||||
{
|
||||
@ -215,7 +227,7 @@ public:
|
||||
bool eof() const { return size() == 0; }
|
||||
int in_avail() const { return size(); }
|
||||
|
||||
void read(Span<value_type> dst)
|
||||
void read(std::span<value_type> dst)
|
||||
{
|
||||
if (dst.size() == 0) return;
|
||||
|
||||
@ -248,11 +260,15 @@ public:
|
||||
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
|
||||
vch.insert(vch.end(), src.begin(), src.end());
|
||||
}
|
||||
void write(std::span<const value_type, 1> src)
|
||||
{
|
||||
vch.push_back(src[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
DataStream& operator<<(const T& obj)
|
||||
@ -431,7 +447,7 @@ public:
|
||||
void SetXor(std::vector<std::byte> data_xor) { m_xor = data_xor; }
|
||||
|
||||
/** 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. */
|
||||
void seek(int64_t offset, int origin);
|
||||
@ -448,9 +464,11 @@ public:
|
||||
//
|
||||
// Stream subset
|
||||
//
|
||||
void read(Span<std::byte> dst);
|
||||
void read(std::span<std::byte> dst);
|
||||
void read(std::span<std::byte, 1> dst);
|
||||
void ignore(size_t nSize);
|
||||
void write(Span<const std::byte> src);
|
||||
void write(std::span<const std::byte> src);
|
||||
void write(std::span<const std::byte, 1> src);
|
||||
|
||||
template <typename T>
|
||||
AutoFile& operator<<(const T& obj)
|
||||
@ -492,7 +510,7 @@ private:
|
||||
readNow = nAvail;
|
||||
if (readNow == 0)
|
||||
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) {
|
||||
throw std::ios_base::failure{m_src.feof() ? "BufferedFile::Fill: end of file" : "BufferedFile::Fill: fread failed"};
|
||||
}
|
||||
@ -536,7 +554,7 @@ public:
|
||||
}
|
||||
|
||||
//! read a number of bytes
|
||||
void read(Span<std::byte> dst)
|
||||
void read(std::span<std::byte> dst)
|
||||
{
|
||||
while (dst.size() > 0) {
|
||||
auto [buffer_pointer, length]{AdvanceStream(dst.size())};
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -91,7 +91,7 @@ void TestBIP324PacketVector(
|
||||
BOOST_CHECK(out_ciphertext == ciphertext);
|
||||
} else {
|
||||
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) {
|
||||
@ -121,8 +121,8 @@ void TestBIP324PacketVector(
|
||||
for (uint32_t i = 0; i < dec_idx; ++i) {
|
||||
unsigned use_idx = i < in_idx ? i : 0;
|
||||
bool dec_ignore{false};
|
||||
dec_cipher.DecryptLength(Span{dummies[use_idx]}.first(cipher.LENGTH_LEN));
|
||||
dec_cipher.Decrypt(Span{dummies[use_idx]}.subspan(cipher.LENGTH_LEN), {}, dec_ignore, {});
|
||||
dec_cipher.DecryptLength(std::span{dummies[use_idx]}.first(cipher.LENGTH_LEN));
|
||||
dec_cipher.Decrypt(std::span{dummies[use_idx]}.subspan(cipher.LENGTH_LEN), {}, dec_ignore, {});
|
||||
}
|
||||
|
||||
// Construct copied (and possibly damaged) copy of ciphertext.
|
||||
@ -147,7 +147,7 @@ void TestBIP324PacketVector(
|
||||
// Decrypt contents.
|
||||
std::vector<std::byte> decrypted(dec_len);
|
||||
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.
|
||||
BOOST_CHECK(dec_ok == !error);
|
||||
|
@ -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
|
||||
// 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;
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
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 {
|
||||
rng.Keystream(Span{outres}.subspan(pos, lens[j]));
|
||||
rng.Keystream(std::span{outres}.subspan(pos, lens[j]));
|
||||
}
|
||||
pos += lens[j];
|
||||
}
|
||||
@ -237,7 +237,7 @@ void TestPoly1305(const std::string &hexmessage, const std::string &hexkey, cons
|
||||
// Test incremental interface
|
||||
for (int splits = 0; splits < 10; ++splits) {
|
||||
for (int iter = 0; iter < 10; ++iter) {
|
||||
auto data = Span{m};
|
||||
auto data = std::span{m};
|
||||
Poly1305 poly1305{key};
|
||||
for (int chunk = 0; chunk < splits; ++chunk) {
|
||||
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) {
|
||||
aead.Encrypt(plain, aad, nonce, cipher);
|
||||
} 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);
|
||||
|
||||
@ -277,7 +277,7 @@ void TestChaCha20Poly1305(const std::string& plain_hex, const std::string& aad_h
|
||||
if (i == 0) {
|
||||
ret = aead.Decrypt(cipher, aad, nonce, decipher);
|
||||
} 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(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.
|
||||
FSChaCha20Poly1305 enc_aead{key, 224};
|
||||
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.
|
||||
if (it == 0) {
|
||||
enc_aead.Encrypt(plain, aad, cipher);
|
||||
} 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);
|
||||
|
||||
// Do msg_idx dummy decryptions to seek to the correct packet.
|
||||
FSChaCha20Poly1305 dec_aead{key, 224};
|
||||
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.
|
||||
@ -331,7 +331,7 @@ void TestFSChaCha20Poly1305(const std::string& plain_hex, const std::string& aad
|
||||
if (it == 0) {
|
||||
ret = dec_aead.Decrypt(cipher, aad, decipher);
|
||||
} 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(decipher == plain);
|
||||
@ -843,9 +843,9 @@ BOOST_AUTO_TEST_CASE(chacha20_midblock)
|
||||
c20.Keystream(b2);
|
||||
c20.Keystream(b3);
|
||||
|
||||
BOOST_CHECK(std::ranges::equal(Span{block}.first(5), b1));
|
||||
BOOST_CHECK(std::ranges::equal(Span{block}.subspan(5, 7), b2));
|
||||
BOOST_CHECK(std::ranges::equal(Span{block}.last(52), b3));
|
||||
BOOST_CHECK(std::ranges::equal(std::span{block}.first(5), b1));
|
||||
BOOST_CHECK(std::ranges::equal(std::span{block}.subspan(5, 7), b2));
|
||||
BOOST_CHECK(std::ranges::equal(std::span{block}.last(52), b3));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(poly1305_testvector)
|
||||
@ -1079,7 +1079,7 @@ BOOST_AUTO_TEST_CASE(sha256d64)
|
||||
in[j] = m_rng.randbits(8);
|
||||
}
|
||||
for (int j = 0; j < i; ++j) {
|
||||
CHash256().Write({in + 64 * j, 64}).Finalize({out1 + 32 * j, 32});
|
||||
CHash256().Write(std::span{in + 64 * j, 64}).Finalize({out1 + 32 * j, 32});
|
||||
}
|
||||
SHA256D64(out2, in, i);
|
||||
BOOST_CHECK(memcmp(out1, out2, 32 * i) == 0);
|
||||
@ -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 s2 = m_rng.randrange(in_bytes.size() + 1 - s1);
|
||||
int s3 = in_bytes.size() - s1 - s2;
|
||||
sha.Write(Span{in_bytes}.first(s1)).Write(Span{in_bytes}.subspan(s1, s2));
|
||||
sha.Write(Span{in_bytes}.last(s3)).Finalize(out);
|
||||
sha.Write(std::span{in_bytes}.first(s1)).Write(std::span{in_bytes}.subspan(s1, s2));
|
||||
sha.Write(std::span{in_bytes}.last(s3)).Finalize(out);
|
||||
BOOST_CHECK(std::equal(std::begin(out_bytes), std::end(out_bytes), out));
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
// 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()) {
|
||||
KeyOriginInfo info;
|
||||
Span<const char> origin_sp{origin_str};
|
||||
std::vector<Span<const char>> origin_split = Split(origin_sp, "/");
|
||||
std::span<const char> origin_sp{origin_str};
|
||||
std::vector<std::span<const char>> origin_split = Split(origin_sp, "/");
|
||||
std::string fpr_str(origin_split[0].begin(), origin_split[0].end());
|
||||
auto fpr_bytes = ParseHex(fpr_str);
|
||||
std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.fingerprint);
|
||||
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;
|
||||
if (elem.size() > 0) {
|
||||
const char last = elem[elem.size() - 1];
|
||||
|
@ -29,14 +29,14 @@ FUZZ_TARGET(autofile)
|
||||
[&] {
|
||||
std::array<std::byte, 4096> arr{};
|
||||
try {
|
||||
auto_file.read({arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)});
|
||||
auto_file.read(std::span{arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)});
|
||||
} catch (const std::ios_base::failure&) {
|
||||
}
|
||||
},
|
||||
[&] {
|
||||
const std::array<std::byte, 4096> arr{};
|
||||
try {
|
||||
auto_file.write({arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)});
|
||||
auto_file.write(std::span{arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)});
|
||||
} catch (const std::ios_base::failure&) {
|
||||
}
|
||||
},
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -106,7 +106,7 @@ FUZZ_TARGET(bip324_cipher_roundtrip, .init=Initialize)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
assert(dec_length == length);
|
||||
} else {
|
||||
@ -119,7 +119,7 @@ FUZZ_TARGET(bip324_cipher_roundtrip, .init=Initialize)
|
||||
// Decrypt
|
||||
std::vector<std::byte> decrypt(dec_length);
|
||||
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.
|
||||
assert(!ok == damage);
|
||||
if (!ok) break;
|
||||
|
@ -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
|
||||
// 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
|
||||
// to 0x00 input bytes.
|
||||
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 {
|
||||
crypt2.Keystream(Span{data2}.subspan(bytes2, now));
|
||||
crypt2.Keystream(std::span{data2}.subspan(bytes2, now));
|
||||
}
|
||||
bytes2 += now;
|
||||
if (is_last) break;
|
||||
|
@ -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
|
||||
// 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) {
|
||||
std::byte dummy_tag[FSChaCha20Poly1305::EXPANSION] = {{}};
|
||||
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 {
|
||||
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) {
|
||||
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 {
|
||||
aead.Encrypt(plain, aad, nonce, cipher);
|
||||
}
|
||||
@ -102,7 +102,7 @@ FUZZ_TARGET(crypto_aeadchacha20poly1305)
|
||||
|
||||
if (use_splits && length > 0) {
|
||||
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 {
|
||||
ok = aead.Decrypt(cipher, aad, nonce, decrypted_contents);
|
||||
}
|
||||
@ -152,7 +152,7 @@ FUZZ_TARGET(crypto_fschacha20poly1305)
|
||||
crypt_till_rekey(enc_aead, rekey_interval, true);
|
||||
if (use_splits && length > 0) {
|
||||
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 {
|
||||
enc_aead.Encrypt(plain, aad, cipher);
|
||||
}
|
||||
@ -187,7 +187,7 @@ FUZZ_TARGET(crypto_fschacha20poly1305)
|
||||
crypt_till_rekey(dec_aead, rekey_interval, false);
|
||||
if (use_splits && length > 0) {
|
||||
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 {
|
||||
ok = dec_aead.Decrypt(cipher, aad, decrypted_contents);
|
||||
}
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
namespace {
|
||||
|
||||
/** 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;
|
||||
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
|
||||
* 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);
|
||||
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};
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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_le = true;
|
||||
|
@ -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
|
||||
// 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::vector<unsigned char> data = ParseHex(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);
|
||||
if (IsHex(random_hex_string)) {
|
||||
assert(ToLower(random_hex_string) == hex_data);
|
||||
|
@ -236,10 +236,6 @@ FUZZ_TARGET(integer, .init = initialize_integer)
|
||||
const uint16_t deserialized_u16 = ser_readdata16(stream);
|
||||
assert(u16 == deserialized_u16 && stream.empty());
|
||||
|
||||
ser_writedata16be(stream, u16);
|
||||
const uint16_t deserialized_u16be = ser_readdata16be(stream);
|
||||
assert(u16 == deserialized_u16be && stream.empty());
|
||||
|
||||
ser_writedata8(stream, u8);
|
||||
const uint8_t deserialized_u8 = ser_readdata8(stream);
|
||||
assert(u8 == deserialized_u8 && stream.empty());
|
||||
|
@ -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
|
||||
// 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);
|
||||
if (it == TEST_DATA.dummy_key_idx_map.end()) return {};
|
||||
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 {
|
||||
@ -290,7 +290,7 @@ const struct CheckerContext: BaseSignatureChecker {
|
||||
if (it == TEST_DATA.dummy_sigs.end()) return false;
|
||||
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 {
|
||||
XOnlyPubKey pk{pubkey};
|
||||
auto it = TEST_DATA.schnorr_sigs.find(pk);
|
||||
|
@ -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
|
||||
// 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,
|
||||
* 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() <= 768);
|
||||
@ -36,7 +36,7 @@ public:
|
||||
|
||||
/** Serialize an arithm_uint6144 to any multiply of 4 bytes in LE notation,
|
||||
* 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() <= 768);
|
||||
for (unsigned i = 0; i * 4 < bytes.size(); ++i) {
|
||||
|
@ -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
|
||||
// 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());
|
||||
Span<const uint8_t> msg_bytes{mutable_msg_bytes};
|
||||
std::span<const uint8_t> msg_bytes{mutable_msg_bytes};
|
||||
while (msg_bytes.size() > 0) {
|
||||
if (!recv_transport.ReceivedBytes(msg_bytes)) {
|
||||
break;
|
||||
@ -87,7 +87,7 @@ FUZZ_TARGET(p2p_transport_serialization, .init = initialize_p2p_transport_serial
|
||||
assert(msg.m_time == m_time);
|
||||
|
||||
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);
|
||||
assert(queued);
|
||||
std::optional<bool> known_more;
|
||||
@ -191,7 +191,7 @@ void SimulationTest(Transport& initiator, Transport& responder, R& rng, FuzzedDa
|
||||
if (more_nonext) assert(more_next);
|
||||
// Compare with previously reported output.
|
||||
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());
|
||||
std::copy(bytes.begin(), bytes.end(), to_send[side].begin());
|
||||
// Remember 'more' results.
|
||||
@ -252,7 +252,7 @@ void SimulationTest(Transport& initiator, Transport& responder, R& rng, FuzzedDa
|
||||
// Decide span to receive
|
||||
size_t to_recv_len = in_flight[side].size();
|
||||
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
|
||||
while (!to_recv.empty()) {
|
||||
size_t old_len = to_recv.size();
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -25,11 +25,11 @@ class PoolResourceFuzzer
|
||||
size_t m_total_allocated{};
|
||||
|
||||
struct Entry {
|
||||
Span<std::byte> span;
|
||||
std::span<std::byte> span;
|
||||
size_t alignment;
|
||||
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;
|
||||
@ -48,7 +48,7 @@ public:
|
||||
assert((alignment & (alignment - 1)) == 0); // Alignment must be power of 2.
|
||||
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;
|
||||
|
||||
auto ptr_val = reinterpret_cast<std::uintptr_t>(span.data());
|
||||
|
@ -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
|
||||
// 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 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 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);
|
||||
|
||||
mut_span = const_span;
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -29,7 +29,7 @@ public:
|
||||
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();
|
||||
}
|
||||
|
@ -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
|
||||
// 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());
|
||||
|
||||
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.begin();
|
||||
(void)span.end();
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#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;
|
||||
if (compressed) {
|
||||
|
@ -87,7 +87,7 @@ void utxo_snapshot_fuzz(FuzzBufferType buffer)
|
||||
// Metadata
|
||||
if (fuzzed_data_provider.ConsumeBool()) {
|
||||
std::vector<uint8_t> metadata{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
|
||||
outfile << Span{metadata};
|
||||
outfile << std::span{metadata};
|
||||
} else {
|
||||
auto msg_start = chainman.GetParams().MessageStart();
|
||||
int base_blockheight{fuzzed_data_provider.ConsumeIntegralInRange<int>(1, 2 * COINBASE_MATURITY)};
|
||||
@ -99,7 +99,7 @@ void utxo_snapshot_fuzz(FuzzBufferType buffer)
|
||||
// Coins
|
||||
if (fuzzed_data_provider.ConsumeBool()) {
|
||||
std::vector<uint8_t> file_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
|
||||
outfile << Span{file_data};
|
||||
outfile << std::span{file_data};
|
||||
} else {
|
||||
int height{0};
|
||||
for (const auto& block : *g_chain) {
|
||||
|
@ -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.
|
||||
*/
|
||||
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());
|
||||
// Local RNG, only used for the seeds to initialize T objects with.
|
||||
|
@ -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
|
||||
// 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)
|
||||
{
|
||||
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
|
||||
CSipHasher hasher3(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL);
|
||||
|
@ -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
|
||||
// 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());
|
||||
|
||||
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();
|
||||
if (!key.IsCompressed()) {
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -272,7 +272,7 @@ public:
|
||||
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 {
|
||||
XOnlyPubKey pk{pubkey};
|
||||
auto it = g_testdata->schnorr_signatures.find(pk);
|
||||
|
@ -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
|
||||
// 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;
|
||||
CaptureMessage = [&sent, &expected](const CAddress& addr,
|
||||
const std::string& msg_type,
|
||||
Span<const unsigned char> data,
|
||||
std::span<const unsigned char> data,
|
||||
bool is_incoming) -> void {
|
||||
if (!is_incoming && msg_type == "addr") {
|
||||
DataStream s{data};
|
||||
@ -1054,7 +1054,7 @@ public:
|
||||
bool progress{false};
|
||||
// Send bytes from m_to_send to the transport.
|
||||
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();
|
||||
if (!m_transport.ReceivedBytes(to_send)) {
|
||||
return std::nullopt; // transport error occurred
|
||||
@ -1099,7 +1099,7 @@ public:
|
||||
BIP324Cipher& GetCipher() { return m_cipher; }
|
||||
|
||||
/** 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());
|
||||
}
|
||||
@ -1114,13 +1114,13 @@ public:
|
||||
}
|
||||
|
||||
/** 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. */
|
||||
void SendKey() { Send(m_cipher.GetOurPubKey()); }
|
||||
|
||||
/** 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).
|
||||
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
|
||||
* (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.
|
||||
std::vector<std::byte> ciphertext;
|
||||
@ -1189,9 +1189,9 @@ public:
|
||||
}
|
||||
|
||||
/** 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.
|
||||
if (!m_sent_aad) aad = m_sent_garbage;
|
||||
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
|
||||
* (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. */
|
||||
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;
|
||||
// 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.
|
||||
BOOST_REQUIRE(m_received.size() >= BIP324Cipher::LENGTH_LEN);
|
||||
// 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.
|
||||
BOOST_REQUIRE(m_received.size() >= size + BIP324Cipher::EXPANSION);
|
||||
// Decrypt the packet contents.
|
||||
@ -1217,7 +1217,7 @@ public:
|
||||
bool ignore{false};
|
||||
bool ret = m_cipher.Decrypt(
|
||||
/*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,
|
||||
/*ignore=*/ignore,
|
||||
/*contents=*/MakeWritableByteSpan(contents));
|
||||
@ -1240,7 +1240,7 @@ public:
|
||||
size_t garblen;
|
||||
for (garblen = 0; garblen <= V2Transport::MAX_GARBAGE_LEN; ++garblen) {
|
||||
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;
|
||||
}
|
||||
// Copy the garbage to a buffer.
|
||||
@ -1261,17 +1261,17 @@ public:
|
||||
|
||||
/** Expect application packet to have been received, with specified short id and payload.
|
||||
* (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();
|
||||
BOOST_CHECK(ret.size() == payload.size() + 1);
|
||||
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
|
||||
* 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();
|
||||
BOOST_REQUIRE(ret.size() == payload.size() + 1 + CMessageHeader::MESSAGE_TYPE_SIZE);
|
||||
@ -1283,12 +1283,12 @@ public:
|
||||
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
|
||||
* 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.
|
||||
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
|
||||
* 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.
|
||||
std::vector<uint8_t> contents(1 + payload.size());
|
||||
|
@ -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
|
||||
// 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 {
|
||||
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) {
|
||||
// Ignore sends after end of script, or sends when we expect a receive.
|
||||
FailScript();
|
||||
|
@ -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
|
||||
// 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;
|
||||
|
||||
auto data = std::vector<Span<uint8_t>>();
|
||||
auto data = std::vector<std::span<uint8_t>>();
|
||||
|
||||
// allocate an increasing number of bytes
|
||||
for (uint8_t num_bytes = 0; num_bytes < num_allocs; ++num_bytes) {
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -258,7 +258,7 @@ public:
|
||||
CScript scriptPubKey = script;
|
||||
if (wm == WitnessMode::PKH) {
|
||||
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;
|
||||
scriptPubKey = CScript() << witnessversion << ToByteVector(hash);
|
||||
} else if (wm == WitnessMode::SH) {
|
||||
@ -1719,8 +1719,8 @@ BOOST_AUTO_TEST_CASE(compute_tapleaf)
|
||||
constexpr uint256 tlc0{"edbc10c272a1215dcdcc11d605b9027b5ad6ed97cd45521203f136767b5b9c06"};
|
||||
constexpr uint256 tlc2{"8b5c4f90ae6bf76e259dbef5d8a59df06359c391b59263741b25eca76451b27a"};
|
||||
|
||||
BOOST_CHECK_EQUAL(ComputeTapleafHash(0xc0, Span(script)), tlc0);
|
||||
BOOST_CHECK_EQUAL(ComputeTapleafHash(0xc2, Span(script)), tlc2);
|
||||
BOOST_CHECK_EQUAL(ComputeTapleafHash(0xc0, std::span(script)), tlc0);
|
||||
BOOST_CHECK_EQUAL(ComputeTapleafHash(0xc2, std::span(script)), tlc2);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
@ -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
|
||||
// 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;
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
BOOST_CHECK(n == 0xfd);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@ -269,10 +269,10 @@ BOOST_AUTO_TEST_CASE(class_methods)
|
||||
{
|
||||
DataStream ds;
|
||||
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::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(1), std::byte{'b'});
|
||||
BOOST_CHECK_EQUAL(out_3, std::byte{'c'});
|
||||
@ -304,7 +304,7 @@ public:
|
||||
if (s.template GetParams<BaseFormat>().m_base_format == BaseFormat::RAW) {
|
||||
s << m_base_data;
|
||||
} 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;
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -9,13 +9,13 @@
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
namespace spannable {
|
||||
struct Ignore
|
||||
{
|
||||
template<typename T> Ignore(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;
|
||||
}
|
||||
@ -24,47 +24,36 @@ bool Spannable(Ignore)
|
||||
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
|
||||
{
|
||||
int* data();
|
||||
int* begin();
|
||||
int* end();
|
||||
size_t size();
|
||||
};
|
||||
struct SpannableNo
|
||||
{
|
||||
void* data();
|
||||
void data();
|
||||
size_t size();
|
||||
};
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
} // namespace
|
||||
} // namespace spannable
|
||||
|
||||
using namespace spannable;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(span_tests)
|
||||
|
||||
// Make sure template Span template deduction guides accurately enable calls to
|
||||
// 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
|
||||
// Make sure template std::span template deduction guides accurately enable calls to
|
||||
// std::span constructor overloads that work, and disable calls to constructor overloads that
|
||||
// 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
|
||||
// aren't compatible with Spans 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.
|
||||
// aren't compatible with std::span at compile time.
|
||||
BOOST_AUTO_TEST_CASE(span_constructor_sfinae)
|
||||
{
|
||||
BOOST_CHECK(Spannable(std::vector<int>{}));
|
||||
BOOST_CHECK(!Spannable(std::set<int>{}));
|
||||
BOOST_CHECK(!Spannable(std::vector<bool>{}));
|
||||
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(SpannableYes{}));
|
||||
BOOST_CHECK(!Spannable(SpannableNo{}));
|
||||
|
@ -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
|
||||
// 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
|
||||
AutoFile non_xor_file{raw_file("rb")};
|
||||
std::vector<std::byte> raw(7);
|
||||
non_xor_file >> Span{raw};
|
||||
non_xor_file >> std::span{raw};
|
||||
BOOST_CHECK_EQUAL(HexStr(raw), "fc01fd03fd04fa");
|
||||
// Check that no padding exists
|
||||
BOOST_CHECK_EXCEPTION(non_xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: end of file"});
|
||||
|
@ -392,7 +392,7 @@ void SanityCheck(const DepGraph<SetType>& depgraph)
|
||||
|
||||
/** Perform a sanity check on a linearization. */
|
||||
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.
|
||||
assert(linearization.size() == depgraph.TxCount());
|
||||
|
@ -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
|
||||
// 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));
|
||||
if (complete) {
|
||||
@ -279,7 +279,7 @@ std::optional<CNetMessage> DynSock::Pipe::GetNetMsg()
|
||||
}
|
||||
|
||||
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.
|
||||
return std::nullopt;
|
||||
}
|
||||
|
@ -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
|
||||
// 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);
|
||||
}
|
||||
|
||||
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;
|
||||
void FlushSendBuffer(CNode& node) const;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user