From 35f1c94672c2260a05b95277a1f03ab616cb410c Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Fri, 22 Sep 2023 13:24:24 +0530 Subject: [PATCH 01/21] refactor: wrap P2PK scriptPubKey range into Span Co-authored-by: Konstantin Akimov --- src/txmempool.cpp | 6 +++--- src/validation.cpp | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index aae9e0d61c959..8328db1167a7d 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -487,7 +487,7 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC mapAddress.insert(std::make_pair(key, delta)); inserted.push_back(key); } else if (prevout.scriptPubKey.IsPayToPublicKey()) { - uint160 hashBytes(Hash160(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.end()-1)); + uint160 hashBytes{Hash160(Span{prevout.scriptPubKey.data()+1, prevout.scriptPubKey.size() - 2})}; CMempoolAddressDeltaKey key(1, hashBytes, txhash, j, 1); CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n); mapAddress.insert(std::make_pair(key, delta)); @@ -509,7 +509,7 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC mapAddress.insert(std::make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue))); inserted.push_back(key); } else if (out.scriptPubKey.IsPayToPublicKey()) { - uint160 hashBytes(Hash160(out.scriptPubKey.begin()+1, out.scriptPubKey.end()-1)); + uint160 hashBytes{Hash160(Span{out.scriptPubKey.data()+1, out.scriptPubKey.size() - 2})}; std::pair ret; CMempoolAddressDeltaKey key(1, hashBytes, txhash, k, 0); mapAddress.insert(std::make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue))); @@ -572,7 +572,7 @@ void CTxMemPool::addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCac addressHash = uint160(std::vector (prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23)); addressType = 1; } else if (prevout.scriptPubKey.IsPayToPublicKey()) { - addressHash = Hash160(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.end()-1); + addressHash = Hash160(Span{prevout.scriptPubKey.data()+1, prevout.scriptPubKey.size() - 2}); addressType = 1; } else { addressHash.SetNull(); diff --git a/src/validation.cpp b/src/validation.cpp index 845e9ba229c13..e195e0b97067f 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1726,7 +1726,7 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(1, uint160(hashBytes), hash, k), CAddressUnspentValue())); } else if (out.scriptPubKey.IsPayToPublicKey()) { - uint160 hashBytes(Hash160(out.scriptPubKey.begin()+1, out.scriptPubKey.end()-1)); + uint160 hashBytes{Hash160(Span{out.scriptPubKey.data()+1, out.scriptPubKey.size() - 2})}; addressIndex.push_back(std::make_pair(CAddressIndexKey(1, hashBytes, pindex->nHeight, i, hash, k, false), out.nValue)); addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(1, hashBytes, hash, k), CAddressUnspentValue())); } else { @@ -1794,7 +1794,7 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(1, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undoHeight))); } else if (prevout.scriptPubKey.IsPayToPublicKey()) { - uint160 hashBytes(Hash160(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.end()-1)); + uint160 hashBytes{Hash160(Span{prevout.scriptPubKey.data()+1, prevout.scriptPubKey.size()-2})}; // undo spending activity addressIndex.push_back(std::make_pair(CAddressIndexKey(1, hashBytes, pindex->nHeight, i, hash, j, true), prevout.nValue * -1)); // restore unspent index @@ -2265,7 +2265,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, hashBytes = uint160(std::vector(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23)); addressType = 1; } else if (prevout.scriptPubKey.IsPayToPublicKey()) { - hashBytes = Hash160(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.end()-1); + hashBytes = Hash160(Span{prevout.scriptPubKey.data()+1, prevout.scriptPubKey.size()-2}); addressType = 1; } else { hashBytes.SetNull(); @@ -2341,7 +2341,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(1, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight))); } else if (out.scriptPubKey.IsPayToPublicKey()) { - uint160 hashBytes(Hash160(out.scriptPubKey.begin()+1, out.scriptPubKey.end()-1)); + uint160 hashBytes{Hash160(Span{out.scriptPubKey.data()+1, out.scriptPubKey.size()-2})}; addressIndex.push_back(std::make_pair(CAddressIndexKey(1, hashBytes, pindex->nHeight, i, txhash, k, false), out.nValue)); addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(1, hashBytes, txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight))); } else { @@ -4871,7 +4871,7 @@ bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& i hashBytes = uint160(std::vector(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23)); addressType = 1; } else if (prevout.scriptPubKey.IsPayToPublicKey()) { - hashBytes = Hash160(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.end()-1); + hashBytes = Hash160(Span{prevout.scriptPubKey.data()+1, prevout.scriptPubKey.size()-2}); addressType = 1; } else { hashBytes.SetNull(); @@ -4917,7 +4917,7 @@ bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& i addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(1, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight))); } else if (out.scriptPubKey.IsPayToPublicKey()) { - uint160 hashBytes(Hash160(out.scriptPubKey.begin()+1, out.scriptPubKey.end()-1)); + uint160 hashBytes{Hash160(Span{out.scriptPubKey.data()+1, out.scriptPubKey.size()-2})}; addressIndex.push_back(std::make_pair(CAddressIndexKey(1, hashBytes, pindex->nHeight, i, txhash, k, false), out.nValue)); addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(1, hashBytes, txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight))); } else { From 7ddf2ff59b1172208ea8e43683c7df64dc94933f Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Wed, 20 Sep 2023 16:58:43 +0530 Subject: [PATCH 02/21] refactor: remove unused Hash function variants The three object variant was removed in dash#3276 through the backport of bitcoin#11385, leaving behind the four, five and six variant options. They aren't used anywhere in the codebase and aren't present in Bitcoin Core currently, and so, have been removed. --- src/hash.h | 54 ------------------------------------------------------ 1 file changed, 54 deletions(-) diff --git a/src/hash.h b/src/hash.h index 80322a163e5da..4be5e9c72fc71 100644 --- a/src/hash.h +++ b/src/hash.h @@ -106,60 +106,6 @@ inline uint256 Hash(const T1 p1begin, const T1 p1end, return result; } -/** Compute the 256-bit hash of the concatenation of three objects. */ -template -inline uint256 Hash(const T1 p1begin, const T1 p1end, - const T2 p2begin, const T2 p2end, - const T3 p3begin, const T3 p3end, - const T4 p4begin, const T4 p4end) { - static const unsigned char pblank[1] = {}; - uint256 result; - CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])) - .Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])) - .Write(p3begin == p3end ? pblank : (const unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0])) - .Write(p4begin == p4end ? pblank : (const unsigned char*)&p4begin[0], (p4end - p4begin) * sizeof(p4begin[0])) - .Finalize((unsigned char*)&result); - return result; -} - -/** Compute the 256-bit hash of the concatenation of three objects. */ -template -inline uint256 Hash(const T1 p1begin, const T1 p1end, - const T2 p2begin, const T2 p2end, - const T3 p3begin, const T3 p3end, - const T4 p4begin, const T4 p4end, - const T5 p5begin, const T5 p5end) { - static const unsigned char pblank[1] = {}; - uint256 result; - CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])) - .Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])) - .Write(p3begin == p3end ? pblank : (const unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0])) - .Write(p4begin == p4end ? pblank : (const unsigned char*)&p4begin[0], (p4end - p4begin) * sizeof(p4begin[0])) - .Write(p5begin == p5end ? pblank : (const unsigned char*)&p5begin[0], (p5end - p5begin) * sizeof(p5begin[0])) - .Finalize((unsigned char*)&result); - return result; -} - -/** Compute the 256-bit hash of the concatenation of three objects. */ -template -inline uint256 Hash(const T1 p1begin, const T1 p1end, - const T2 p2begin, const T2 p2end, - const T3 p3begin, const T3 p3end, - const T4 p4begin, const T4 p4end, - const T5 p5begin, const T5 p5end, - const T6 p6begin, const T6 p6end) { - static const unsigned char pblank[1] = {}; - uint256 result; - CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])) - .Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])) - .Write(p3begin == p3end ? pblank : (const unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0])) - .Write(p4begin == p4end ? pblank : (const unsigned char*)&p4begin[0], (p4end - p4begin) * sizeof(p4begin[0])) - .Write(p5begin == p5end ? pblank : (const unsigned char*)&p5begin[0], (p5end - p5begin) * sizeof(p5begin[0])) - .Write(p6begin == p6end ? pblank : (const unsigned char*)&p6begin[0], (p6end - p6begin) * sizeof(p6begin[0])) - .Finalize((unsigned char*)&result); - return result; -} - /** Compute the 160-bit hash an object. */ template inline uint160 Hash160(const T1 pbegin, const T1 pend) From 65ff12c303f1ca8303e608209fa101b066f6f508 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Fri, 8 Sep 2023 19:04:57 +0530 Subject: [PATCH 03/21] merge bitcoin#19326: Simplify hash.h interface using Spans includes: - 2a2182c387f607cd8284f33890bd285a81077b7f - 77c507358bda9bd6c496f33e0f4418c0603bb08d completion of partial merge done in dash#4164 as 56f1b2d (blocker bitcoin#17938 was merged in dash#5246 as 00802bb) --- src/base58.cpp | 4 ++-- src/flat-database.h | 4 ++-- src/hash.h | 35 +++++++------------------------- src/hdchain.cpp | 2 +- src/merkleblock.cpp | 4 ++-- src/net.cpp | 2 +- src/netaddress.cpp | 2 +- src/pubkey.h | 4 ++-- src/script/standard.cpp | 5 ++--- src/test/fuzz/crypto.cpp | 2 +- src/test/fuzz/key.cpp | 2 +- src/test/key_tests.cpp | 8 ++++---- src/test/merkle_tests.cpp | 7 +++---- src/test/serialize_tests.cpp | 4 ++-- src/test/util_tests.cpp | 4 ++-- src/util/hash_type.h | 3 +++ src/wallet/test/wallet_tests.cpp | 2 +- src/wallet/walletdb.cpp | 8 ++++---- 18 files changed, 41 insertions(+), 61 deletions(-) diff --git a/src/base58.cpp b/src/base58.cpp index 36d00120664c8..b505d52583c4e 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -136,7 +136,7 @@ std::string EncodeBase58Check(Span input) { // add 4-byte hash check to the end std::vector vch(input.begin(), input.end()); - uint256 hash = Hash(vch.begin(), vch.end()); + uint256 hash = Hash(vch); vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4); return EncodeBase58(vch); } @@ -149,7 +149,7 @@ bool DecodeBase58Check(const char* psz, std::vector& vchRet, int return false; } // re-calculate the checksum, ensure it matches the included 4-byte checksum - uint256 hash = Hash(vchRet.begin(), vchRet.end() - 4); + uint256 hash = Hash(MakeSpan(vchRet).first(vchRet.size() - 4)); if (memcmp(&hash, &vchRet[vchRet.size() - 4], 4) != 0) { vchRet.clear(); return false; diff --git a/src/flat-database.h b/src/flat-database.h index 405707677244c..c08c42a5e3991 100644 --- a/src/flat-database.h +++ b/src/flat-database.h @@ -47,7 +47,7 @@ class CFlatDB ssObj << strMagicMessage; // specific magic message for this type of object ssObj << Params().MessageStart(); // network specific magic number ssObj << objToSave; - uint256 hash = Hash(ssObj.begin(), ssObj.end()); + uint256 hash = Hash(ssObj); ssObj << hash; // open output file, and associate with CAutoFile @@ -109,7 +109,7 @@ class CFlatDB CDataStream ssObj(vchData, SER_DISK, CLIENT_VERSION); // verify stored checksum matches input data - uint256 hashTmp = Hash(ssObj.begin(), ssObj.end()); + uint256 hashTmp = Hash(ssObj); if (hashIn != hashTmp) { error("%s: Checksum mismatch, data corrupted", __func__); diff --git a/src/hash.h b/src/hash.h index 4be5e9c72fc71..ce48d77bda5d1 100644 --- a/src/hash.h +++ b/src/hash.h @@ -84,52 +84,31 @@ class CHash160 { }; /** Compute the 256-bit hash of an object. */ -template -inline uint256 Hash(const T1 pbegin, const T1 pend) +template +inline uint256 Hash(const T& in1) { - static const unsigned char pblank[1] = {}; uint256 result; - CHash256().Write({pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0])}) - .Finalize(result); + CHash256().Write(MakeUCharSpan(in1)).Finalize(result); return result; } /** Compute the 256-bit hash of the concatenation of two objects. */ template -inline uint256 Hash(const T1 p1begin, const T1 p1end, - const T2 p2begin, const T2 p2end) { - static const unsigned char pblank[1] = {}; +inline uint256 Hash(const T1& in1, const T2& in2) { uint256 result; - CHash256().Write({p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])}) - .Write({p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])}) - .Finalize(result); + CHash256().Write(MakeUCharSpan(in1)).Write(MakeUCharSpan(in2)).Finalize(result); return result; } /** Compute the 160-bit hash an object. */ template -inline uint160 Hash160(const T1 pbegin, const T1 pend) +inline uint160 Hash160(const T1& in1) { - static unsigned char pblank[1] = {}; uint160 result; - CHash160().Write({pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0])}) - .Finalize(result); + CHash160().Write(MakeUCharSpan(in1)).Finalize(result); return result; } -/** Compute the 160-bit hash of a vector. */ -inline uint160 Hash160(const std::vector& vch) -{ - return Hash160(vch.begin(), vch.end()); -} - -/** Compute the 160-bit hash of a vector. */ -template -inline uint160 Hash160(const prevector& vch) -{ - return Hash160(vch.begin(), vch.end()); -} - /** A writer stream (for serialization) that computes a 256-bit hash. */ class CHashWriter { diff --git a/src/hdchain.cpp b/src/hdchain.cpp index 12852f4d8e9bb..43e7b397fe1a7 100644 --- a/src/hdchain.cpp +++ b/src/hdchain.cpp @@ -153,7 +153,7 @@ SecureVector CHDChain::GetSeed() const uint256 CHDChain::GetSeedHash() { LOCK(cs); - return Hash(vchSeed.begin(), vchSeed.end()); + return Hash(vchSeed); } void CHDChain::DeriveChildExtKey(uint32_t nAccountIndex, bool fInternal, uint32_t nChildIndex, CExtKey& extKeyRet, KeyOriginInfo& key_origin) diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index c55fab4773502..a53b65bea238f 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -84,7 +84,7 @@ uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::ve else right = left; // combine subhashes - return Hash(left.begin(), left.end(), right.begin(), right.end()); + return Hash(left, right); } } @@ -140,7 +140,7 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns right = left; } // and combine them before returning - return Hash(left.begin(), left.end(), right.begin(), right.end()); + return Hash(left, right); } } diff --git a/src/net.cpp b/src/net.cpp index 5698ad69779cf..65f63fc339ef1 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -850,7 +850,7 @@ std::optional V1TransportDeserializer::GetMessage(int64_t time, uin void V1TransportSerializer::prepareForTransport(CSerializedNetMsg& msg, std::vector& header) { // create dbl-sha256 checksum - uint256 hash = Hash(msg.data.begin(), msg.data.end()); + uint256 hash = Hash(msg.data); // create header CMessageHeader hdr(Params().MessageStart(), msg.command.c_str(), msg.data.size()); diff --git a/src/netaddress.cpp b/src/netaddress.cpp index 5dbd3b544f5ba..378da0627254b 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -830,7 +830,7 @@ std::vector CNetAddr::GetAddrBytes() const uint64_t CNetAddr::GetHash() const { - uint256 hash = Hash(m_addr.begin(), m_addr.end()); + uint256 hash = Hash(m_addr); uint64_t nRet; memcpy(&nRet, &hash, sizeof(nRet)); return nRet; diff --git a/src/pubkey.h b/src/pubkey.h index 9b633972677c0..193b4667ab294 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -157,13 +157,13 @@ class CPubKey //! Get the KeyID of this public key (hash of its serialization) CKeyID GetID() const { - return CKeyID(Hash160(vch, vch + size())); + return CKeyID(Hash160(MakeSpan(vch).first(size()))); } //! Get the 256-bit hash of this public key. uint256 GetHash() const { - return Hash(vch, vch + size()); + return Hash(MakeSpan(vch).first(size())); } /* diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 3f7db837d0a49..3cb5bb4cdab4e 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -13,10 +13,10 @@ typedef std::vector valtype; bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER; unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY; -CScriptID::CScriptID(const CScript& in) : BaseHash(Hash160(in.begin(), in.end())) {} +CScriptID::CScriptID(const CScript& in) : BaseHash(Hash160(in)) {} CScriptID::CScriptID(const ScriptHash& in) : BaseHash(static_cast(in)) {} -ScriptHash::ScriptHash(const CScript& in) : BaseHash(Hash160(in.begin(), in.end())) {} +ScriptHash::ScriptHash(const CScript& in) : BaseHash(Hash160(in)) {} ScriptHash::ScriptHash(const CScriptID& in) : BaseHash(static_cast(in)) {} PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {} @@ -242,7 +242,6 @@ CScript GetScriptForMultisig(int nRequired, const std::vector& keys) return script; } - bool IsValidDestination(const CTxDestination& dest) { return dest.index() != 0; } diff --git a/src/test/fuzz/crypto.cpp b/src/test/fuzz/crypto.cpp index f482b516322ef..40bb2208f2a5d 100644 --- a/src/test/fuzz/crypto.cpp +++ b/src/test/fuzz/crypto.cpp @@ -62,8 +62,8 @@ FUZZ_TARGET(crypto) (void)sha512.Write(data.data(), data.size()); (void)sip_hasher.Write(data.data(), data.size()); + (void)Hash(data); (void)Hash160(data); - (void)Hash160(data.begin(), data.end()); (void)sha512.Size(); }, [&] { diff --git a/src/test/fuzz/key.cpp b/src/test/fuzz/key.cpp index 1c8cfed65e677..686298b80352b 100644 --- a/src/test/fuzz/key.cpp +++ b/src/test/fuzz/key.cpp @@ -81,7 +81,7 @@ FUZZ_TARGET_INIT(key, initialize_key) assert(negated_key == key); } - const uint256 random_uint256 = Hash(buffer.begin(), buffer.end()); + const uint256 random_uint256 = Hash(buffer); { CKey child_key; diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 99ea119e30b3b..dcdd0928dfba9 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(key_test1) for (int n=0; n<16; n++) { std::string strMsg = strprintf("Very secret message %i: 11", n); - uint256 hashMsg = Hash(strMsg.begin(), strMsg.end()); + uint256 hashMsg = Hash(strMsg); // normal signatures @@ -134,7 +134,7 @@ BOOST_AUTO_TEST_CASE(key_test1) std::vector detsig, detsigc; std::string strMsg = "Very deterministic message"; - uint256 hashMsg = Hash(strMsg.begin(), strMsg.end()); + uint256 hashMsg = Hash(strMsg); BOOST_CHECK(key1.Sign(hashMsg, detsig)); BOOST_CHECK(key1C.Sign(hashMsg, detsigc)); BOOST_CHECK(detsig == detsigc); @@ -158,7 +158,7 @@ BOOST_AUTO_TEST_CASE(key_signature_tests) // When entropy is specified, we should see at least one high R signature within 20 signatures CKey key = DecodeSecret(strSecret1); std::string msg = "A message to be signed"; - uint256 msg_hash = Hash(msg.begin(), msg.end()); + uint256 msg_hash = Hash(msg); std::vector sig; bool found = false; @@ -179,7 +179,7 @@ BOOST_AUTO_TEST_CASE(key_signature_tests) for (int i = 0; i < 256; ++i) { sig.clear(); std::string msg = "A message to be signed" + ToString(i); - msg_hash = Hash(msg.begin(), msg.end()); + msg_hash = Hash(msg); BOOST_CHECK(key.Sign(msg_hash, sig)); found = sig[3] == 0x20; BOOST_CHECK(sig.size() <= 70); diff --git a/src/test/merkle_tests.cpp b/src/test/merkle_tests.cpp index 1510a8697a6c0..69fff2835d9cc 100644 --- a/src/test/merkle_tests.cpp +++ b/src/test/merkle_tests.cpp @@ -13,9 +13,9 @@ static uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vecto uint256 hash = leaf; for (std::vector::const_iterator it = vMerkleBranch.begin(); it != vMerkleBranch.end(); ++it) { if (nIndex & 1) { - hash = Hash(it->begin(), it->end(), hash.begin(), hash.end()); + hash = Hash(*it, hash); } else { - hash = Hash(hash.begin(), hash.end(), it->begin(), it->end()); + hash = Hash(hash, *it); } nIndex >>= 1; } @@ -144,8 +144,7 @@ static uint256 BlockBuildMerkleTree(const CBlock& block, bool* fMutated, std::ve // Two identical hashes at the end of the list at a particular level. mutated = true; } - vMerkleTree.push_back(Hash(vMerkleTree[j+i].begin(), vMerkleTree[j+i].end(), - vMerkleTree[j+i2].begin(), vMerkleTree[j+i2].end())); + vMerkleTree.push_back(Hash(vMerkleTree[j+i], vMerkleTree[j+i2])); } j += nSize; } diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index 9690755ff33f7..4dcfff4cc83c4 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE(floats) for (int i = 0; i < 1000; i++) { ss << float(i); } - BOOST_CHECK(Hash(ss.begin(), ss.end()) == uint256S("8e8b4cf3e4df8b332057e3e23af42ebc663b61e0495d5e7e32d85099d7f3fe0c")); + BOOST_CHECK(Hash(ss) == uint256S("8e8b4cf3e4df8b332057e3e23af42ebc663b61e0495d5e7e32d85099d7f3fe0c")); // decode for (int i = 0; i < 1000; i++) { @@ -162,7 +162,7 @@ BOOST_AUTO_TEST_CASE(doubles) for (int i = 0; i < 1000; i++) { ss << double(i); } - BOOST_CHECK(Hash(ss.begin(), ss.end()) == uint256S("43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96")); + BOOST_CHECK(Hash(ss) == uint256S("43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96")); // decode for (int i = 0; i < 1000; i++) { diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index d06bdec5c06a6..4095e2a7396b1 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -2576,8 +2576,8 @@ BOOST_AUTO_TEST_CASE(message_hash) std::string(1, (char)unsigned_tx.length()) + unsigned_tx; - const uint256 signature_hash = Hash(unsigned_tx.begin(), unsigned_tx.end()); - const uint256 message_hash1 = Hash(prefixed_message.begin(), prefixed_message.end()); + const uint256 signature_hash = Hash(unsigned_tx); + const uint256 message_hash1 = Hash(prefixed_message); const uint256 message_hash2 = MessageHash(unsigned_tx); BOOST_CHECK_EQUAL(message_hash1, message_hash2); diff --git a/src/util/hash_type.h b/src/util/hash_type.h index 96771546dc0fd..6113644393626 100644 --- a/src/util/hash_type.h +++ b/src/util/hash_type.h @@ -64,6 +64,9 @@ class BaseHash { return m_hash.size(); } + + unsigned char* data() { return m_hash.data(); } + const unsigned char* data() const { return m_hash.data(); } }; #endif // BITCOIN_UTIL_HASH_TYPE_H diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 98ad52d252c2c..dc72bee749f1f 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -1323,7 +1323,7 @@ static size_t CalculateNestedKeyhashInputSize(bool use_max_sig) CPubKey pubkey = key.GetPubKey(); // Generate pubkey hash - uint160 key_hash(Hash160(pubkey.begin(), pubkey.end())); + uint160 key_hash(Hash160(pubkey)); // Create inner-script to enter into keystore. Key hash can't be 0... CScript inner_script = CScript() << OP_0 << std::vector(key_hash.begin(), key_hash.end()); diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 82ee674140100..9ea4bba0cc532 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -113,7 +113,7 @@ bool WalletBatch::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end()); vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end()); - return WriteIC(std::make_pair(DBKeys::KEY, vchPubKey), std::make_pair(vchPrivKey, Hash(vchKey.begin(), vchKey.end())), false); + return WriteIC(std::make_pair(DBKeys::KEY, vchPubKey), std::make_pair(vchPrivKey, Hash(vchKey)), false); } bool WalletBatch::WriteCryptedKey(const CPubKey& vchPubKey, @@ -125,7 +125,7 @@ bool WalletBatch::WriteCryptedKey(const CPubKey& vchPubKey, } // Compute a checksum of the encrypted key - uint256 checksum = Hash(vchCryptedSecret.begin(), vchCryptedSecret.end()); + uint256 checksum = Hash(vchCryptedSecret); const auto key = std::make_pair(DBKeys::CRYPTED_KEY, vchPubKey); if (!WriteIC(key, std::make_pair(vchCryptedSecret, checksum), false)) { @@ -339,7 +339,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end()); vchKey.insert(vchKey.end(), pkey.begin(), pkey.end()); - if (Hash(vchKey.begin(), vchKey.end()) != hash) + if (Hash(vchKey) != hash) { strErr = "Error reading wallet database: CPubKey/CPrivKey corrupt"; return false; @@ -388,7 +388,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, if (!ssValue.eof()) { uint256 checksum; ssValue >> checksum; - if ((checksum_valid = Hash(vchPrivKey.begin(), vchPrivKey.end()) != checksum)) { + if ((checksum_valid = Hash(vchPrivKey) != checksum)) { strErr = "Error reading wallet database: Crypted key corrupt"; return false; } From dba0dc950153aa74da2bb14330dc4a03aaca0dcd Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Mon, 11 Sep 2023 00:53:19 +0530 Subject: [PATCH 04/21] merge bitcoin#20464: Treat CDataStream bytes as uint8_t --- src/bench/prevector.cpp | 2 +- src/dbwrapper.h | 29 +++++---- src/llmq/dkgsessionhandler.cpp | 2 +- src/psbt.cpp | 2 +- src/qt/recentrequeststablemodel.cpp | 2 +- src/qt/walletmodel.cpp | 2 +- src/rpc/rawtransaction.cpp | 10 +-- src/streams.h | 90 ++++++++------------------ src/support/allocators/zeroafterfree.h | 4 +- src/test/bloom_tests.cpp | 24 ++----- src/test/fuzz/util.h | 2 +- src/test/serialize_tests.cpp | 11 +--- src/test/streams_tests.cpp | 2 +- src/wallet/bdb.cpp | 4 +- 14 files changed, 64 insertions(+), 122 deletions(-) diff --git a/src/bench/prevector.cpp b/src/bench/prevector.cpp index 5075312fe9ae1..36a16ef019c80 100644 --- a/src/bench/prevector.cpp +++ b/src/bench/prevector.cpp @@ -79,7 +79,7 @@ static void PrevectorDeserialize(benchmark::Bench& bench) for (auto x = 0; x < 1000; ++x) { s0 >> t1; } - s0.Init(SER_NETWORK, 0); + s0.Rewind(); }); } diff --git a/src/dbwrapper.h b/src/dbwrapper.h index ff618fcfe06e1..5a86aeedbccf4 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -8,9 +8,10 @@ #include #include #include +#include #include -#include #include +#include #include @@ -82,12 +83,12 @@ class CDBBatch template void Write(const CDataStream& _ssKey, const V& value) { - leveldb::Slice slKey(_ssKey.data(), _ssKey.size()); + leveldb::Slice slKey((const char*)_ssKey.data(), _ssKey.size()); ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE); ssValue << value; ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent)); - leveldb::Slice slValue(ssValue.data(), ssValue.size()); + leveldb::Slice slValue((const char*)ssValue.data(), ssValue.size()); batch.Put(slKey, slValue); // - varint: key length (1 byte up to 127B, 2 bytes up to 16383B, ...) @@ -109,7 +110,7 @@ class CDBBatch } void Erase(const CDataStream& _ssKey) { - leveldb::Slice slKey(_ssKey.data(), _ssKey.size()); + leveldb::Slice slKey((const char*)_ssKey.data(), _ssKey.size()); batch.Delete(slKey); // - byte: header @@ -150,7 +151,7 @@ class CDBIterator } void Seek(const CDataStream& ssKey) { - leveldb::Slice slKey(ssKey.data(), ssKey.size()); + leveldb::Slice slKey((const char*)ssKey.data(), ssKey.size()); piter->Seek(slKey); } @@ -168,7 +169,7 @@ class CDBIterator CDataStream GetKey() { leveldb::Slice slKey = piter->key(); - return CDataStream(slKey.data(), slKey.data() + slKey.size(), SER_DISK, CLIENT_VERSION); + return CDataStream(MakeUCharSpan(slKey), SER_DISK, CLIENT_VERSION); } unsigned int GetKeySize() { @@ -178,7 +179,7 @@ class CDBIterator template bool GetValue(V& value) { leveldb::Slice slValue = piter->value(); try { - CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION); + CDataStream ssValue(MakeUCharSpan(slValue), SER_DISK, CLIENT_VERSION); ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent)); ssValue >> value; } catch (const std::exception&) { @@ -258,7 +259,7 @@ class CDBWrapper bool ReadDataStream(const CDataStream& ssKey, CDataStream& ssValue) const { - leveldb::Slice slKey(ssKey.data(), ssKey.size()); + leveldb::Slice slKey((const char*)ssKey.data(), ssKey.size()); std::string strValue; leveldb::Status status = pdb->Get(readoptions, slKey, &strValue); @@ -268,7 +269,7 @@ class CDBWrapper LogPrintf("LevelDB read failure: %s\n", status.ToString()); dbwrapper_private::HandleError(status); } - CDataStream ssValueTmp(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION); + CDataStream ssValueTmp(MakeUCharSpan(strValue), SER_DISK, CLIENT_VERSION); ssValueTmp.Xor(obfuscate_key); ssValue = std::move(ssValueTmp); return true; @@ -318,7 +319,7 @@ class CDBWrapper bool Exists(const CDataStream& key) const { - leveldb::Slice slKey(key.data(), key.size()); + leveldb::Slice slKey((const char*)key.data(), key.size()); std::string strValue; leveldb::Status status = pdb->Get(readoptions, slKey, &strValue); @@ -362,8 +363,8 @@ class CDBWrapper ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); ssKey1 << key_begin; ssKey2 << key_end; - leveldb::Slice slKey1(ssKey1.data(), ssKey1.size()); - leveldb::Slice slKey2(ssKey2.data(), ssKey2.size()); + leveldb::Slice slKey1((const char*)ssKey1.data(), ssKey1.size()); + leveldb::Slice slKey2((const char*)ssKey2.data(), ssKey2.size()); uint64_t size = 0; leveldb::Range range(slKey1, slKey2); pdb->GetApproximateSizes(&range, 1, &size); @@ -381,8 +382,8 @@ class CDBWrapper ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); ssKey1 << key_begin; ssKey2 << key_end; - leveldb::Slice slKey1(ssKey1.data(), ssKey1.size()); - leveldb::Slice slKey2(ssKey2.data(), ssKey2.size()); + leveldb::Slice slKey1((const char*)ssKey1.data(), ssKey1.size()); + leveldb::Slice slKey2((const char*)ssKey2.data(), ssKey2.size()); pdb->CompactRange(&slKey1, &slKey2); } diff --git a/src/llmq/dkgsessionhandler.cpp b/src/llmq/dkgsessionhandler.cpp index b5f515e13f1bf..4f3ba6d65dbb9 100644 --- a/src/llmq/dkgsessionhandler.cpp +++ b/src/llmq/dkgsessionhandler.cpp @@ -51,7 +51,7 @@ void CDKGPendingMessages::PushPendingMessage(NodeId from, CDataStream& vRecv) auto pm = std::make_shared(std::move(vRecv)); CHashWriter hw(SER_GETHASH, 0); - hw.write(pm->data(), pm->size()); + hw.write(reinterpret_cast(pm->data()), pm->size()); uint256 hash = hw.GetHash(); if (from != -1) { diff --git a/src/psbt.cpp b/src/psbt.cpp index 3c7532c5ce0a9..c5eafb675d513 100644 --- a/src/psbt.cpp +++ b/src/psbt.cpp @@ -461,7 +461,7 @@ bool DecodeBase64PSBT(PartiallySignedTransaction& psbt, const std::string& base6 bool DecodeRawPSBT(PartiallySignedTransaction& psbt, const std::string& tx_data, std::string& error) { - CDataStream ss_data(tx_data.data(), tx_data.data() + tx_data.size(), SER_NETWORK, PROTOCOL_VERSION); + CDataStream ss_data(MakeUCharSpan(tx_data), SER_NETWORK, PROTOCOL_VERSION); try { ss_data >> psbt; if (!ss_data.empty()) { diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 635d14d935fe3..d12c31caa1921 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -181,7 +181,7 @@ void RecentRequestsTableModel::addNewRequest(const SendCoinsRecipient &recipient // called from ctor when loading from wallet void RecentRequestsTableModel::addNewRequest(const std::string &recipient) { - std::vector data(recipient.begin(), recipient.end()); + std::vector data(recipient.begin(), recipient.end()); CDataStream ss(data, SER_DISK, CLIENT_VERSION); RecentRequestEntry entry; diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 8a27a6719dd99..da0ebe9a4b7a6 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -288,7 +288,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << *newTx; - transaction_array.append(ssTx.data(), ssTx.size()); + transaction_array.append((const char*)ssTx.data(), ssTx.size()); } // Add addresses / update labels that we've sent to the address book, diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 15332e71d49a5..bcda6799c515d 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -1306,7 +1306,7 @@ UniValue combinepsbt(const JSONRPCRequest& request) CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << merged_psbt; - return EncodeBase64(ssTx.str()); + return EncodeBase64(ssTx); } UniValue finalizepsbt(const JSONRPCRequest& request) @@ -1434,7 +1434,7 @@ UniValue createpsbt(const JSONRPCRequest& request) CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << psbtx; - return EncodeBase64(ssTx.str()); + return EncodeBase64(ssTx); } UniValue converttopsbt(const JSONRPCRequest& request) @@ -1489,7 +1489,7 @@ UniValue converttopsbt(const JSONRPCRequest& request) CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << psbtx; - return EncodeBase64(ssTx.str()); + return EncodeBase64(ssTx); } UniValue utxoupdatepsbt(const JSONRPCRequest& request) @@ -1573,7 +1573,7 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request) CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << psbtx; - return EncodeBase64(ssTx.str()); + return EncodeBase64(ssTx); } UniValue joinpsbts(const JSONRPCRequest& request) @@ -1644,7 +1644,7 @@ UniValue joinpsbts(const JSONRPCRequest& request) CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << merged_psbt; - return EncodeBase64(ssTx.str()); + return EncodeBase64(ssTx); } UniValue analyzepsbt(const JSONRPCRequest& request) diff --git a/src/streams.h b/src/streams.h index 7faf7e43d3f00..4df194db2d0f6 100644 --- a/src/streams.h +++ b/src/streams.h @@ -6,17 +6,19 @@ #ifndef BITCOIN_STREAMS_H #define BITCOIN_STREAMS_H -#include #include +#include +#include #include #include #include #include +#include #include #include -#include #include +#include #include #include @@ -206,14 +208,14 @@ class VectorReader class CDataStream { protected: - typedef CSerializeData vector_type; + using vector_type = SerializeData; vector_type vch; - unsigned int nReadPos; + unsigned int nReadPos{0}; int nType; int nVersion; -public: +public: typedef vector_type::allocator_type allocator_type; typedef vector_type::size_type size_type; typedef vector_type::difference_type difference_type; @@ -225,62 +227,22 @@ class CDataStream typedef vector_type::reverse_iterator reverse_iterator; explicit CDataStream(int nTypeIn, int nVersionIn) - { - Init(nTypeIn, nVersionIn); - } - - CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) - { - Init(nTypeIn, nVersionIn); - } - - CDataStream(const char* pbegin, const char* pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) - { - Init(nTypeIn, nVersionIn); - } - - CDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) - { - Init(nTypeIn, nVersionIn); - } - - CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) - { - Init(nTypeIn, nVersionIn); - } + : nType{nTypeIn}, + nVersion{nVersionIn} {} - CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) - { - Init(nTypeIn, nVersionIn); - } + explicit CDataStream(Span sp, int nTypeIn, int nVersionIn) + : vch(sp.data(), sp.data() + sp.size()), + nType{nTypeIn}, + nVersion{nVersionIn} {} template CDataStream(int nTypeIn, int nVersionIn, Args&&... args) + : nType{nTypeIn}, + nVersion{nVersionIn} { - Init(nTypeIn, nVersionIn); ::SerializeMany(*this, std::forward(args)...); } - void Init(int nTypeIn, int nVersionIn) - { - nReadPos = 0; - nType = nTypeIn; - nVersion = nVersionIn; - } - - CDataStream& operator+=(const CDataStream& b) - { - vch.insert(vch.end(), b.begin(), b.end()); - return *this; - } - - friend CDataStream operator+(const CDataStream& a, const CDataStream& b) - { - CDataStream ret = a; - ret += b; - return (ret); - } - std::string str() const { return (std::string(begin(), end())); @@ -301,12 +263,12 @@ class CDataStream const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; } reference operator[](size_type pos) { return vch[pos + nReadPos]; } void clear() { vch.clear(); nReadPos = 0; } - iterator insert(iterator it, const char x=char()) { return vch.insert(it, x); } - void insert(iterator it, size_type n, const char x) { vch.insert(it, n, x); } + iterator insert(iterator it, const uint8_t x) { return vch.insert(it, x); } + void insert(iterator it, size_type n, const uint8_t x) { vch.insert(it, n, x); } value_type* data() { return vch.data() + nReadPos; } const value_type* data() const { return vch.data() + nReadPos; } - void insert(iterator it, std::vector::const_iterator first, std::vector::const_iterator last) + void insert(iterator it, std::vector::const_iterator first, std::vector::const_iterator last) { if (last == first) return; assert(last - first > 0); @@ -377,12 +339,17 @@ class CDataStream nReadPos = 0; } - bool Rewind(size_type n) + bool Rewind(std::optional n = std::nullopt) { + // Total rewind if no size is passed + if (!n) { + nReadPos = 0; + return true; + } // Rewind by n characters if the buffer hasn't been compacted yet - if (n > nReadPos) + if (*n > nReadPos) return false; - nReadPos -= n; + nReadPos -= *n; return true; } @@ -466,11 +433,6 @@ class CDataStream return (*this); } - void GetAndClear(CSerializeData &d) { - d.insert(d.end(), begin(), end()); - clear(); - } - /** * XOR the contents of this stream with a certain key. * diff --git a/src/support/allocators/zeroafterfree.h b/src/support/allocators/zeroafterfree.h index 6bcf192b5f88c..623a936fe2a42 100644 --- a/src/support/allocators/zeroafterfree.h +++ b/src/support/allocators/zeroafterfree.h @@ -40,7 +40,7 @@ struct zero_after_free_allocator : public std::allocator { } }; -// Byte-vector that clears its contents before deletion. -typedef std::vector > CSerializeData; +/** Byte-vector that clears its contents before deletion. */ +using SerializeData = std::vector>; #endif // BITCOIN_SUPPORT_ALLOCATORS_ZEROAFTERFREE_H diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 41158d992d45e..d15632893dc65 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -40,11 +40,7 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize) CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << filter; - std::vector vch = ParseHex("03614e9b050000000000000001"); - std::vector expected(vch.size()); - - for (unsigned int i = 0; i < vch.size(); i++) - expected[i] = (char)vch[i]; + std::vector expected = ParseHex("03614e9b050000000000000001"); BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end()); @@ -70,11 +66,7 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak) CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << filter; - std::vector vch = ParseHex("03ce4299050000000100008001"); - std::vector expected(vch.size()); - - for (unsigned int i = 0; i < vch.size(); i++) - expected[i] = (char)vch[i]; + std::vector expected = ParseHex("03ce4299050000000100008001"); BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end()); } @@ -94,11 +86,7 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_key) CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << filter; - std::vector vch = ParseHex("038fc16b080000000000000001"); - std::vector expected(vch.size()); - - for (unsigned int i = 0; i < vch.size(); i++) - expected[i] = (char)vch[i]; + std::vector expected = ParseHex("038fc16b080000000000000001"); BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end()); } @@ -454,11 +442,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize) CDataStream merkleStream(SER_NETWORK, PROTOCOL_VERSION); merkleStream << merkleBlock; - std::vector vch = ParseHex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101"); - std::vector expected(vch.size()); - - for (unsigned int i = 0; i < vch.size(); i++) - expected[i] = (char)vch[i]; + std::vector expected = ParseHex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101"); BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), merkleStream.begin(), merkleStream.end()); } diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index bc0d48c24dbb4..30a3580e3913c 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -64,7 +64,7 @@ void CallOneOf(FuzzedDataProvider& fuzzed_data_provider, Callables... callables) [[ nodiscard ]] inline CDataStream ConsumeDataStream(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept { - return {ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length), SER_NETWORK, INIT_PROTO_VERSION}; + return CDataStream{ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length), SER_NETWORK, INIT_PROTO_VERSION}; } [[ nodiscard ]] inline std::vector ConsumeRandomLengthStringVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_vector_size = 16, const size_t max_string_length = 16) noexcept diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index 4dcfff4cc83c4..f1332d4a659a1 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -320,7 +320,7 @@ BOOST_AUTO_TEST_CASE(insert_delete) ss.insert(ss.end(), c); BOOST_CHECK_EQUAL(ss.size(), 6U); - BOOST_CHECK_EQUAL(ss[4], (char)0xff); + BOOST_CHECK_EQUAL(ss[4], 0xff); BOOST_CHECK_EQUAL(ss[5], c); ss.insert(ss.begin()+2, c); @@ -334,19 +334,14 @@ BOOST_AUTO_TEST_CASE(insert_delete) ss.erase(ss.begin()+ss.size()-1); BOOST_CHECK_EQUAL(ss.size(), 5U); - BOOST_CHECK_EQUAL(ss[4], (char)0xff); + BOOST_CHECK_EQUAL(ss[4], 0xff); ss.erase(ss.begin()+1); BOOST_CHECK_EQUAL(ss.size(), 4U); BOOST_CHECK_EQUAL(ss[0], 0); BOOST_CHECK_EQUAL(ss[1], 1); BOOST_CHECK_EQUAL(ss[2], 2); - BOOST_CHECK_EQUAL(ss[3], (char)0xff); - - // Make sure GetAndClear does the right thing: - CSerializeData d; - ss.GetAndClear(d); - BOOST_CHECK_EQUAL(ss.size(), 0U); + BOOST_CHECK_EQUAL(ss[3], 0xff); } // Change struct size and check if it can be deserialized diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp index b0b8f9853d7c5..ba2d879bb716d 100644 --- a/src/test/streams_tests.cpp +++ b/src/test/streams_tests.cpp @@ -160,7 +160,7 @@ BOOST_AUTO_TEST_CASE(bitstream_reader_writer) BOOST_AUTO_TEST_CASE(streams_serializedata_xor) { - std::vector in; + std::vector in; std::vector expected_xor; std::vector key; CDataStream ds(in, 0, 0); diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp index a8d35f6e36364..640c99e564f9b 100644 --- a/src/wallet/bdb.cpp +++ b/src/wallet/bdb.cpp @@ -488,9 +488,9 @@ bool BerkeleyDatabase::Rewrite(const char* pszSkip) break; } if (pszSkip && - strncmp(ssKey.data(), pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0) + strncmp((const char*)ssKey.data(), pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0) continue; - if (strncmp(ssKey.data(), "\x07version", 8) == 0) { + if (strncmp((const char*)ssKey.data(), "\x07version", 8) == 0) { // Update version: ssValue.clear(); ssValue << CLIENT_VERSION; From bb8bd9a94d76a70117b5a8623c03fe79dc92ce8f Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Thu, 4 Nov 2021 09:17:14 +0100 Subject: [PATCH 05/21] merge bitcoin#23451: Add std::byte helpers --- src/pubkey.h | 6 ++---- src/span.h | 25 +++++++++++++++++++++++++ src/streams.h | 12 ++++++------ src/test/base64_tests.cpp | 10 ++++++++++ src/test/streams_tests.cpp | 6 +++--- src/test/util_tests.cpp | 23 ++++++++++++++++++----- src/util/strencodings.cpp | 5 ----- src/util/strencodings.h | 5 +++-- 8 files changed, 67 insertions(+), 25 deletions(-) diff --git a/src/pubkey.h b/src/pubkey.h index 193b4667ab294..c2aa8517259f1 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -139,7 +139,7 @@ class CPubKey template void Unserialize(Stream& s) { - unsigned int len = ::ReadCompactSize(s); + const unsigned int len(::ReadCompactSize(s)); if (len <= SIZE) { s.read((char*)vch, len); if (len != size()) { @@ -147,9 +147,7 @@ class CPubKey } } else { // invalid pubkey, skip available data - char dummy; - while (len--) - s.read(&dummy, 1); + s.ignore(len); Invalidate(); } } diff --git a/src/span.h b/src/span.h index de88fa08c59b6..3d96269768afd 100644 --- a/src/span.h +++ b/src/span.h @@ -180,6 +180,7 @@ class Span 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 { @@ -236,11 +237,35 @@ T& SpanPopBack(Span& span) return back; } +// From C++20 as_bytes and as_writeable_bytes +template +Span AsBytes(Span s) noexcept +{ + return {reinterpret_cast(s.data()), s.size_bytes()}; +} +template +Span AsWritableBytes(Span s) noexcept +{ + return {reinterpret_cast(s.data()), s.size_bytes()}; +} + +template +Span MakeByteSpan(V&& v) noexcept +{ + return AsBytes(MakeSpan(std::forward(v))); +} +template +Span MakeWritableByteSpan(V&& v) noexcept +{ + return AsWritableBytes(MakeSpan(std::forward(v))); +} + // Helper functions to safely cast to unsigned char pointers. inline unsigned char* UCharCast(char* c) { return (unsigned char*)c; } inline unsigned char* UCharCast(unsigned char* c) { return c; } inline const unsigned char* UCharCast(const char* c) { return (unsigned char*)c; } inline const unsigned char* UCharCast(const unsigned char* c) { return c; } +inline const unsigned char* UCharCast(const std::byte* c) { return reinterpret_cast(c); } // Helper function to safely convert a Span to a Span<[const] unsigned char>. template constexpr auto UCharSpanCast(Span s) -> Span::type> { return {UCharCast(s.data()), s.size()}; } diff --git a/src/streams.h b/src/streams.h index 4df194db2d0f6..7ddf405049118 100644 --- a/src/streams.h +++ b/src/streams.h @@ -230,7 +230,7 @@ class CDataStream : nType{nTypeIn}, nVersion{nVersionIn} {} - explicit CDataStream(Span sp, int nTypeIn, int nVersionIn) + explicit CDataStream(Span sp, int nTypeIn, int nVersionIn) : vch(sp.data(), sp.data() + sp.size()), nType{nTypeIn}, nVersion{nVersionIn} {} @@ -258,17 +258,17 @@ class CDataStream iterator end() { return vch.end(); } size_type size() const { return vch.size() - nReadPos; } bool empty() const { return vch.size() == nReadPos; } - void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); } + void resize(size_type n, value_type c = value_type{}) { vch.resize(n + nReadPos, c); } void reserve(size_type n) { vch.reserve(n + nReadPos); } const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; } reference operator[](size_type pos) { return vch[pos + nReadPos]; } void clear() { vch.clear(); nReadPos = 0; } - iterator insert(iterator it, const uint8_t x) { return vch.insert(it, x); } - void insert(iterator it, size_type n, const uint8_t x) { vch.insert(it, n, x); } + iterator insert(iterator it, const value_type x) { return vch.insert(it, x); } + void insert(iterator it, size_type n, const value_type x) { vch.insert(it, n, x); } value_type* data() { return vch.data() + nReadPos; } const value_type* data() const { return vch.data() + nReadPos; } - void insert(iterator it, std::vector::const_iterator first, std::vector::const_iterator last) + void insert(iterator it, std::vector::const_iterator first, std::vector::const_iterator last) { if (last == first) return; assert(last - first > 0); @@ -282,7 +282,7 @@ class CDataStream vch.insert(it, first, last); } - void insert(iterator it, const char* first, const char* last) + void insert(iterator it, const value_type* first, const value_type* last) { if (last == first) return; assert(last - first > 0); diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp index 714fccffaac63..99f3ebdfa120c 100644 --- a/src/test/base64_tests.cpp +++ b/src/test/base64_tests.cpp @@ -24,6 +24,16 @@ BOOST_AUTO_TEST_CASE(base64_testvectors) BOOST_CHECK_EQUAL(strDec, vstrIn[i]); } + { + const std::vector in_u{0xff, 0x01, 0xff}; + const std::vector in_b{std::byte{0xff}, std::byte{0x01}, std::byte{0xff}}; + const std::string in_s{"\xff\x01\xff"}; + const std::string out_exp{"/wH/"}; + BOOST_CHECK_EQUAL(EncodeBase64(in_u), out_exp); + BOOST_CHECK_EQUAL(EncodeBase64(in_b), out_exp); + BOOST_CHECK_EQUAL(EncodeBase64(in_s), out_exp); + } + // Decoding strings with embedded NUL characters should fail bool failure; (void)DecodeBase64("invalid\0"s, &failure); diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp index ba2d879bb716d..7aa4d9b3c3b10 100644 --- a/src/test/streams_tests.cpp +++ b/src/test/streams_tests.cpp @@ -172,7 +172,7 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor) ds.Xor(key); BOOST_CHECK_EQUAL( std::string(expected_xor.begin(), expected_xor.end()), - std::string(ds.begin(), ds.end())); + ds.str()); in.push_back('\x0f'); in.push_back('\xf0'); @@ -189,7 +189,7 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor) ds.Xor(key); BOOST_CHECK_EQUAL( std::string(expected_xor.begin(), expected_xor.end()), - std::string(ds.begin(), ds.end())); + ds.str()); // Multi character key @@ -210,7 +210,7 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor) ds.Xor(key); BOOST_CHECK_EQUAL( std::string(expected_xor.begin(), expected_xor.end()), - std::string(ds.begin(), ds.end())); + ds.str()); } BOOST_AUTO_TEST_CASE(streams_buffered_file) diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 4095e2a7396b1..c1fe68c8706ba 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -186,12 +186,25 @@ BOOST_AUTO_TEST_CASE(util_HexStr) HexStr(Span(ParseHex_expected, ParseHex_expected)), ""); - std::vector ParseHex_vec(ParseHex_expected, ParseHex_expected + 5); + { + const std::vector in_s{ParseHex_expected, ParseHex_expected + 5}; + const Span in_u{MakeUCharSpan(in_s)}; + const Span in_b{MakeByteSpan(in_s)}; + const std::string out_exp{"04678afdb0"}; + + BOOST_CHECK_EQUAL(HexStr(in_u), out_exp); + BOOST_CHECK_EQUAL(HexStr(in_s), out_exp); + BOOST_CHECK_EQUAL(HexStr(in_b), out_exp); + } +} - BOOST_CHECK_EQUAL( - HexStr(ParseHex_vec), - "04678afdb0" - ); +BOOST_AUTO_TEST_CASE(span_write_bytes) +{ + std::array mut_arr{uint8_t{0xaa}, uint8_t{0xbb}}; + const auto mut_bytes{MakeWritableByteSpan(mut_arr)}; + mut_bytes[1] = std::byte{0x11}; + BOOST_CHECK_EQUAL(mut_arr.at(0), 0xaa); + BOOST_CHECK_EQUAL(mut_arr.at(1), 0x11); } BOOST_AUTO_TEST_CASE(util_Join) diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp index 84d806d65adcc..ed4624c3c5958 100644 --- a/src/util/strencodings.cpp +++ b/src/util/strencodings.cpp @@ -138,11 +138,6 @@ std::string EncodeBase64(Span input) return str; } -std::string EncodeBase64(const std::string& str) -{ - return EncodeBase64(MakeUCharSpan(str)); -} - std::vector DecodeBase64(const char* p, bool* pf_invalid) { static const int8_t decode64_table[256]{ diff --git a/src/util/strencodings.h b/src/util/strencodings.h index 427f3e2651c24..ab5cf47adfa25 100644 --- a/src/util/strencodings.h +++ b/src/util/strencodings.h @@ -49,8 +49,8 @@ bool IsHexNumber(const std::string& str); std::vector DecodeBase64(const char* p, bool* pf_invalid = nullptr); std::string DecodeBase64(const std::string& str, bool* pf_invalid = nullptr); std::string EncodeBase64(Span input); -std::string EncodeBase64(const std::string& str); - +inline std::string EncodeBase64(Span input) { return EncodeBase64(MakeUCharSpan(input)); } +inline std::string EncodeBase64(const std::string& str) { return EncodeBase64(MakeUCharSpan(str)); } std::vector DecodeBase32(const char* p, bool* pf_invalid = nullptr); std::string DecodeBase32(const std::string& str, bool* pf_invalid = nullptr); @@ -194,6 +194,7 @@ std::optional ToIntegral(const std::string& str) */ std::string HexStr(const Span s); inline std::string HexStr(const Span s) { return HexStr(MakeUCharSpan(s)); } +inline std::string HexStr(const Span s) { return HexStr(MakeUCharSpan(s)); } /** * Format a paragraph of text to a fixed width, adding spaces for From 4b29a74904f45486b3807f7ccb5cc5249f5cb577 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Mon, 4 Jan 2021 18:37:52 +0100 Subject: [PATCH 06/21] merge bitcoin#20852: allow CSubNet of non-IP networks --- src/netaddress.cpp | 81 +++++++++++++++++++++++++++++------ src/netaddress.h | 24 ++++++++++- src/test/netbase_tests.cpp | 21 +++++++-- test/functional/rpc_setban.py | 16 +++++++ 4 files changed, 123 insertions(+), 19 deletions(-) diff --git a/src/netaddress.cpp b/src/netaddress.cpp index 378da0627254b..b571ee4306fdf 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -1125,15 +1125,24 @@ CSubNet::CSubNet(const CNetAddr& addr, const CNetAddr& mask) : CSubNet() CSubNet::CSubNet(const CNetAddr& addr) : CSubNet() { - valid = addr.IsIPv4() || addr.IsIPv6(); - if (!valid) { + switch (addr.m_net) { + case NET_IPV4: + case NET_IPV6: + valid = true; + assert(addr.m_addr.size() <= sizeof(netmask)); + memset(netmask, 0xFF, addr.m_addr.size()); + break; + case NET_ONION: + case NET_I2P: + case NET_CJDNS: + valid = true; + break; + case NET_INTERNAL: + case NET_UNROUTABLE: + case NET_MAX: return; } - assert(addr.m_addr.size() <= sizeof(netmask)); - - memset(netmask, 0xFF, addr.m_addr.size()); - network = addr; } @@ -1145,6 +1154,21 @@ bool CSubNet::Match(const CNetAddr &addr) const { if (!valid || !addr.IsValid() || network.m_net != addr.m_net) return false; + + switch (network.m_net) { + case NET_IPV4: + case NET_IPV6: + break; + case NET_ONION: + case NET_I2P: + case NET_CJDNS: + case NET_INTERNAL: + return addr == network; + case NET_UNROUTABLE: + case NET_MAX: + return false; + } + assert(network.m_addr.size() == addr.m_addr.size()); for (size_t x = 0; x < addr.m_addr.size(); ++x) { if ((addr.m_addr[x] & netmask[x]) != network.m_addr[x]) { @@ -1156,18 +1180,35 @@ bool CSubNet::Match(const CNetAddr &addr) const std::string CSubNet::ToString() const { - assert(network.m_addr.size() <= sizeof(netmask)); + std::string suffix; - uint8_t cidr = 0; + switch (network.m_net) { + case NET_IPV4: + case NET_IPV6: { + assert(network.m_addr.size() <= sizeof(netmask)); - for (size_t i = 0; i < network.m_addr.size(); ++i) { - if (netmask[i] == 0x00) { - break; + uint8_t cidr = 0; + + for (size_t i = 0; i < network.m_addr.size(); ++i) { + if (netmask[i] == 0x00) { + break; + } + cidr += NetmaskBits(netmask[i]); } - cidr += NetmaskBits(netmask[i]); + + suffix = strprintf("/%u", cidr); + break; + } + case NET_ONION: + case NET_I2P: + case NET_CJDNS: + case NET_INTERNAL: + case NET_UNROUTABLE: + case NET_MAX: + break; } - return network.ToString() + strprintf("/%u", cidr); + return network.ToString() + suffix; } bool CSubNet::IsValid() const @@ -1177,7 +1218,19 @@ bool CSubNet::IsValid() const bool CSubNet::SanityCheck() const { - if (!(network.IsIPv4() || network.IsIPv6())) return false; + switch (network.m_net) { + case NET_IPV4: + case NET_IPV6: + break; + case NET_ONION: + case NET_I2P: + case NET_CJDNS: + return true; + case NET_INTERNAL: + case NET_UNROUTABLE: + case NET_MAX: + return false; + } for (size_t x = 0; x < network.m_addr.size(); ++x) { if (network.m_addr[x] & ~netmask[x]) return false; diff --git a/src/netaddress.h b/src/netaddress.h index 140e8bd288dd6..49800a9085c8a 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -489,11 +489,33 @@ class CSubNet bool SanityCheck() const; public: + /** + * Construct an invalid subnet (empty, `Match()` always returns false). + */ CSubNet(); + + /** + * Construct from a given network start and number of bits (CIDR mask). + * @param[in] addr Network start. Must be IPv4 or IPv6, otherwise an invalid subnet is + * created. + * @param[in] mask CIDR mask, must be in [0, 32] for IPv4 addresses and in [0, 128] for + * IPv6 addresses. Otherwise an invalid subnet is created. + */ CSubNet(const CNetAddr& addr, uint8_t mask); + + /** + * Construct from a given network start and mask. + * @param[in] addr Network start. Must be IPv4 or IPv6, otherwise an invalid subnet is + * created. + * @param[in] mask Network mask, must be of the same type as `addr` and not contain 0-bits + * followed by 1-bits. Otherwise an invalid subnet is created. + */ CSubNet(const CNetAddr& addr, const CNetAddr& mask); - //constructor for single ip subnet (/32 or /128) + /** + * Construct a single-host subnet. + * @param[in] addr The sole address to be contained in the subnet, can also be non-IPv[46]. + */ explicit CSubNet(const CNetAddr& addr); bool Match(const CNetAddr &addr) const; diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index 377f38901376c..30a46c0e05561 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -228,8 +228,22 @@ BOOST_AUTO_TEST_CASE(subnet_test) // IPv4 address with IPv6 netmask or the other way around. BOOST_CHECK(!CSubNet(ResolveIP("1.1.1.1"), ResolveIP("ffff::")).IsValid()); BOOST_CHECK(!CSubNet(ResolveIP("::1"), ResolveIP("255.0.0.0")).IsValid()); - // Can't subnet TOR (or any other non-IPv4 and non-IPv6 network). - BOOST_CHECK(!CSubNet(ResolveIP("5wyqrzbvrdsumnok.onion"), ResolveIP("255.0.0.0")).IsValid()); + + // Create Non-IP subnets. + + const CNetAddr tor_addr{ + ResolveIP("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion")}; + + subnet = CSubNet(tor_addr); + BOOST_CHECK(subnet.IsValid()); + BOOST_CHECK_EQUAL(subnet.ToString(), tor_addr.ToString()); + BOOST_CHECK(subnet.Match(tor_addr)); + BOOST_CHECK( + !subnet.Match(ResolveIP("kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion"))); + BOOST_CHECK(!subnet.Match(ResolveIP("1.2.3.4"))); + + BOOST_CHECK(!CSubNet(tor_addr, 200).IsValid()); + BOOST_CHECK(!CSubNet(tor_addr, ResolveIP("255.0.0.0")).IsValid()); subnet = ResolveSubNet("1.2.3.4/255.255.255.255"); BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32"); @@ -545,8 +559,7 @@ BOOST_AUTO_TEST_CASE(netbase_dont_resolve_strings_with_embedded_nul_characters) BOOST_CHECK(!LookupSubNet("1.2.3.0/24\0"s, ret)); BOOST_CHECK(!LookupSubNet("1.2.3.0/24\0example.com"s, ret)); BOOST_CHECK(!LookupSubNet("1.2.3.0/24\0example.com\0"s, ret)); - // We only do subnetting for IPv4 and IPv6 - BOOST_CHECK(!LookupSubNet("5wyqrzbvrdsumnok.onion"s, ret)); + BOOST_CHECK(LookupSubNet("5wyqrzbvrdsumnok.onion"s, ret)); BOOST_CHECK(!LookupSubNet("5wyqrzbvrdsumnok.onion\0"s, ret)); BOOST_CHECK(!LookupSubNet("5wyqrzbvrdsumnok.onion\0example.com"s, ret)); BOOST_CHECK(!LookupSubNet("5wyqrzbvrdsumnok.onion\0example.com\0"s, ret)); diff --git a/test/functional/rpc_setban.py b/test/functional/rpc_setban.py index f6072b0ab4471..a185b353b3e1c 100755 --- a/test/functional/rpc_setban.py +++ b/test/functional/rpc_setban.py @@ -15,6 +15,9 @@ def set_test_params(self): self.setup_clean_chain = True self.extra_args = [[],[]] + def is_banned(self, node, addr): + return any(e['address'] == addr for e in node.listbanned()) + def run_test(self): # Node 0 connects to Node 1, check that the noban permission is not granted self.connect_nodes(0, 1) @@ -42,5 +45,18 @@ def run_test(self): peerinfo = self.nodes[1].getpeerinfo()[0] assert not 'noban' in peerinfo['permissions'] + self.log.info("Test that a non-IP address can be banned/unbanned") + node = self.nodes[1] + tor_addr = "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion" + ip_addr = "1.2.3.4" + assert(not self.is_banned(node, tor_addr)) + assert(not self.is_banned(node, ip_addr)) + node.setban(tor_addr, "add") + assert(self.is_banned(node, tor_addr)) + assert(not self.is_banned(node, ip_addr)) + node.setban(tor_addr, "remove") + assert(not self.is_banned(self.nodes[1], tor_addr)) + assert(not self.is_banned(node, ip_addr)) + if __name__ == '__main__': SetBanTests().main() From 4041d2071670a0ec448292a312606d570b21e97f Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Fri, 8 Sep 2023 20:48:57 +0530 Subject: [PATCH 07/21] merge bitcoin#20355: Check for addrv1 compatibility before using addrv1 serializer/deserializer on CSubNet --- src/test/fuzz/deserialize.cpp | 38 ++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp index e31eca375cedb..09cbb1644bd84 100644 --- a/src/test/fuzz/deserialize.cpp +++ b/src/test/fuzz/deserialize.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -69,15 +70,19 @@ T Deserialize(CDataStream ds) } template -void DeserializeFromFuzzingInput(const std::vector& buffer, T& obj) +void DeserializeFromFuzzingInput(const std::vector& buffer, T& obj, const std::optional& protocol_version = {}) { CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION); - try { - int version; - ds >> version; - ds.SetVersion(version); - } catch (const std::ios_base::failure&) { - throw invalid_fuzzing_input_exception(); + if (protocol_version) { + ds.SetVersion(*protocol_version); + } else { + try { + int version; + ds >> version; + ds.SetVersion(version); + } catch (const std::ios_base::failure&) { + throw invalid_fuzzing_input_exception(); + } } try { ds >> obj; @@ -141,9 +146,15 @@ FUZZ_TARGET_DESERIALIZE(script_deserialize, { DeserializeFromFuzzingInput(buffer, script); }) FUZZ_TARGET_DESERIALIZE(sub_net_deserialize, { - CSubNet sub_net; - DeserializeFromFuzzingInput(buffer, sub_net); - AssertEqualAfterSerializeDeserialize(sub_net); + CSubNet sub_net_1; + DeserializeFromFuzzingInput(buffer, sub_net_1, INIT_PROTO_VERSION); + AssertEqualAfterSerializeDeserialize(sub_net_1, INIT_PROTO_VERSION); + CSubNet sub_net_2; + DeserializeFromFuzzingInput(buffer, sub_net_2, INIT_PROTO_VERSION | ADDRV2_FORMAT); + AssertEqualAfterSerializeDeserialize(sub_net_2, INIT_PROTO_VERSION | ADDRV2_FORMAT); + CSubNet sub_net_3; + DeserializeFromFuzzingInput(buffer, sub_net_3); + AssertEqualAfterSerializeDeserialize(sub_net_3, INIT_PROTO_VERSION | ADDRV2_FORMAT); }) FUZZ_TARGET_DESERIALIZE(tx_in_deserialize, { CTxIn tx_in; @@ -231,6 +242,13 @@ FUZZ_TARGET_DESERIALIZE(service_deserialize, { AssertEqualAfterSerializeDeserialize(s); } AssertEqualAfterSerializeDeserialize(s, INIT_PROTO_VERSION | ADDRV2_FORMAT); + CService s1; + DeserializeFromFuzzingInput(buffer, s1, INIT_PROTO_VERSION); + AssertEqualAfterSerializeDeserialize(s1, INIT_PROTO_VERSION); + assert(s1.IsAddrV1Compatible()); + CService s2; + DeserializeFromFuzzingInput(buffer, s2, INIT_PROTO_VERSION | ADDRV2_FORMAT); + AssertEqualAfterSerializeDeserialize(s2, INIT_PROTO_VERSION | ADDRV2_FORMAT); }) FUZZ_TARGET_DESERIALIZE(messageheader_deserialize, { CMessageHeader mh; From aa76506bc96fbb7d09c0073e5d731eecdca111a3 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Sun, 10 Sep 2023 19:40:08 +0530 Subject: [PATCH 08/21] partial bitcoin#21560: Add Tor v3 hardcoded seeds excludes: - 2a257de113fd31539b68c28c47ef94f257b6e427 - 9b29d5df7fc555eaea42029f334f2995c6ccde3d --- contrib/seeds/generate-seeds.py | 103 +++++---- src/chainparams.cpp | 4 +- src/chainparams.h | 9 +- src/chainparamsseeds.h | 363 ++++++++++++++++---------------- src/net.cpp | 17 +- 5 files changed, 256 insertions(+), 240 deletions(-) diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py index d905658f6594d..fb714d61a57ef 100755 --- a/contrib/seeds/generate-seeds.py +++ b/contrib/seeds/generate-seeds.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2017 Wladimir J. van der Laan +# Copyright (c) 2014-2021 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,19 +13,13 @@ These files must consist of lines in the format - : - [] []: - .onion - 0xDDBBCCAA (IPv4 little-endian old pnSeeds format) + .onion: The output will be two data structures with the peers in binary format: - static SeedSpec6 pnSeed6_main[]={ - ... - } - static SeedSpec6 pnSeed6_test[]={ + static const uint8_t chainparams_seed_{main,test}[]={ ... } @@ -33,24 +27,33 @@ ''' from base64 import b32decode -from binascii import a2b_hex +from enum import Enum +import struct import sys import os import re -# ipv4 in ipv6 prefix -pchIPv4 = bytearray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff]) -# tor-specific ipv6 prefix -pchOnionCat = bytearray([0xFD,0x87,0xD8,0x7E,0xEB,0x43]) - -def name_to_ipv6(addr): - if len(addr)>6 and addr.endswith('.onion'): +class BIP155Network(Enum): + IPV4 = 1 + IPV6 = 2 + TORV2 = 3 + TORV3 = 4 + I2P = 5 + CJDNS = 6 + +def name_to_bip155(addr): + '''Convert address string to BIP155 (networkID, addr) tuple.''' + if addr.endswith('.onion'): vchAddr = b32decode(addr[0:-6], True) - if len(vchAddr) != 16-len(pchOnionCat): + if len(vchAddr) == 10: + return (BIP155Network.TORV2, vchAddr) + elif len(vchAddr) == 35: + assert(vchAddr[34] == 3) + return (BIP155Network.TORV3, vchAddr[:32]) + else: raise ValueError('Invalid onion %s' % vchAddr) - return pchOnionCat + vchAddr elif '.' in addr: # IPv4 - return pchIPv4 + bytearray((int(x) for x in addr.split('.'))) + return (BIP155Network.IPV4, bytes((int(x) for x in addr.split('.')))) elif ':' in addr: # IPv6 sub = [[], []] # prefix, suffix x = 0 @@ -67,13 +70,12 @@ def name_to_ipv6(addr): sub[x].append(val & 0xff) nullbytes = 16 - len(sub[0]) - len(sub[1]) assert((x == 0 and nullbytes == 0) or (x == 1 and nullbytes > 0)) - return bytearray(sub[0] + ([0] * nullbytes) + sub[1]) - elif addr.startswith('0x'): # IPv4-in-little-endian - return pchIPv4 + bytearray(reversed(a2b_hex(addr[2:]))) + return (BIP155Network.IPV6, bytes(sub[0] + ([0] * nullbytes) + sub[1])) else: raise ValueError('Could not parse address %s' % addr) -def parse_spec(s, defaultport): +def parse_spec(s): + '''Convert endpoint string to BIP155 (networkID, addr, port) tuple.''' match = re.match(r'\[([0-9a-fA-F:]+)\](?::([0-9]+))?$', s) if match: # ipv6 host = match.group(1) @@ -85,17 +87,39 @@ def parse_spec(s, defaultport): (host,_,port) = s.partition(':') if not port: - port = defaultport + port = 0 else: port = int(port) - host = name_to_ipv6(host) + host = name_to_bip155(host) - return (host,port) + return host + (port, ) -def process_nodes(g, f, structname, defaultport): - g.write('static SeedSpec6 %s[] = {\n' % structname) - first = True +def ser_compact_size(l): + r = b"" + if l < 253: + r = struct.pack("B", l) + elif l < 0x10000: + r = struct.pack("H', spec[2]) + return r + +def process_nodes(g, f, structname): + g.write('static const uint8_t %s[] = {\n' % structname) for line in f: comment = line.find('#') if comment != -1: @@ -103,14 +127,12 @@ def process_nodes(g, f, structname, defaultport): line = line.strip() if not line: continue - if not first: - g.write(',\n') - first = False - (host,port) = parse_spec(line, defaultport) - hoststr = ','.join(('0x%02x' % b) for b in host) - g.write(' {{%s}, %i}' % (hoststr, port)) - g.write('\n};\n') + spec = parse_spec(line) + blob = bip155_serialize(spec) + hoststr = ','.join(('0x%02x' % b) for b in blob) + g.write(f' {hoststr},\n') + g.write('};\n') def main(): if len(sys.argv)<2: @@ -124,14 +146,13 @@ def main(): g.write(' * List of fixed seed nodes for the dash network\n') g.write(' * AUTOGENERATED by contrib/seeds/generate-seeds.py\n') g.write(' *\n') - g.write(' * Each line contains a 16-byte IPv6 address and a port.\n') - g.write(' * IPv4 as well as onion addresses are wrapped inside an IPv6 address accordingly.\n') + g.write(' * Each line contains a BIP155 serialized (networkID, addr, port) tuple.\n') g.write(' */\n') with open(os.path.join(indir,'nodes_main.txt'), 'r', encoding="utf8") as f: - process_nodes(g, f, 'pnSeed6_main', 9999) + process_nodes(g, f, 'chainparams_seed_main') g.write('\n') with open(os.path.join(indir,'nodes_test.txt'), 'r', encoding="utf8") as f: - process_nodes(g, f, 'pnSeed6_test', 19999) + process_nodes(g, f, 'chainparams_seed_test') g.write('#endif // BITCOIN_CHAINPARAMSSEEDS_H\n') if __name__ == '__main__': diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 5eff1ae6369be..151ba48622060 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -245,7 +245,7 @@ class CMainParams : public CChainParams { // Dash BIP44 coin type is '5' nExtCoinType = 5; - vFixedSeeds = std::vector(std::begin(pnSeed6_main), std::end(pnSeed6_main)); + vFixedSeeds = std::vector(std::begin(chainparams_seed_main), std::end(chainparams_seed_main)); // long living quorum params AddLLMQ(Consensus::LLMQType::LLMQ_50_60); @@ -417,7 +417,7 @@ class CTestNetParams : public CChainParams { assert(genesis.hashMerkleRoot == uint256S("0xe0028eb9648db56b1ac77cf090b99048a8007e2bb64b68f092c03c7f56a662c7")); vFixedSeeds.clear(); - vFixedSeeds = std::vector(std::begin(pnSeed6_test), std::end(pnSeed6_test)); + vFixedSeeds = std::vector(std::begin(chainparams_seed_test), std::end(chainparams_seed_test)); vSeeds.clear(); // nodes with support for servicebits filtering should be at the top diff --git a/src/chainparams.h b/src/chainparams.h index 59404c9d037c7..3218f81b07992 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -19,11 +19,6 @@ #include #include -struct SeedSpec6 { - uint8_t addr[16]; - uint16_t port; -}; - typedef std::map MapCheckpoints; struct CCheckpointData { @@ -127,7 +122,7 @@ class CChainParams const std::vector& DNSSeeds() const { return vSeeds; } const std::vector& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } int ExtCoinType() const { return nExtCoinType; } - const std::vector& FixedSeeds() const { return vFixedSeeds; } + const std::vector& FixedSeeds() const { return vFixedSeeds; } const CCheckpointData& Checkpoints() const { return checkpointData; } //! Get allowed assumeutxo configuration. @@ -161,7 +156,7 @@ class CChainParams std::string strNetworkID; CBlock genesis; CBlock devnetGenesis; - std::vector vFixedSeeds; + std::vector vFixedSeeds; bool fDefaultConsistencyChecks; bool fRequireStandard; bool fRequireRoutableExternalIP; diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index ec0c31f85f56f..2ca3968f5ced7 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -4,190 +4,189 @@ * List of fixed seed nodes for the dash network * AUTOGENERATED by contrib/seeds/generate-seeds.py * - * Each line contains a 16-byte IPv6 address and a port. - * IPv4 as well as onion addresses are wrapped inside an IPv6 address accordingly. + * Each line contains a BIP155 serialized (networkID, addr, port) tuple. */ -static SeedSpec6 pnSeed6_main[] = { - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x02,0x38,0xd5,0xdd}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x02,0x43,0xbe}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x02,0x49,0x3a}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0xed,0x22}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x4f,0x6d,0xf3}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x65,0x2c,0xe1}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xa1,0x57,0xb8}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xa1,0x78,0x23}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xa1,0x7e,0x07}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xb5,0xca,0x12}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0x8b,0xf4,0x09}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0x9d,0x81,0x94}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x51,0xf6,0x2a}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x53,0x85,0x0a}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x53,0x85,0xc4}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x0a,0x61,0x24}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x94,0x63,0xf2}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xb2,0x04,0x32}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x22,0xd1,0xed,0xf2}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x12,0xe3,0x38}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x61,0xe3,0x15}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2a,0xc2,0x85,0x77}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2b,0xe5,0x4d,0x2e}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x21,0x18,0x18}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x38,0x40,0x6b}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x38,0x46,0x71}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x3f,0x6b,0x5a}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x47,0x9e,0x3a}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x47,0x9e,0x42}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x47,0x9f,0x68}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4c,0x27,0xf1}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4c,0x59,0x3f}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4f,0x2e,0x47}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x55,0x75,0x2d}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x55,0x75,0xca}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x56,0xa2,0x53}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x56,0xa2,0x55}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x56,0xa2,0x9a}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1e,0xbd,0xbd}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1e,0xbd,0xd5}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1e,0xbd,0xd6}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1e,0xbd,0xfb}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x24,0x28,0xf2}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xfe,0xf1,0x18}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xfe,0xf1,0x1c}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x38,0x76,0x14}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x5b,0x98,0xe8}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x62,0x7b,0x6a}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x11,0xaf,0x5b}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x0f,0x60,0xce}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x0f,0x75,0x2a}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x0f,0xfe,0xe0}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x26,0xb3,0xe6}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x53,0xbf,0xd2}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x9e,0xa9,0xed}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0xca,0x8d,0x3c}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xa4,0xb9,0x60}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xda,0xda,0x2b}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xab,0xbe,0x8c}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0xfb,0x41,0xce}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xac,0x0c,0x56}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xf4,0xf3,0x45}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xca,0x14,0xe6}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x3d,0x6b,0xd7}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x3d,0x6b,0xd9}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x3d,0x6b,0xf2}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xdc,0xd4,0xb3}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x55,0x88,0xf8}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xd1,0xea,0xaa}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xf0,0x84,0xe7}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x02,0xf0,0x76}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x47,0x0d,0xa5}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xab,0x02,0xf5}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xe2,0xdf,0x99}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xca,0xe6,0x53}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xd3,0x15,0x17}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xd3,0x15,0xb3}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xd3,0x19,0x69}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xd3,0x19,0xc1}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x34,0x74,0x34}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xf2,0xb3,0xcc}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x11,0xf8,0x5b}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xce,0xa5,0x59}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xce,0xa5,0x5a}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd1,0xf1,0x23}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd1,0xf1,0xbe}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd1,0xf2,0x04}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd1,0xf2,0x62}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x62,0xfd,0x56}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x28,0x0d,0x2c}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x2d,0x43,0x36}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x2d,0x43,0x8a}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xbe,0x8c,0x72}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xb7,0x33,0x8d}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xb7,0x33,0x92}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xb7,0x35,0x27}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd3,0xc4,0x22}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd7,0x2d,0xe1}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd7,0x6e,0x78}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xa0,0x5f,0xdb}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xa0,0x5f,0xe1}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x80,0xef,0xd6}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0x34,0x79,0xda}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xa1,0x18,0x5a}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xbf,0x65,0xd4}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0xf7,0x46}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xc1,0x40,0xa6}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8a,0x44,0x1c,0x08}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8b,0x09,0xc7,0xf0}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8c,0xee,0xd2,0x22}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0x5f,0x35,0x6b}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8e,0xca,0xcd,0x65}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x7e,0x8e,0xa7}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x91,0x83,0x1c,0x42}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x91,0x83,0x1c,0x44}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x91,0x83,0x1d,0xd6}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x91,0x83,0x2a,0x60}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0xaf,0xce}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x98,0x43,0x45,0xe4}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9e,0x65,0xa2,0x4a}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9e,0x65,0xa8,0x1c}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0x47,0x33,0xcd}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0x56,0x4f,0x3e}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0x77,0x50,0x04}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0xeb,0x51,0x55}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0xeb,0x55,0xf1}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaa,0x4b,0xaa,0x87}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xf9,0x15,0x7a}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xf9,0x1a,0x14}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x22,0xe9,0xc9}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x22,0xe9,0xca}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x22,0xe9,0xcb}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x22,0xe9,0xcc}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x66,0x41,0x91}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x7b,0x39,0xc6}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x7b,0x39,0xc8}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x7b,0x39,0xcb}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x7b,0x39,0xcd}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xdf,0x88,0x2b}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3f,0x79,0x81}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x9d,0x5b,0x7e}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x9d,0x5b,0xb0}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x9d,0x5b,0xb3}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x05,0x34,0xe0}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x3e,0x97,0xaa}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x3e,0x97,0xae}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x40,0x68,0xde}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x40,0x68,0xdf}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x8e,0xd4,0x90}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xa5,0xab,0x75}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xaf,0x9e,0x28}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xb1,0x3b,0x25}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xe4,0x53,0x71}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xe4,0x53,0x9c}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xf3,0x0a,0x70}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xf3,0x0a,0x73}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x28,0xf1,0x6a}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x7f,0xe6,0x28}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x7f,0xed,0xf3}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xf4,0x75,0x0c}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xa9,0x06,0x19}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x1d,0x38,0x58}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x1d,0x3b,0x60}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xed,0x51,0xe0}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x1a,0xe8,0xc3}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0xb6,0x4b,0x88}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xb5,0xd2,0x11}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xb5,0xd3,0x40}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3d,0xc6,0x70}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3d,0xf8,0xd3}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x6b,0xd9,0x3e}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xbd,0x93,0x5f}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xbd,0x93,0xb2}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xbd,0x97,0x5e}, 9999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xde,0x74,0x40,0xe5}, 9999} +static const uint8_t chainparams_seed_main[] = { + 0x01,0x04,0x02,0x38,0xd5,0xdd,0x27,0x0f, + 0x01,0x04,0x05,0x02,0x43,0xbe,0x27,0x0f, + 0x01,0x04,0x05,0x02,0x49,0x3a,0x27,0x0f, + 0x01,0x04,0x05,0x09,0xed,0x22,0x27,0x0f, + 0x01,0x04,0x05,0x4f,0x6d,0xf3,0x27,0x0f, + 0x01,0x04,0x05,0x65,0x2c,0xe1,0x27,0x0f, + 0x01,0x04,0x05,0xa1,0x57,0xb8,0x27,0x0f, + 0x01,0x04,0x05,0xa1,0x78,0x23,0x27,0x0f, + 0x01,0x04,0x05,0xa1,0x7e,0x07,0x27,0x0f, + 0x01,0x04,0x05,0xb5,0xca,0x12,0x27,0x0f, + 0x01,0x04,0x12,0x8b,0xf4,0x09,0x27,0x0f, + 0x01,0x04,0x12,0x9d,0x81,0x94,0x27,0x0f, + 0x01,0x04,0x17,0x51,0xf6,0x2a,0x27,0x0f, + 0x01,0x04,0x17,0x53,0x85,0x0a,0x27,0x0f, + 0x01,0x04,0x17,0x53,0x85,0xc4,0x27,0x0f, + 0x01,0x04,0x1f,0x0a,0x61,0x24,0x27,0x0f, + 0x01,0x04,0x1f,0x94,0x63,0xf2,0x27,0x0f, + 0x01,0x04,0x1f,0xb2,0x04,0x32,0x27,0x0f, + 0x01,0x04,0x22,0xd1,0xed,0xf2,0x27,0x0f, + 0x01,0x04,0x25,0x12,0xe3,0x38,0x27,0x0f, + 0x01,0x04,0x25,0x61,0xe3,0x15,0x27,0x0f, + 0x01,0x04,0x2a,0xc2,0x85,0x77,0x27,0x0f, + 0x01,0x04,0x2b,0xe5,0x4d,0x2e,0x27,0x0f, + 0x01,0x04,0x2d,0x21,0x18,0x18,0x27,0x0f, + 0x01,0x04,0x2d,0x38,0x40,0x6b,0x27,0x0f, + 0x01,0x04,0x2d,0x38,0x46,0x71,0x27,0x0f, + 0x01,0x04,0x2d,0x3f,0x6b,0x5a,0x27,0x0f, + 0x01,0x04,0x2d,0x47,0x9e,0x3a,0x27,0x0f, + 0x01,0x04,0x2d,0x47,0x9e,0x42,0x27,0x0f, + 0x01,0x04,0x2d,0x47,0x9f,0x68,0x27,0x0f, + 0x01,0x04,0x2d,0x4c,0x27,0xf1,0x27,0x0f, + 0x01,0x04,0x2d,0x4c,0x59,0x3f,0x27,0x0f, + 0x01,0x04,0x2d,0x4f,0x2e,0x47,0x27,0x0f, + 0x01,0x04,0x2d,0x55,0x75,0x2d,0x27,0x0f, + 0x01,0x04,0x2d,0x55,0x75,0xca,0x27,0x0f, + 0x01,0x04,0x2d,0x56,0xa2,0x53,0x27,0x0f, + 0x01,0x04,0x2d,0x56,0xa2,0x55,0x27,0x0f, + 0x01,0x04,0x2d,0x56,0xa2,0x9a,0x27,0x0f, + 0x01,0x04,0x2e,0x1e,0xbd,0xbd,0x27,0x0f, + 0x01,0x04,0x2e,0x1e,0xbd,0xd5,0x27,0x0f, + 0x01,0x04,0x2e,0x1e,0xbd,0xd6,0x27,0x0f, + 0x01,0x04,0x2e,0x1e,0xbd,0xfb,0x27,0x0f, + 0x01,0x04,0x2e,0x24,0x28,0xf2,0x27,0x0f, + 0x01,0x04,0x2e,0xfe,0xf1,0x18,0x27,0x0f, + 0x01,0x04,0x2e,0xfe,0xf1,0x1c,0x27,0x0f, + 0x01,0x04,0x2f,0x38,0x76,0x14,0x27,0x0f, + 0x01,0x04,0x2f,0x5b,0x98,0xe8,0x27,0x0f, + 0x01,0x04,0x2f,0x62,0x7b,0x6a,0x27,0x0f, + 0x01,0x04,0x32,0x11,0xaf,0x5b,0x27,0x0f, + 0x01,0x04,0x33,0x0f,0x60,0xce,0x27,0x0f, + 0x01,0x04,0x33,0x0f,0x75,0x2a,0x27,0x0f, + 0x01,0x04,0x33,0x0f,0xfe,0xe0,0x27,0x0f, + 0x01,0x04,0x33,0x26,0xb3,0xe6,0x27,0x0f, + 0x01,0x04,0x33,0x53,0xbf,0xd2,0x27,0x0f, + 0x01,0x04,0x33,0x9e,0xa9,0xed,0x27,0x0f, + 0x01,0x04,0x34,0xca,0x8d,0x3c,0x27,0x0f, + 0x01,0x04,0x36,0xa4,0xb9,0x60,0x27,0x0f, + 0x01,0x04,0x36,0xda,0xda,0x2b,0x27,0x0f, + 0x01,0x04,0x3e,0xab,0xbe,0x8c,0x27,0x0f, + 0x01,0x04,0x40,0xfb,0x41,0xce,0x27,0x0f, + 0x01,0x04,0x42,0xac,0x0c,0x56,0x27,0x0f, + 0x01,0x04,0x42,0xf4,0xf3,0x45,0x27,0x0f, + 0x01,0x04,0x43,0xca,0x14,0xe6,0x27,0x0f, + 0x01,0x04,0x45,0x3d,0x6b,0xd7,0x27,0x0f, + 0x01,0x04,0x45,0x3d,0x6b,0xd9,0x27,0x0f, + 0x01,0x04,0x45,0x3d,0x6b,0xf2,0x27,0x0f, + 0x01,0x04,0x4d,0xdc,0xd4,0xb3,0x27,0x0f, + 0x01,0x04,0x50,0x55,0x88,0xf8,0x27,0x0f, + 0x01,0x04,0x50,0xd1,0xea,0xaa,0x27,0x0f, + 0x01,0x04,0x50,0xf0,0x84,0xe7,0x27,0x0f, + 0x01,0x04,0x51,0x02,0xf0,0x76,0x27,0x0f, + 0x01,0x04,0x51,0x47,0x0d,0xa5,0x27,0x0f, + 0x01,0x04,0x51,0xab,0x02,0xf5,0x27,0x0f, + 0x01,0x04,0x51,0xe2,0xdf,0x99,0x27,0x0f, + 0x01,0x04,0x52,0xca,0xe6,0x53,0x27,0x0f, + 0x01,0x04,0x52,0xd3,0x15,0x17,0x27,0x0f, + 0x01,0x04,0x52,0xd3,0x15,0xb3,0x27,0x0f, + 0x01,0x04,0x52,0xd3,0x19,0x69,0x27,0x0f, + 0x01,0x04,0x52,0xd3,0x19,0xc1,0x27,0x0f, + 0x01,0x04,0x54,0x34,0x74,0x34,0x27,0x0f, + 0x01,0x04,0x54,0xf2,0xb3,0xcc,0x27,0x0f, + 0x01,0x04,0x55,0x11,0xf8,0x5b,0x27,0x0f, + 0x01,0x04,0x55,0xce,0xa5,0x59,0x27,0x0f, + 0x01,0x04,0x55,0xce,0xa5,0x5a,0x27,0x0f, + 0x01,0x04,0x55,0xd1,0xf1,0x23,0x27,0x0f, + 0x01,0x04,0x55,0xd1,0xf1,0xbe,0x27,0x0f, + 0x01,0x04,0x55,0xd1,0xf2,0x04,0x27,0x0f, + 0x01,0x04,0x55,0xd1,0xf2,0x62,0x27,0x0f, + 0x01,0x04,0x57,0x62,0xfd,0x56,0x27,0x0f, + 0x01,0x04,0x59,0x28,0x0d,0x2c,0x27,0x0f, + 0x01,0x04,0x59,0x2d,0x43,0x36,0x27,0x0f, + 0x01,0x04,0x59,0x2d,0x43,0x8a,0x27,0x0f, + 0x01,0x04,0x5d,0xbe,0x8c,0x72,0x27,0x0f, + 0x01,0x04,0x5f,0xb7,0x33,0x8d,0x27,0x0f, + 0x01,0x04,0x5f,0xb7,0x33,0x92,0x27,0x0f, + 0x01,0x04,0x5f,0xb7,0x35,0x27,0x27,0x0f, + 0x01,0x04,0x5f,0xd3,0xc4,0x22,0x27,0x0f, + 0x01,0x04,0x5f,0xd7,0x2d,0xe1,0x27,0x0f, + 0x01,0x04,0x5f,0xd7,0x6e,0x78,0x27,0x0f, + 0x01,0x04,0x67,0xa0,0x5f,0xdb,0x27,0x0f, + 0x01,0x04,0x67,0xa0,0x5f,0xe1,0x27,0x0f, + 0x01,0x04,0x68,0x80,0xef,0xd6,0x27,0x0f, + 0x01,0x04,0x6a,0x34,0x79,0xda,0x27,0x0f, + 0x01,0x04,0x6b,0xa1,0x18,0x5a,0x27,0x0f, + 0x01,0x04,0x6b,0xbf,0x65,0xd4,0x27,0x0f, + 0x01,0x04,0x6c,0x3d,0xf7,0x46,0x27,0x0f, + 0x01,0x04,0x7b,0xc1,0x40,0xa6,0x27,0x0f, + 0x01,0x04,0x8a,0x44,0x1c,0x08,0x27,0x0f, + 0x01,0x04,0x8b,0x09,0xc7,0xf0,0x27,0x0f, + 0x01,0x04,0x8c,0xee,0xd2,0x22,0x27,0x0f, + 0x01,0x04,0x8d,0x5f,0x35,0x6b,0x27,0x0f, + 0x01,0x04,0x8e,0xca,0xcd,0x65,0x27,0x0f, + 0x01,0x04,0x90,0x7e,0x8e,0xa7,0x27,0x0f, + 0x01,0x04,0x91,0x83,0x1c,0x42,0x27,0x0f, + 0x01,0x04,0x91,0x83,0x1c,0x44,0x27,0x0f, + 0x01,0x04,0x91,0x83,0x1d,0xd6,0x27,0x0f, + 0x01,0x04,0x91,0x83,0x2a,0x60,0x27,0x0f, + 0x01,0x04,0x92,0xb9,0xaf,0xce,0x27,0x0f, + 0x01,0x04,0x98,0x43,0x45,0xe4,0x27,0x0f, + 0x01,0x04,0x9e,0x65,0xa2,0x4a,0x27,0x0f, + 0x01,0x04,0x9e,0x65,0xa8,0x1c,0x27,0x0f, + 0x01,0x04,0xa7,0x47,0x33,0xcd,0x27,0x0f, + 0x01,0x04,0xa7,0x56,0x4f,0x3e,0x27,0x0f, + 0x01,0x04,0xa8,0x77,0x50,0x04,0x27,0x0f, + 0x01,0x04,0xa8,0xeb,0x51,0x55,0x27,0x0f, + 0x01,0x04,0xa8,0xeb,0x55,0xf1,0x27,0x0f, + 0x01,0x04,0xaa,0x4b,0xaa,0x87,0x27,0x0f, + 0x01,0x04,0xad,0xf9,0x15,0x7a,0x27,0x0f, + 0x01,0x04,0xad,0xf9,0x1a,0x14,0x27,0x0f, + 0x01,0x04,0xae,0x22,0xe9,0xc9,0x27,0x0f, + 0x01,0x04,0xae,0x22,0xe9,0xca,0x27,0x0f, + 0x01,0x04,0xae,0x22,0xe9,0xcb,0x27,0x0f, + 0x01,0x04,0xae,0x22,0xe9,0xcc,0x27,0x0f, + 0x01,0x04,0xb0,0x66,0x41,0x91,0x27,0x0f, + 0x01,0x04,0xb0,0x7b,0x39,0xc6,0x27,0x0f, + 0x01,0x04,0xb0,0x7b,0x39,0xc8,0x27,0x0f, + 0x01,0x04,0xb0,0x7b,0x39,0xcb,0x27,0x0f, + 0x01,0x04,0xb0,0x7b,0x39,0xcd,0x27,0x0f, + 0x01,0x04,0xb0,0xdf,0x88,0x2b,0x27,0x0f, + 0x01,0x04,0xb2,0x3f,0x79,0x81,0x27,0x0f, + 0x01,0x04,0xb2,0x9d,0x5b,0x7e,0x27,0x0f, + 0x01,0x04,0xb2,0x9d,0x5b,0xb0,0x27,0x0f, + 0x01,0x04,0xb2,0x9d,0x5b,0xb3,0x27,0x0f, + 0x01,0x04,0xb9,0x05,0x34,0xe0,0x27,0x0f, + 0x01,0x04,0xb9,0x3e,0x97,0xaa,0x27,0x0f, + 0x01,0x04,0xb9,0x3e,0x97,0xae,0x27,0x0f, + 0x01,0x04,0xb9,0x40,0x68,0xde,0x27,0x0f, + 0x01,0x04,0xb9,0x40,0x68,0xdf,0x27,0x0f, + 0x01,0x04,0xb9,0x8e,0xd4,0x90,0x27,0x0f, + 0x01,0x04,0xb9,0xa5,0xab,0x75,0x27,0x0f, + 0x01,0x04,0xb9,0xaf,0x9e,0x28,0x27,0x0f, + 0x01,0x04,0xb9,0xb1,0x3b,0x25,0x27,0x0f, + 0x01,0x04,0xb9,0xe4,0x53,0x71,0x27,0x0f, + 0x01,0x04,0xb9,0xe4,0x53,0x9c,0x27,0x0f, + 0x01,0x04,0xb9,0xf3,0x0a,0x70,0x27,0x0f, + 0x01,0x04,0xb9,0xf3,0x0a,0x73,0x27,0x0f, + 0x01,0x04,0xbc,0x28,0xf1,0x6a,0x27,0x0f, + 0x01,0x04,0xbc,0x7f,0xe6,0x28,0x27,0x0f, + 0x01,0x04,0xbc,0x7f,0xed,0xf3,0x27,0x0f, + 0x01,0x04,0xbc,0xf4,0x75,0x0c,0x27,0x0f, + 0x01,0x04,0xc0,0xa9,0x06,0x19,0x27,0x0f, + 0x01,0x04,0xc1,0x1d,0x38,0x58,0x27,0x0f, + 0x01,0x04,0xc1,0x1d,0x3b,0x60,0x27,0x0f, + 0x01,0x04,0xc1,0xed,0x51,0xe0,0x27,0x0f, + 0x01,0x04,0xc2,0x1a,0xe8,0xc3,0x27,0x0f, + 0x01,0x04,0xc2,0xb6,0x4b,0x88,0x27,0x0f, + 0x01,0x04,0xc3,0xb5,0xd2,0x11,0x27,0x0f, + 0x01,0x04,0xc3,0xb5,0xd3,0x40,0x27,0x0f, + 0x01,0x04,0xca,0x3d,0xc6,0x70,0x27,0x0f, + 0x01,0x04,0xca,0x3d,0xf8,0xd3,0x27,0x0f, + 0x01,0x04,0xd8,0x6b,0xd9,0x3e,0x27,0x0f, + 0x01,0x04,0xd8,0xbd,0x93,0x5f,0x27,0x0f, + 0x01,0x04,0xd8,0xbd,0x93,0xb2,0x27,0x0f, + 0x01,0x04,0xd8,0xbd,0x97,0x5e,0x27,0x0f, + 0x01,0x04,0xde,0x74,0x40,0xe5,0x27,0x0f, }; -static SeedSpec6 pnSeed6_test[] = { - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2b,0xe5,0x4d,0x2e}, 19999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4d,0xa7,0xf7}, 19999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0xcb,0xf9}, 19999} +static const uint8_t chainparams_seed_test[] = { + 0x01,0x04,0x2b,0xe5,0x4d,0x2e,0x4e,0x1f, + 0x01,0x04,0x2d,0x4d,0xa7,0xf7,0x4e,0x1f, + 0x01,0x04,0xb2,0x3e,0xcb,0xf9,0x4e,0x1f, }; #endif // BITCOIN_CHAINPARAMSSEEDS_H diff --git a/src/net.cpp b/src/net.cpp index 65f63fc339ef1..e0e231218225a 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -166,8 +166,8 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer) return nBestScore >= 0; } -//! Convert the pnSeed6 array into usable address objects. -static std::vector convertSeed6(const std::vector &vSeedsIn) +//! Convert the serialized seeds into usable address objects. +static std::vector ConvertSeeds(const std::vector &vSeedsIn) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. @@ -175,13 +175,14 @@ static std::vector convertSeed6(const std::vector &vSeedsIn // weeks ago. const int64_t nOneWeek = 7*24*60*60; std::vector vSeedsOut; - vSeedsOut.reserve(vSeedsIn.size()); FastRandomContext rng; - for (const auto& seed_in : vSeedsIn) { - struct in6_addr ip; - memcpy(&ip, seed_in.addr, sizeof(ip)); - CAddress addr(CService(ip, seed_in.port), GetDesirableServiceFlags(NODE_NONE)); + CDataStream s(vSeedsIn, SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT); + while (!s.eof()) { + CService endpoint; + s >> endpoint; + CAddress addr{endpoint, GetDesirableServiceFlags(NODE_NONE)}; addr.nTime = GetTime() - rng.randrange(nOneWeek) - nOneWeek; + LogPrint(BCLog::NET, "Added hardcoded seed: %s\n", addr.ToString()); vSeedsOut.push_back(addr); } return vSeedsOut; @@ -2258,7 +2259,7 @@ void CConnman::ThreadOpenConnections(const std::vector connect) LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n"); CNetAddr local; local.SetInternal("fixedseeds"); - addrman.Add(convertSeed6(Params().FixedSeeds()), local); + addrman.Add(ConvertSeeds(Params().FixedSeeds()), local); done = true; } } From 546f7557d86767e4995ed4c50c3396a148b2dae3 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Sun, 13 Sep 2020 11:04:50 +0200 Subject: [PATCH 09/21] merge bitcoin#19951: CNetAddr scoped ipv6 test coverage, rename scopeId to m_scope_id --- src/netaddress.cpp | 4 ++-- src/netaddress.h | 8 ++++++-- src/test/net_tests.cpp | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/netaddress.cpp b/src/netaddress.cpp index b571ee4306fdf..17eee364e459d 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -323,7 +323,7 @@ CNetAddr::CNetAddr(const struct in_addr& ipv4Addr) CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope) { SetLegacyIPv6(Span(reinterpret_cast(&ipv6Addr), sizeof(ipv6Addr))); - scopeId = scope; + m_scope_id = scope; } bool CNetAddr::IsBindAny() const @@ -1002,7 +1002,7 @@ bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const memset(paddrin6, 0, *addrlen); if (!GetIn6Addr(&paddrin6->sin6_addr)) return false; - paddrin6->sin6_scope_id = scopeId; + paddrin6->sin6_scope_id = m_scope_id; paddrin6->sin6_family = AF_INET6; paddrin6->sin6_port = htons(port); return true; diff --git a/src/netaddress.h b/src/netaddress.h index 49800a9085c8a..cf9c8ab70c522 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -134,7 +134,11 @@ class CNetAddr */ Network m_net{NET_IPV6}; - uint32_t scopeId{0}; // for scoped/link-local ipv6 addresses + /** + * Scope id if scoped/link-local IPV6 address. + * See https://tools.ietf.org/html/rfc4007 + */ + uint32_t m_scope_id{0}; public: CNetAddr(); @@ -433,7 +437,7 @@ class CNetAddr "Address too long: %u > %u", address_size, MAX_ADDRV2_SIZE)); } - scopeId = 0; + m_scope_id = 0; if (SetNetFromBIP155Network(bip155_net, address_size)) { m_addr.resize(address_size); diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 0b7db7bc1782c..f0cbfc13583cb 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -262,6 +262,25 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic) BOOST_CHECK(addr.IsAddrV1Compatible()); BOOST_CHECK_EQUAL(addr.ToString(), "1122:3344:5566:7788:9900:aabb:ccdd:eeff"); + // IPv6, scoped/link-local. See https://tools.ietf.org/html/rfc4007 + // We support non-negative decimal integers (uint32_t) as zone id indices. + // Test with a fairly-high value, e.g. 32, to avoid locally reserved ids. + const std::string link_local{"fe80::1"}; + const std::string scoped_addr{link_local + "%32"}; + BOOST_REQUIRE(LookupHost(scoped_addr, addr, false)); + BOOST_REQUIRE(addr.IsValid()); + BOOST_REQUIRE(addr.IsIPv6()); + BOOST_CHECK(!addr.IsBindAny()); + const std::string addr_str{addr.ToString()}; + BOOST_CHECK(addr_str == scoped_addr || addr_str == "fe80:0:0:0:0:0:0:1"); + // The fallback case "fe80:0:0:0:0:0:0:1" is needed for macOS 10.14/10.15 and (probably) later. + // Test that the delimiter "%" and default zone id of 0 can be omitted for the default scope. + BOOST_REQUIRE(LookupHost(link_local + "%0", addr, false)); + BOOST_REQUIRE(addr.IsValid()); + BOOST_REQUIRE(addr.IsIPv6()); + BOOST_CHECK(!addr.IsBindAny()); + BOOST_CHECK_EQUAL(addr.ToString(), link_local); + // TORv2 BOOST_REQUIRE(addr.SetSpecial("6hzph5hv6337r6p2.onion")); BOOST_REQUIRE(addr.IsValid()); From 5d7367e366b45f1af866bffbc8e28d5439d83d02 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Wed, 20 Sep 2023 16:31:53 +0530 Subject: [PATCH 10/21] merge bitcoin#22050: remove tor v2 support --- contrib/seeds/generate-seeds.py | 17 +++++--- src/netaddress.cpp | 67 ++++++++++---------------------- src/netaddress.h | 21 ++-------- src/test/fuzz/deserialize.cpp | 6 +-- src/test/net_tests.cpp | 39 ++++--------------- src/test/netbase_tests.cpp | 36 ++++++----------- test/functional/feature_proxy.py | 4 +- 7 files changed, 60 insertions(+), 130 deletions(-) diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py index fb714d61a57ef..75cb6fad6e80c 100755 --- a/contrib/seeds/generate-seeds.py +++ b/contrib/seeds/generate-seeds.py @@ -36,7 +36,7 @@ class BIP155Network(Enum): IPV4 = 1 IPV6 = 2 - TORV2 = 3 + TORV2 = 3 # no longer supported TORV3 = 4 I2P = 5 CJDNS = 6 @@ -45,11 +45,11 @@ def name_to_bip155(addr): '''Convert address string to BIP155 (networkID, addr) tuple.''' if addr.endswith('.onion'): vchAddr = b32decode(addr[0:-6], True) - if len(vchAddr) == 10: - return (BIP155Network.TORV2, vchAddr) - elif len(vchAddr) == 35: - assert(vchAddr[34] == 3) + if len(vchAddr) == 35: + assert vchAddr[34] == 3 return (BIP155Network.TORV3, vchAddr[:32]) + elif len(vchAddr) == 10: + return (BIP155Network.TORV2, vchAddr) else: raise ValueError('Invalid onion %s' % vchAddr) elif '.' in addr: # IPv4 @@ -93,7 +93,10 @@ def parse_spec(s): host = name_to_bip155(host) - return host + (port, ) + if host[0] == BIP155Network.TORV2: + return None # TORV2 is no longer supported, so we ignore it + else: + return host + (port, ) def ser_compact_size(l): r = b"" @@ -129,6 +132,8 @@ def process_nodes(g, f, structname): continue spec = parse_spec(line) + if spec is None: # ignore this entry (e.g. no longer supported addresses like TORV2) + continue blob = bip155_serialize(spec) hoststr = ','.join(('0x%02x' % b) for b in blob) g.write(f' {hoststr},\n') diff --git a/src/netaddress.cpp b/src/netaddress.cpp index 17eee364e459d..f94631d08767d 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -31,14 +31,7 @@ CNetAddr::BIP155Network CNetAddr::GetBIP155Network() const case NET_IPV6: return BIP155Network::IPV6; case NET_ONION: - switch (m_addr.size()) { - case ADDR_TORV2_SIZE: - return BIP155Network::TORV2; - case ADDR_TORV3_SIZE: - return BIP155Network::TORV3; - default: - assert(false); - } + return BIP155Network::TORV3; case NET_I2P: return BIP155Network::I2P; case NET_CJDNS: @@ -71,14 +64,6 @@ bool CNetAddr::SetNetFromBIP155Network(uint8_t possible_bip155_net, size_t addre throw std::ios_base::failure( strprintf("BIP155 IPv6 address with length %u (should be %u)", address_size, ADDR_IPV6_SIZE)); - case BIP155Network::TORV2: - if (address_size == ADDR_TORV2_SIZE) { - m_net = NET_ONION; - return true; - } - throw std::ios_base::failure( - strprintf("BIP155 TORv2 address with length %u (should be %u)", address_size, - ADDR_TORV2_SIZE)); case BIP155Network::TORV3: if (address_size == ADDR_TORV3_SIZE) { m_net = NET_ONION; @@ -131,7 +116,7 @@ void CNetAddr::SetIP(const CNetAddr& ipIn) assert(ipIn.m_addr.size() == ADDR_IPV6_SIZE); break; case NET_ONION: - assert(ipIn.m_addr.size() == ADDR_TORV2_SIZE || ipIn.m_addr.size() == ADDR_TORV3_SIZE); + assert(ipIn.m_addr.size() == ADDR_TORV3_SIZE); break; case NET_I2P: assert(ipIn.m_addr.size() == ADDR_I2P_SIZE); @@ -162,9 +147,12 @@ void CNetAddr::SetLegacyIPv6(Span ipv6) m_net = NET_IPV4; skip = sizeof(IPV4_IN_IPV6_PREFIX); } else if (HasPrefix(ipv6, TORV2_IN_IPV6_PREFIX)) { - // TORv2-in-IPv6 - m_net = NET_ONION; - skip = sizeof(TORV2_IN_IPV6_PREFIX); + // TORv2-in-IPv6 (unsupported). Unserialize as !IsValid(), thus ignoring them. + // Mimic a default-constructed CNetAddr object which is !IsValid() and thus + // will not be gossiped, but continue reading next addresses from the stream. + m_net = NET_IPV6; + m_addr.assign(ADDR_IPV6_SIZE, 0x0); + return; } else if (HasPrefix(ipv6, INTERNAL_IN_IPV6_PREFIX)) { // Internal-in-IPv6 m_net = NET_INTERNAL; @@ -255,12 +243,7 @@ bool CNetAddr::SetTor(const std::string& addr) return false; } - switch (input.size()) { - case ADDR_TORV2_SIZE: - m_net = NET_ONION; - m_addr.assign(input.begin(), input.end()); - return true; - case torv3::TOTAL_LEN: { + if (input.size() == torv3::TOTAL_LEN) { Span input_pubkey{input.data(), ADDR_TORV3_SIZE}; Span input_checksum{input.data() + ADDR_TORV3_SIZE, torv3::CHECKSUM_LEN}; Span input_version{input.data() + ADDR_TORV3_SIZE + torv3::CHECKSUM_LEN, sizeof(torv3::VERSION)}; @@ -280,7 +263,6 @@ bool CNetAddr::SetTor(const std::string& addr) m_addr.assign(input_pubkey.begin(), input_pubkey.end()); return true; } - } return false; } @@ -533,7 +515,6 @@ bool CNetAddr::IsAddrV1Compatible() const case NET_INTERNAL: return true; case NET_ONION: - return m_addr.size() == ADDR_TORV2_SIZE; case NET_I2P: case NET_CJDNS: return false; @@ -577,6 +558,17 @@ static std::string IPv6ToString(Span a) // clang-format on } +static std::string OnionToString(const Span& addr) +{ + uint8_t checksum[torv3::CHECKSUM_LEN]; + torv3::Checksum(addr, checksum); + // TORv3 onion_address = base32(PUBKEY | CHECKSUM | VERSION) + ".onion" + prevector address{addr.begin(), addr.end()}; + address.insert(address.end(), checksum, checksum + torv3::CHECKSUM_LEN); + address.insert(address.end(), torv3::VERSION, torv3::VERSION + sizeof(torv3::VERSION)); + return EncodeBase32(address) + ".onion"; +} + std::string CNetAddr::ToStringIP(bool fUseGetnameinfo) const { switch (m_net) { @@ -597,24 +589,7 @@ std::string CNetAddr::ToStringIP(bool fUseGetnameinfo) const return IPv6ToString(m_addr); } case NET_ONION: - switch (m_addr.size()) { - case ADDR_TORV2_SIZE: - return EncodeBase32(m_addr) + ".onion"; - case ADDR_TORV3_SIZE: { - - uint8_t checksum[torv3::CHECKSUM_LEN]; - torv3::Checksum(m_addr, checksum); - - // TORv3 onion_address = base32(PUBKEY | CHECKSUM | VERSION) + ".onion" - prevector address{m_addr.begin(), m_addr.end()}; - address.insert(address.end(), checksum, checksum + torv3::CHECKSUM_LEN); - address.insert(address.end(), torv3::VERSION, torv3::VERSION + sizeof(torv3::VERSION)); - - return EncodeBase32(address) + ".onion"; - } - default: - assert(false); - } + return OnionToString(m_addr); case NET_I2P: return EncodeBase32(m_addr, false /* don't pad with = */) + ".b32.i2p"; case NET_CJDNS: diff --git a/src/netaddress.h b/src/netaddress.h index cf9c8ab70c522..a2b8418ad4e95 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -98,9 +98,6 @@ static constexpr size_t ADDR_IPV4_SIZE = 4; /// Size of IPv6 address (in bytes). static constexpr size_t ADDR_IPV6_SIZE = 16; -/// Size of TORv2 address (in bytes). -static constexpr size_t ADDR_TORV2_SIZE = 10; - /// Size of TORv3 address (in bytes). This is the length of just the address /// as used in BIP155, without the checksum and the version byte. static constexpr size_t ADDR_TORV3_SIZE = 32; @@ -262,8 +259,7 @@ class CNetAddr /** * Parse a Tor address and set this object to it. * @param[in] addr Address to parse, must be a valid C string, for example - * pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion or - * 6hzph5hv6337r6p2.onion. + * pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion. * @returns Whether the operation was successful. * @see CNetAddr::IsTor() */ @@ -305,7 +301,7 @@ class CNetAddr /** * Get the BIP155 network id of this address. * Must not be called for IsInternal() objects. - * @returns BIP155 network id + * @returns BIP155 network id, except TORV2 which is no longer supported. */ BIP155Network GetBIP155Network() const; @@ -336,23 +332,14 @@ class CNetAddr memcpy(arr, IPV4_IN_IPV6_PREFIX.data(), prefix_size); memcpy(arr + prefix_size, m_addr.data(), m_addr.size()); return; - case NET_ONION: - if (m_addr.size() == ADDR_TORV3_SIZE) { - break; - } - prefix_size = sizeof(TORV2_IN_IPV6_PREFIX); - assert(prefix_size + m_addr.size() == sizeof(arr)); - memcpy(arr, TORV2_IN_IPV6_PREFIX.data(), prefix_size); - memcpy(arr + prefix_size, m_addr.data(), m_addr.size()); - return; case NET_INTERNAL: prefix_size = sizeof(INTERNAL_IN_IPV6_PREFIX); assert(prefix_size + m_addr.size() == sizeof(arr)); memcpy(arr, INTERNAL_IN_IPV6_PREFIX.data(), prefix_size); memcpy(arr + prefix_size, m_addr.data(), m_addr.size()); return; + case NET_ONION: case NET_I2P: - break; case NET_CJDNS: break; case NET_UNROUTABLE: @@ -360,7 +347,7 @@ class CNetAddr assert(false); } // no default case, so the compiler can warn about missing cases - // Serialize TORv3, I2P and CJDNS as all-zeros. + // Serialize ONION, I2P and CJDNS as all-zeros. memset(arr, 0x0, V1_SERIALIZATION_SIZE); } diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp index 09cbb1644bd84..fb0a9127c8c7c 100644 --- a/src/test/fuzz/deserialize.cpp +++ b/src/test/fuzz/deserialize.cpp @@ -145,7 +145,7 @@ FUZZ_TARGET_DESERIALIZE(script_deserialize, { CScript script; DeserializeFromFuzzingInput(buffer, script); }) -FUZZ_TARGET_DESERIALIZE(sub_net_deserialize, { +FUZZ_TARGET_DESERIALIZE(subnet_deserialize, { CSubNet sub_net_1; DeserializeFromFuzzingInput(buffer, sub_net_1, INIT_PROTO_VERSION); AssertEqualAfterSerializeDeserialize(sub_net_1, INIT_PROTO_VERSION); @@ -227,7 +227,7 @@ FUZZ_TARGET_DESERIALIZE(coins_deserialize, { Coin coin; DeserializeFromFuzzingInput(buffer, coin); }) -FUZZ_TARGET_DESERIALIZE(netaddr_deserialize, { +FUZZ_TARGET_DESERIALIZE(net_address_deserialize, { CNetAddr na; DeserializeFromFuzzingInput(buffer, na); if (na.IsAddrV1Compatible()) { @@ -235,7 +235,7 @@ FUZZ_TARGET_DESERIALIZE(netaddr_deserialize, { } AssertEqualAfterSerializeDeserialize(na, INIT_PROTO_VERSION | ADDRV2_FORMAT); }) -FUZZ_TARGET_DESERIALIZE(service_deserialize, { +FUZZ_TARGET_DESERIALIZE(net_service_deserialize, { CService s; DeserializeFromFuzzingInput(buffer, s); if (s.IsAddrV1Compatible()) { diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index f0cbfc13583cb..4933f948fd0c1 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -281,15 +281,8 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic) BOOST_CHECK(!addr.IsBindAny()); BOOST_CHECK_EQUAL(addr.ToString(), link_local); - // TORv2 - BOOST_REQUIRE(addr.SetSpecial("6hzph5hv6337r6p2.onion")); - BOOST_REQUIRE(addr.IsValid()); - BOOST_REQUIRE(addr.IsTor()); - - BOOST_CHECK(!addr.IsI2P()); - BOOST_CHECK(!addr.IsBindAny()); - BOOST_CHECK(addr.IsAddrV1Compatible()); - BOOST_CHECK_EQUAL(addr.ToString(), "6hzph5hv6337r6p2.onion"); + // TORv2, no longer supported + BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion")); // TORv3 const char* torv3_addr = "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"; @@ -379,10 +372,8 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1) BOOST_CHECK_EQUAL(HexStr(s), "1a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b"); s.clear(); - BOOST_REQUIRE(addr.SetSpecial("6hzph5hv6337r6p2.onion")); - s << addr; - BOOST_CHECK_EQUAL(HexStr(s), "fd87d87eeb43f1f2f3f4f5f6f7f8f9fa"); - s.clear(); + // TORv2, no longer supported + BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion")); BOOST_REQUIRE(addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion")); s << addr; @@ -417,10 +408,8 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v2) BOOST_CHECK_EQUAL(HexStr(s), "02101a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b"); s.clear(); - BOOST_REQUIRE(addr.SetSpecial("6hzph5hv6337r6p2.onion")); - s << addr; - BOOST_CHECK_EQUAL(HexStr(s), "030af1f2f3f4f5f6f7f8f9fa"); - s.clear(); + // TORv2, no longer supported + BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion")); BOOST_REQUIRE(addr.SetSpecial("kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion")); s << addr; @@ -526,26 +515,14 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) BOOST_CHECK(!addr.IsValid()); BOOST_REQUIRE(s.empty()); - // Valid TORv2. + // TORv2, no longer supported. s << MakeSpan(ParseHex("03" // network type (TORv2) "0a" // address length "f1f2f3f4f5f6f7f8f9fa")); // address s >> addr; - BOOST_CHECK(addr.IsValid()); - BOOST_CHECK(addr.IsTor()); - BOOST_CHECK(addr.IsAddrV1Compatible()); - BOOST_CHECK_EQUAL(addr.ToString(), "6hzph5hv6337r6p2.onion"); + BOOST_CHECK(!addr.IsValid()); BOOST_REQUIRE(s.empty()); - // Invalid TORv2, with bogus length. - s << MakeSpan(ParseHex("03" // network type (TORv2) - "07" // address length - "00")); // address - BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure, - HasReason("BIP155 TORv2 address with length 7 (should be 10)")); - BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. - s.clear(); - // Valid TORv3. s << MakeSpan(ParseHex("04" // network type (TORv3) "20" // address length diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index 30a46c0e05561..fcb11b7a0bba7 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -45,13 +45,12 @@ static CNetAddr CreateInternal(const std::string& host) BOOST_AUTO_TEST_CASE(netbase_networks) { - BOOST_CHECK(ResolveIP("127.0.0.1").GetNetwork() == NET_UNROUTABLE); - BOOST_CHECK(ResolveIP("::1").GetNetwork() == NET_UNROUTABLE); - BOOST_CHECK(ResolveIP("8.8.8.8").GetNetwork() == NET_IPV4); - BOOST_CHECK(ResolveIP("2001::8888").GetNetwork() == NET_IPV6); - BOOST_CHECK(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetNetwork() == NET_ONION); - BOOST_CHECK(CreateInternal("foo.com").GetNetwork() == NET_INTERNAL); - + BOOST_CHECK(ResolveIP("127.0.0.1").GetNetwork() == NET_UNROUTABLE); + BOOST_CHECK(ResolveIP("::1").GetNetwork() == NET_UNROUTABLE); + BOOST_CHECK(ResolveIP("8.8.8.8").GetNetwork() == NET_IPV4); + BOOST_CHECK(ResolveIP("2001::8888").GetNetwork() == NET_IPV6); + BOOST_CHECK(ResolveIP("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion").GetNetwork() == NET_ONION); + BOOST_CHECK(CreateInternal("foo.com").GetNetwork() == NET_INTERNAL); } BOOST_AUTO_TEST_CASE(netbase_properties) @@ -74,7 +73,7 @@ BOOST_AUTO_TEST_CASE(netbase_properties) BOOST_CHECK(ResolveIP("2001:20::").IsRFC7343()); BOOST_CHECK(ResolveIP("FE80::").IsRFC4862()); BOOST_CHECK(ResolveIP("64:FF9B::").IsRFC6052()); - BOOST_CHECK(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").IsTor()); + BOOST_CHECK(ResolveIP("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion").IsTor()); BOOST_CHECK(ResolveIP("127.0.0.1").IsLocal()); BOOST_CHECK(ResolveIP("::1").IsLocal()); BOOST_CHECK(ResolveIP("8.8.8.8").IsRoutable()); @@ -134,18 +133,6 @@ BOOST_AUTO_TEST_CASE(netbase_lookupnumeric) BOOST_CHECK(TestParse("[fd6c:88c0:8724:1:2:3:4:5]", "[fd6c:88c0:8724:1:2:3:4:5]:65535")); } -BOOST_AUTO_TEST_CASE(onioncat_test) -{ - // values from https://web.archive.org/web/20121122003543/http://www.cypherpunk.at/onioncat/wiki/OnionCat - CNetAddr addr1(ResolveIP("5wyqrzbvrdsumnok.onion")); - CNetAddr addr2(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca")); - BOOST_CHECK(addr1 == addr2); - BOOST_CHECK(addr1.IsTor()); - BOOST_CHECK(addr1.ToStringIP() == "5wyqrzbvrdsumnok.onion"); - BOOST_CHECK(addr1.IsRoutable()); - -} - BOOST_AUTO_TEST_CASE(embedded_test) { CNetAddr addr1(ResolveIP("1.2.3.4")); @@ -339,7 +326,6 @@ BOOST_AUTO_TEST_CASE(netbase_getgroup) BOOST_CHECK(ResolveIP("64:FF9B::102:304").GetGroup(asmap) == std::vector({(unsigned char)NET_IPV4, 1, 2})); // RFC6052 BOOST_CHECK(ResolveIP("2002:102:304:9999:9999:9999:9999:9999").GetGroup(asmap) == std::vector({(unsigned char)NET_IPV4, 1, 2})); // RFC3964 BOOST_CHECK(ResolveIP("2001:0:9999:9999:9999:9999:FEFD:FCFB").GetGroup(asmap) == std::vector({(unsigned char)NET_IPV4, 1, 2})); // RFC4380 - BOOST_CHECK(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetGroup(asmap) == std::vector({(unsigned char)NET_ONION, 239})); // Tor BOOST_CHECK(ResolveIP("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup(asmap) == std::vector({(unsigned char)NET_IPV6, 32, 1, 4, 112, 175})); //he.net BOOST_CHECK(ResolveIP("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup(asmap) == std::vector({(unsigned char)NET_IPV6, 32, 1, 32, 1})); //IPv6 @@ -559,10 +545,10 @@ BOOST_AUTO_TEST_CASE(netbase_dont_resolve_strings_with_embedded_nul_characters) BOOST_CHECK(!LookupSubNet("1.2.3.0/24\0"s, ret)); BOOST_CHECK(!LookupSubNet("1.2.3.0/24\0example.com"s, ret)); BOOST_CHECK(!LookupSubNet("1.2.3.0/24\0example.com\0"s, ret)); - BOOST_CHECK(LookupSubNet("5wyqrzbvrdsumnok.onion"s, ret)); - BOOST_CHECK(!LookupSubNet("5wyqrzbvrdsumnok.onion\0"s, ret)); - BOOST_CHECK(!LookupSubNet("5wyqrzbvrdsumnok.onion\0example.com"s, ret)); - BOOST_CHECK(!LookupSubNet("5wyqrzbvrdsumnok.onion\0example.com\0"s, ret)); + BOOST_CHECK(LookupSubNet("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"s, ret)); + BOOST_CHECK(!LookupSubNet("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion\0"s, ret)); + BOOST_CHECK(!LookupSubNet("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion\0example.com"s, ret)); + BOOST_CHECK(!LookupSubNet("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion\0example.com\0"s, ret)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/functional/feature_proxy.py b/test/functional/feature_proxy.py index f55e2d65941bf..a32b032d5739f 100755 --- a/test/functional/feature_proxy.py +++ b/test/functional/feature_proxy.py @@ -147,13 +147,13 @@ def node_test(self, node, proxies, auth, test_onion=True): self.network_test(node, addr, network=NET_IPV6) if test_onion: - addr = "bitcoinostk4e4re.onion:8333" + addr = "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion:8333" self.log.debug("Test: outgoing onion connection through node for address {}".format(addr)) node.addnode(addr, "onetry") cmd = proxies[2].queue.get() assert isinstance(cmd, Socks5Command) assert_equal(cmd.atyp, AddressType.DOMAINNAME) - assert_equal(cmd.addr, b"bitcoinostk4e4re.onion") + assert_equal(cmd.addr, b"pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion") assert_equal(cmd.port, 8333) if not auth: assert_equal(cmd.username, None) From 8c2d480f1ab02a42739f3f880ad0f9382bfcf854 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Sat, 9 Sep 2023 00:49:46 +0530 Subject: [PATCH 11/21] merge bitcoin#23115: use Span instead of std::vector for insert and contains --- src/bloom.cpp | 69 ++++++++++++---------------------------- src/bloom.h | 21 +++++------- src/hash.cpp | 1 + src/test/bloom_tests.cpp | 2 +- 4 files changed, 31 insertions(+), 62 deletions(-) diff --git a/src/bloom.cpp b/src/bloom.cpp index b9508b3da1246..1bb8cff7d8cf9 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -4,23 +4,27 @@ #include -#include #include -#include #include -#include +#include #include +#include +#include +#include #include