merge bitcoin#22570: Ignore banlist.dat

This commit is contained in:
Kittywhiskers Van Gogh 2023-09-20 16:35:01 +05:30 committed by PastaPastaPasta
parent c3b4b6746a
commit b89963abf2
8 changed files with 529 additions and 565 deletions

View File

@ -56,7 +56,6 @@ Subdirectory | File(s) | Description
`./` | `anchors.dat` | Anchor IP address database, created on shutdown and deleted at startup. Anchors are last known outgoing block-relay-only peers that are tried to re-connect to on startup `./` | `anchors.dat` | Anchor IP address database, created on shutdown and deleted at startup. Anchors are last known outgoing block-relay-only peers that are tried to re-connect to on startup
`evodb/` | |special txes and quorums database `evodb/` | |special txes and quorums database
`llmq/` | |quorum signatures database `llmq/` | |quorum signatures database
`./` | `banlist.dat` | Stores the addresses/subnets of banned nodes (deprecated). `dashd` or `dash-qt` no longer save the banlist to this file, but read it on startup if `banlist.json` is not present.
`./` | `banlist.json` | Stores the addresses/subnets of banned nodes. `./` | `banlist.json` | Stores the addresses/subnets of banned nodes.
`./` | `dash.conf` | User-defined [configuration settings](dash-conf.md) for `dashd` or `dash-qt`. File is not written to by the software and must be created manually. Path can be specified by `-conf` option `./` | `dash.conf` | User-defined [configuration settings](dash-conf.md) for `dashd` or `dash-qt`. File is not written to by the software and must be created manually. Path can be specified by `-conf` option
`./` | `dashd.pid` | Stores the process ID (PID) of `dashd` or `dash-qt` while running; created at start and deleted on shutdown; can be specified by `-pid` option `./` | `dashd.pid` | Stores the process ID (PID) of `dashd` or `dash-qt` while running; created at start and deleted on shutdown; can be specified by `-pid` option
@ -116,6 +115,7 @@ These subdirectories and files are no longer used by Dash Core:
Path | Description | Repository notes Path | Description | Repository notes
---------------|-------------|----------------- ---------------|-------------|-----------------
`banlist.dat` | Stores the addresses/subnets of banned nodes; completely ignored and superseded by `banlist.json` in 20.0 | [PR #5574](https://github.com/dashpay/dash/pull/5574)
`blktree/` | Blockchain index; replaced by `blocks/index/` in [0.8.0](https://github.com/dash/dash/blob/master/doc/release-notes/release-notes-0.8.0.md#improvements) | [PR #2231](https://github.com/dash/dash/pull/2231), [`8fdc94cc`](https://github.com/dash/dash/commit/8fdc94cc8f0341e96b1edb3a5b56811c0b20bd15) `blktree/` | Blockchain index; replaced by `blocks/index/` in [0.8.0](https://github.com/dash/dash/blob/master/doc/release-notes/release-notes-0.8.0.md#improvements) | [PR #2231](https://github.com/dash/dash/pull/2231), [`8fdc94cc`](https://github.com/dash/dash/commit/8fdc94cc8f0341e96b1edb3a5b56811c0b20bd15)
`coins/` | Unspent transaction output database; replaced by `chainstate/` in 0.8.0 | [PR #2231](https://github.com/dash/dash/pull/2231), [`8fdc94cc`](https://github.com/dash/dash/commit/8fdc94cc8f0341e96b1edb3a5b56811c0b20bd15) `coins/` | Unspent transaction output database; replaced by `chainstate/` in 0.8.0 | [PR #2231](https://github.com/dash/dash/pull/2231), [`8fdc94cc`](https://github.com/dash/dash/commit/8fdc94cc8f0341e96b1edb3a5b56811c0b20bd15)
`blkindex.dat` | Blockchain index BDB database; replaced by {`chainstate/`, `blocks/index/`, `blocks/revNNNNN.dat`<sup>[\[2\]](#note2)</sup>} in 0.8.0 | [PR #1677](https://github.com/dash/dash/pull/1677) `blkindex.dat` | Blockchain index BDB database; replaced by {`chainstate/`, `blocks/index/`, `blocks/revNNNNN.dat`<sup>[\[2\]](#note2)</sup>} in 0.8.0 | [PR #1677](https://github.com/dash/dash/pull/1677)

View File

@ -198,16 +198,15 @@ bool CBanDB::Write(const banmap_t& banSet)
return false; return false;
} }
bool CBanDB::Read(banmap_t& banSet, bool& dirty) bool CBanDB::Read(banmap_t& banSet)
{ {
// If the JSON banlist does not exist, then try to read the non-upgraded banlist.dat. if (fs::exists(m_banlist_dat)) {
if (!fs::exists(m_banlist_json)) { LogPrintf("banlist.dat ignored because it can only be read by " PACKAGE_NAME " version 19.x. Remove %s to silence this warning.\n", m_banlist_dat);
// If this succeeds then we need to flush to disk in order to create the JSON banlist. }
dirty = true; // If the JSON banlist does not exist, then recreate it
return DeserializeFileDB(m_banlist_dat, banSet, CLIENT_VERSION); if (!fs::exists(m_banlist_json)) {
return false;
} }
dirty = false;
std::map<std::string, util::SettingsValue> settings; std::map<std::string, util::SettingsValue> settings;
std::vector<std::string> errors; std::vector<std::string> errors;

View File

@ -76,7 +76,7 @@ public:
static bool Read(CAddrMan& addr, CDataStream& ssPeers); static bool Read(CAddrMan& addr, CDataStream& ssPeers);
}; };
/** Access to the banlist databases (banlist.json and banlist.dat) */ /** Access to the banlist database (banlist.json) */
class CBanDB class CBanDB
{ {
private: private:
@ -95,11 +95,9 @@ public:
* Read the banlist from disk. * Read the banlist from disk.
* @param[out] banSet The loaded list. Set if `true` is returned, otherwise it is left * @param[out] banSet The loaded list. Set if `true` is returned, otherwise it is left
* in an undefined state. * in an undefined state.
* @param[out] dirty Indicates whether the loaded list needs flushing to disk. Set if
* `true` is returned, otherwise it is left in an undefined state.
* @return true on success * @return true on success
*/ */
bool Read(banmap_t& banSet, bool& dirty); bool Read(banmap_t& banSet);
}; };
/** /**

View File

@ -18,7 +18,7 @@ BanMan::BanMan(fs::path ban_file, CClientUIInterface* client_interface, int64_t
if (m_client_interface) m_client_interface->InitMessage(_("Loading banlist...").translated); if (m_client_interface) m_client_interface->InitMessage(_("Loading banlist...").translated);
int64_t n_start = GetTimeMillis(); int64_t n_start = GetTimeMillis();
if (m_ban_db.Read(m_banned, m_is_dirty)) { if (m_ban_db.Read(m_banned)) {
SweepBanned(); // sweep out unused entries SweepBanned(); // sweep out unused entries
LogPrint(BCLog::NET, "Loaded %d banned node addresses/subnets %dms\n", m_banned.size(), LogPrint(BCLog::NET, "Loaded %d banned node addresses/subnets %dms\n", m_banned.size(),

View File

@ -89,7 +89,7 @@ private:
RecursiveMutex m_cs_banned; RecursiveMutex m_cs_banned;
banmap_t m_banned GUARDED_BY(m_cs_banned); banmap_t m_banned GUARDED_BY(m_cs_banned);
bool m_is_dirty GUARDED_BY(m_cs_banned); bool m_is_dirty GUARDED_BY(m_cs_banned){false};
CClientUIInterface* m_client_interface = nullptr; CClientUIInterface* m_client_interface = nullptr;
CBanDB m_ban_db; CBanDB m_ban_db;
const int64_t m_default_ban_time; const int64_t m_default_ban_time;

View File

@ -41,8 +41,7 @@ static constexpr int ADDRV2_FORMAT = 0x20000000;
* over all enum values and also `GetExtNetwork()` "extends" this enum by * over all enum values and also `GetExtNetwork()` "extends" this enum by
* introducing standalone constants starting from `NET_MAX`. * introducing standalone constants starting from `NET_MAX`.
*/ */
enum Network enum Network {
{
/// Addresses from these networks are not publicly routable on the global Internet. /// Addresses from these networks are not publicly routable on the global Internet.
NET_UNROUTABLE = 0, NET_UNROUTABLE = 0,
@ -72,16 +71,14 @@ enum Network
/// Prefix of an IPv6 address when it contains an embedded IPv4 address. /// Prefix of an IPv6 address when it contains an embedded IPv4 address.
/// Used when (un)serializing addresses in ADDRv1 format (pre-BIP155). /// Used when (un)serializing addresses in ADDRv1 format (pre-BIP155).
static const std::array<uint8_t, 12> IPV4_IN_IPV6_PREFIX{ static const std::array<uint8_t, 12> IPV4_IN_IPV6_PREFIX{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF};
};
/// Prefix of an IPv6 address when it contains an embedded TORv2 address. /// Prefix of an IPv6 address when it contains an embedded TORv2 address.
/// Used when (un)serializing addresses in ADDRv1 format (pre-BIP155). /// Used when (un)serializing addresses in ADDRv1 format (pre-BIP155).
/// Such dummy IPv6 addresses are guaranteed to not be publicly routable as they /// Such dummy IPv6 addresses are guaranteed to not be publicly routable as they
/// fall under RFC4193's fc00::/7 subnet allocated to unique-local addresses. /// fall under RFC4193's fc00::/7 subnet allocated to unique-local addresses.
static const std::array<uint8_t, 6> TORV2_IN_IPV6_PREFIX{ static const std::array<uint8_t, 6> TORV2_IN_IPV6_PREFIX{
0xFD, 0x87, 0xD8, 0x7E, 0xEB, 0x43 0xFD, 0x87, 0xD8, 0x7E, 0xEB, 0x43};
};
/// Prefix of an IPv6 address when it contains an embedded "internal" address. /// Prefix of an IPv6 address when it contains an embedded "internal" address.
/// Used when (un)serializing addresses in ADDRv1 format (pre-BIP155). /// Used when (un)serializing addresses in ADDRv1 format (pre-BIP155).
@ -119,455 +116,438 @@ static constexpr uint16_t I2P_SAM31_PORT{0};
*/ */
class CNetAddr class CNetAddr
{ {
protected: protected:
/** /**
* Raw representation of the network address. * Raw representation of the network address.
* In network byte order (big endian) for IPv4 and IPv6. * In network byte order (big endian) for IPv4 and IPv6.
*/ */
prevector<ADDR_IPV6_SIZE, uint8_t> m_addr{ADDR_IPV6_SIZE, 0x0}; prevector<ADDR_IPV6_SIZE, uint8_t> m_addr{ADDR_IPV6_SIZE, 0x0};
/** /**
* Network to which this address belongs. * Network to which this address belongs.
*/ */
Network m_net{NET_IPV6}; Network m_net{NET_IPV6};
/** /**
* Scope id if scoped/link-local IPV6 address. * Scope id if scoped/link-local IPV6 address.
* See https://tools.ietf.org/html/rfc4007 * See https://tools.ietf.org/html/rfc4007
*/ */
uint32_t m_scope_id{0}; uint32_t m_scope_id{0};
public: public:
CNetAddr(); CNetAddr();
explicit CNetAddr(const struct in_addr& ipv4Addr); explicit CNetAddr(const struct in_addr& ipv4Addr);
void SetIP(const CNetAddr& ip); void SetIP(const CNetAddr& ip);
/** /**
* Set from a legacy IPv6 address. * Set from a legacy IPv6 address.
* Legacy IPv6 address may be a normal IPv6 address, or another address * Legacy IPv6 address may be a normal IPv6 address, or another address
* (e.g. IPv4) disguised as IPv6. This encoding is used in the legacy * (e.g. IPv4) disguised as IPv6. This encoding is used in the legacy
* `addr` encoding. * `addr` encoding.
*/ */
void SetLegacyIPv6(Span<const uint8_t> ipv6); void SetLegacyIPv6(Span<const uint8_t> ipv6);
/** /**
* Set raw IPv4 or IPv6 address (in network byte order) * Set raw IPv4 or IPv6 address (in network byte order)
* @note Only NET_IPV4 and NET_IPV6 are allowed for network. * @note Only NET_IPV4 and NET_IPV6 are allowed for network.
*/ */
void SetRaw(Network network, const uint8_t *data); void SetRaw(Network network, const uint8_t *data);
public: public:
bool SetInternal(const std::string& name); bool SetInternal(const std::string& name);
/** /**
* Parse a Tor or I2P address and set this object to it. * Parse a Tor or I2P address and set this object to it.
* @param[in] addr Address to parse, for example * @param[in] addr Address to parse, for example
* pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion or * pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion or
* ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq.b32.i2p. * ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq.b32.i2p.
* @returns Whether the operation was successful. * @returns Whether the operation was successful.
* @see CNetAddr::IsTor(), CNetAddr::IsI2P() * @see CNetAddr::IsTor(), CNetAddr::IsI2P()
*/ */
bool SetSpecial(const std::string& addr); bool SetSpecial(const std::string& addr);
bool IsBindAny() const; // INADDR_ANY equivalent bool IsBindAny() const; // INADDR_ANY equivalent
bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0) bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor) bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor)
bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12) bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
bool IsRFC2544() const; // IPv4 inter-network communications (198.18.0.0/15) bool IsRFC2544() const; // IPv4 inter-network communications (198.18.0.0/15)
bool IsRFC6598() const; // IPv4 ISP-level NAT (100.64.0.0/10) bool IsRFC6598() const; // IPv4 ISP-level NAT (100.64.0.0/10)
bool IsRFC5737() const; // IPv4 documentation addresses (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24) bool IsRFC5737() const; // IPv4 documentation addresses (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24)
bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32) bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32)
bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16) bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16)
bool IsRFC3964() const; // IPv6 6to4 tunnelling (2002::/16) bool IsRFC3964() const; // IPv6 6to4 tunnelling (2002::/16)
bool IsRFC4193() const; // IPv6 unique local (FC00::/7) bool IsRFC4193() const; // IPv6 unique local (FC00::/7)
bool IsRFC4380() const; // IPv6 Teredo tunnelling (2001::/32) bool IsRFC4380() const; // IPv6 Teredo tunnelling (2001::/32)
bool IsRFC4843() const; // IPv6 ORCHID (deprecated) (2001:10::/28) bool IsRFC4843() const; // IPv6 ORCHID (deprecated) (2001:10::/28)
bool IsRFC7343() const; // IPv6 ORCHIDv2 (2001:20::/28) bool IsRFC7343() const; // IPv6 ORCHIDv2 (2001:20::/28)
bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64) bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64)
bool IsRFC6052() const; // IPv6 well-known prefix for IPv4-embedded address (64:FF9B::/96) bool IsRFC6052() const; // IPv6 well-known prefix for IPv4-embedded address (64:FF9B::/96)
bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96) (actually defined in RFC2765) bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96) (actually defined in RFC2765)
bool IsHeNet() const; // IPv6 Hurricane Electric - https://he.net (2001:0470::/36) bool IsHeNet() const; // IPv6 Hurricane Electric - https://he.net (2001:0470::/36)
bool IsTor() const; bool IsTor() const;
bool IsI2P() const; bool IsI2P() const;
bool IsCJDNS() const; bool IsCJDNS() const;
bool IsLocal() const; bool IsLocal() const;
bool IsRoutable() const; bool IsRoutable() const;
bool IsInternal() const; bool IsInternal() const;
bool IsValid() const; bool IsValid() const;
/** /**
* Check if the current object can be serialized in pre-ADDRv2/BIP155 format. * Check if the current object can be serialized in pre-ADDRv2/BIP155 format.
*/ */
bool IsAddrV1Compatible() const; bool IsAddrV1Compatible() const;
enum Network GetNetwork() const; enum Network GetNetwork() const;
std::string ToString() const; std::string ToString() const;
std::string ToStringIP(bool fUseGetnameinfo = true) const; std::string ToStringIP(bool fUseGetnameinfo = true) const;
uint64_t GetHash() const; uint64_t GetHash() const;
bool GetInAddr(struct in_addr* pipv4Addr) const; bool GetInAddr(struct in_addr* pipv4Addr) const;
Network GetNetClass() const; Network GetNetClass() const;
//! For IPv4, mapped IPv4, SIIT translated IPv4, Teredo, 6to4 tunneled addresses, return the relevant IPv4 address as a uint32. //! For IPv4, mapped IPv4, SIIT translated IPv4, Teredo, 6to4 tunneled addresses, return the relevant IPv4 address as a uint32.
uint32_t GetLinkedIPv4() const; uint32_t GetLinkedIPv4() const;
//! Whether this address has a linked IPv4 address (see GetLinkedIPv4()). //! Whether this address has a linked IPv4 address (see GetLinkedIPv4()).
bool HasLinkedIPv4() const; bool HasLinkedIPv4() const;
// The AS on the BGP path to the node we use to diversify // The AS on the BGP path to the node we use to diversify
// peers in AddrMan bucketing based on the AS infrastructure. // peers in AddrMan bucketing based on the AS infrastructure.
// The ip->AS mapping depends on how asmap is constructed. // The ip->AS mapping depends on how asmap is constructed.
uint32_t GetMappedAS(const std::vector<bool> &asmap) const; uint32_t GetMappedAS(const std::vector<bool> &asmap) const;
std::vector<unsigned char> GetGroup(const std::vector<bool> &asmap) const;
std::vector<unsigned char> GetAddrBytes() const;
int GetReachabilityFrom(const CNetAddr *paddrPartner = nullptr) const;
explicit CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0); std::vector<unsigned char> GetGroup(const std::vector<bool> &asmap) const;
bool GetIn6Addr(struct in6_addr* pipv6Addr) const; std::vector<unsigned char> GetAddrBytes() const;
int GetReachabilityFrom(const CNetAddr *paddrPartner = nullptr) const;
friend bool operator==(const CNetAddr& a, const CNetAddr& b); explicit CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0);
friend bool operator!=(const CNetAddr& a, const CNetAddr& b) { return !(a == b); } bool GetIn6Addr(struct in6_addr* pipv6Addr) const;
friend bool operator<(const CNetAddr& a, const CNetAddr& b);
/** friend bool operator==(const CNetAddr& a, const CNetAddr& b);
* Serialize to a stream. friend bool operator!=(const CNetAddr& a, const CNetAddr& b) { return !(a == b); }
*/ friend bool operator<(const CNetAddr& a, const CNetAddr& b);
template <typename Stream>
void Serialize(Stream& s) const /**
{ * Serialize to a stream.
if (s.GetVersion() & ADDRV2_FORMAT) { */
SerializeV2Stream(s); template <typename Stream>
} else { void Serialize(Stream& s) const
SerializeV1Stream(s); {
} if (s.GetVersion() & ADDRV2_FORMAT) {
SerializeV2Stream(s);
} else {
SerializeV1Stream(s);
}
}
/**
* Unserialize from a stream.
*/
template <typename Stream>
void Unserialize(Stream& s)
{
if (s.GetVersion() & ADDRV2_FORMAT) {
UnserializeV2Stream(s);
} else {
UnserializeV1Stream(s);
}
}
friend class CSubNet;
private:
/**
* 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.
* @returns Whether the operation was successful.
* @see CNetAddr::IsTor()
*/
bool SetTor(const std::string& addr);
/**
* Parse an I2P address and set this object to it.
* @param[in] addr Address to parse, must be a valid C string, for example
* ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq.b32.i2p.
* @returns Whether the operation was successful.
* @see CNetAddr::IsI2P()
*/
bool SetI2P(const std::string& addr);
/**
* BIP155 network ids recognized by this software.
*/
enum BIP155Network : uint8_t {
IPV4 = 1,
IPV6 = 2,
TORV2 = 3,
TORV3 = 4,
I2P = 5,
CJDNS = 6,
};
/**
* Size of CNetAddr when serialized as ADDRv1 (pre-BIP155) (in bytes).
*/
static constexpr size_t V1_SERIALIZATION_SIZE = ADDR_IPV6_SIZE;
/**
* Maximum size of an address as defined in BIP155 (in bytes).
* This is only the size of the address, not the entire CNetAddr object
* when serialized.
*/
static constexpr size_t MAX_ADDRV2_SIZE = 512;
/**
* Get the BIP155 network id of this address.
* Must not be called for IsInternal() objects.
* @returns BIP155 network id, except TORV2 which is no longer supported.
*/
BIP155Network GetBIP155Network() const;
/**
* Set `m_net` from the provided BIP155 network id and size after validation.
* @retval true the network was recognized, is valid and `m_net` was set
* @retval false not recognised (from future?) and should be silently ignored
* @throws std::ios_base::failure if the network is one of the BIP155 founding
* networks (id 1..6) with wrong address size.
*/
bool SetNetFromBIP155Network(uint8_t possible_bip155_net, size_t address_size);
/**
* Serialize in pre-ADDRv2/BIP155 format to an array.
*/
void SerializeV1Array(uint8_t (&arr)[V1_SERIALIZATION_SIZE]) const
{
size_t prefix_size;
switch (m_net) {
case NET_IPV6:
assert(m_addr.size() == sizeof(arr));
memcpy(arr, m_addr.data(), m_addr.size());
return;
case NET_IPV4:
prefix_size = sizeof(IPV4_IN_IPV6_PREFIX);
assert(prefix_size + m_addr.size() == sizeof(arr));
memcpy(arr, IPV4_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:
case NET_CJDNS:
break;
case NET_UNROUTABLE:
case NET_MAX:
assert(false);
} // no default case, so the compiler can warn about missing cases
// Serialize ONION, I2P and CJDNS as all-zeros.
memset(arr, 0x0, V1_SERIALIZATION_SIZE);
}
public:
/**
* Serialize in pre-ADDRv2/BIP155 format to a stream.
*/
template <typename Stream>
void SerializeV1Stream(Stream& s) const
{
uint8_t serialized[V1_SERIALIZATION_SIZE];
SerializeV1Array(serialized);
s << serialized;
}
/**
* Serialize as ADDRv2 / BIP155.
*/
template <typename Stream>
void SerializeV2Stream(Stream& s) const
{
if (IsInternal()) {
// Serialize NET_INTERNAL as embedded in IPv6. We need to
// serialize such addresses from addrman.
s << static_cast<uint8_t>(BIP155Network::IPV6);
s << COMPACTSIZE(ADDR_IPV6_SIZE);
SerializeV1Stream(s);
return;
} }
/** s << static_cast<uint8_t>(GetBIP155Network());
* Unserialize from a stream. s << m_addr;
*/ }
template <typename Stream>
void Unserialize(Stream& s) /**
{ * Unserialize from a pre-ADDRv2/BIP155 format from an array.
if (s.GetVersion() & ADDRV2_FORMAT) { */
UnserializeV2Stream(s); void UnserializeV1Array(uint8_t (&arr)[V1_SERIALIZATION_SIZE])
} else { {
UnserializeV1Stream(s); // Use SetLegacyIPv6() so that m_net is set correctly. For example
} // ::FFFF:0102:0304 should be set as m_net=NET_IPV4 (1.2.3.4).
SetLegacyIPv6(arr);
}
/**
* Unserialize from a pre-ADDRv2/BIP155 format from a stream.
*/
template <typename Stream>
void UnserializeV1Stream(Stream& s)
{
uint8_t serialized[V1_SERIALIZATION_SIZE];
s >> serialized;
UnserializeV1Array(serialized);
}
/**
* Unserialize from a ADDRv2 / BIP155 format.
*/
template <typename Stream>
void UnserializeV2Stream(Stream& s)
{
uint8_t bip155_net;
s >> bip155_net;
size_t address_size;
s >> COMPACTSIZE(address_size);
if (address_size > MAX_ADDRV2_SIZE) {
throw std::ios_base::failure(strprintf(
"Address too long: %u > %u", address_size, MAX_ADDRV2_SIZE));
} }
friend class CSubNet; m_scope_id = 0;
private: if (SetNetFromBIP155Network(bip155_net, address_size)) {
/** m_addr.resize(address_size);
* Parse a Tor address and set this object to it. s >> MakeSpan(m_addr);
* @param[in] addr Address to parse, must be a valid C string, for example
* pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion.
* @returns Whether the operation was successful.
* @see CNetAddr::IsTor()
*/
bool SetTor(const std::string& addr);
/** if (m_net != NET_IPV6) {
* Parse an I2P address and set this object to it.
* @param[in] addr Address to parse, must be a valid C string, for example
* ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq.b32.i2p.
* @returns Whether the operation was successful.
* @see CNetAddr::IsI2P()
*/
bool SetI2P(const std::string& addr);
/**
* BIP155 network ids recognized by this software.
*/
enum BIP155Network : uint8_t {
IPV4 = 1,
IPV6 = 2,
TORV2 = 3,
TORV3 = 4,
I2P = 5,
CJDNS = 6,
};
/**
* Size of CNetAddr when serialized as ADDRv1 (pre-BIP155) (in bytes).
*/
static constexpr size_t V1_SERIALIZATION_SIZE = ADDR_IPV6_SIZE;
/**
* Maximum size of an address as defined in BIP155 (in bytes).
* This is only the size of the address, not the entire CNetAddr object
* when serialized.
*/
static constexpr size_t MAX_ADDRV2_SIZE = 512;
/**
* Get the BIP155 network id of this address.
* Must not be called for IsInternal() objects.
* @returns BIP155 network id, except TORV2 which is no longer supported.
*/
BIP155Network GetBIP155Network() const;
/**
* Set `m_net` from the provided BIP155 network id and size after validation.
* @retval true the network was recognized, is valid and `m_net` was set
* @retval false not recognised (from future?) and should be silently ignored
* @throws std::ios_base::failure if the network is one of the BIP155 founding
* networks (id 1..6) with wrong address size.
*/
bool SetNetFromBIP155Network(uint8_t possible_bip155_net, size_t address_size);
/**
* Serialize in pre-ADDRv2/BIP155 format to an array.
*/
void SerializeV1Array(uint8_t (&arr)[V1_SERIALIZATION_SIZE]) const
{
size_t prefix_size;
switch (m_net) {
case NET_IPV6:
assert(m_addr.size() == sizeof(arr));
memcpy(arr, m_addr.data(), m_addr.size());
return;
case NET_IPV4:
prefix_size = sizeof(IPV4_IN_IPV6_PREFIX);
assert(prefix_size + m_addr.size() == sizeof(arr));
memcpy(arr, IPV4_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:
case NET_CJDNS:
break;
case NET_UNROUTABLE:
case NET_MAX:
assert(false);
} // no default case, so the compiler can warn about missing cases
// Serialize ONION, I2P and CJDNS as all-zeros.
memset(arr, 0x0, V1_SERIALIZATION_SIZE);
}
public:
/**
* Serialize in pre-ADDRv2/BIP155 format to a stream.
*/
template <typename Stream>
void SerializeV1Stream(Stream& s) const
{
uint8_t serialized[V1_SERIALIZATION_SIZE];
SerializeV1Array(serialized);
s << serialized;
}
/**
* Serialize as ADDRv2 / BIP155.
*/
template <typename Stream>
void SerializeV2Stream(Stream& s) const
{
if (IsInternal()) {
// Serialize NET_INTERNAL as embedded in IPv6. We need to
// serialize such addresses from addrman.
s << static_cast<uint8_t>(BIP155Network::IPV6);
s << COMPACTSIZE(ADDR_IPV6_SIZE);
SerializeV1Stream(s);
return; return;
} }
s << static_cast<uint8_t>(GetBIP155Network()); // Do some special checks on IPv6 addresses.
s << m_addr;
}
/** // Recognize NET_INTERNAL embedded in IPv6, such addresses are not
* Unserialize from a pre-ADDRv2/BIP155 format from an array. // gossiped but could be coming from addrman, when unserializing from
*/ // disk.
void UnserializeV1Array(uint8_t (&arr)[V1_SERIALIZATION_SIZE]) if (HasPrefix(m_addr, INTERNAL_IN_IPV6_PREFIX)) {
{ m_net = NET_INTERNAL;
// Use SetLegacyIPv6() so that m_net is set correctly. For example memmove(m_addr.data(), m_addr.data() + INTERNAL_IN_IPV6_PREFIX.size(),
// ::FFFF:0102:0304 should be set as m_net=NET_IPV4 (1.2.3.4). ADDR_INTERNAL_SIZE);
SetLegacyIPv6(arr); m_addr.resize(ADDR_INTERNAL_SIZE);
} return;
/**
* Unserialize from a pre-ADDRv2/BIP155 format from a stream.
*/
template <typename Stream>
void UnserializeV1Stream(Stream& s)
{
uint8_t serialized[V1_SERIALIZATION_SIZE];
s >> serialized;
UnserializeV1Array(serialized);
}
/**
* Unserialize from a ADDRv2 / BIP155 format.
*/
template <typename Stream>
void UnserializeV2Stream(Stream& s)
{
uint8_t bip155_net;
s >> bip155_net;
size_t address_size;
s >> COMPACTSIZE(address_size);
if (address_size > MAX_ADDRV2_SIZE) {
throw std::ios_base::failure(strprintf(
"Address too long: %u > %u", address_size, MAX_ADDRV2_SIZE));
} }
m_scope_id = 0; if (!HasPrefix(m_addr, IPV4_IN_IPV6_PREFIX) &&
!HasPrefix(m_addr, TORV2_IN_IPV6_PREFIX)) {
if (SetNetFromBIP155Network(bip155_net, address_size)) { return;
m_addr.resize(address_size);
s >> MakeSpan(m_addr);
if (m_net != NET_IPV6) {
return;
}
// Do some special checks on IPv6 addresses.
// Recognize NET_INTERNAL embedded in IPv6, such addresses are not
// gossiped but could be coming from addrman, when unserializing from
// disk.
if (HasPrefix(m_addr, INTERNAL_IN_IPV6_PREFIX)) {
m_net = NET_INTERNAL;
memmove(m_addr.data(), m_addr.data() + INTERNAL_IN_IPV6_PREFIX.size(),
ADDR_INTERNAL_SIZE);
m_addr.resize(ADDR_INTERNAL_SIZE);
return;
}
if (!HasPrefix(m_addr, IPV4_IN_IPV6_PREFIX) &&
!HasPrefix(m_addr, TORV2_IN_IPV6_PREFIX)) {
return;
}
// IPv4 and TORv2 are not supposed to be embedded in IPv6 (like in V1
// encoding). Unserialize as !IsValid(), thus ignoring them.
} else {
// If we receive an unknown BIP155 network id (from the future?) then
// ignore the address - unserialize as !IsValid().
s.ignore(address_size);
} }
// Mimic a default-constructed CNetAddr object which is !IsValid() and thus // IPv4 and TORv2 are not supposed to be embedded in IPv6 (like in V1
// will not be gossiped, but continue reading next addresses from the stream. // encoding). Unserialize as !IsValid(), thus ignoring them.
m_net = NET_IPV6; } else {
m_addr.assign(ADDR_IPV6_SIZE, 0x0); // If we receive an unknown BIP155 network id (from the future?) then
// ignore the address - unserialize as !IsValid().
s.ignore(address_size);
} }
// 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);
}
}; };
class CSubNet class CSubNet
{ {
protected: protected:
/// Network (base) address /// Network (base) address
CNetAddr network; CNetAddr network;
/// Netmask, in network byte order /// Netmask, in network byte order
uint8_t netmask[16]; uint8_t netmask[16];
/// Is this value valid? (only used to signal parse errors) /// Is this value valid? (only used to signal parse errors)
bool valid; bool valid;
bool SanityCheck() const; bool SanityCheck() const;
public: public:
/** /**
* Construct an invalid subnet (empty, `Match()` always returns false). * Construct an invalid subnet (empty, `Match()` always returns false).
*/ */
CSubNet(); CSubNet();
/** /**
* Construct from a given network start and number of bits (CIDR mask). * 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 * @param[in] addr Network start. Must be IPv4 or IPv6, otherwise an invalid subnet is
* created. * created.
* @param[in] mask CIDR mask, must be in [0, 32] for IPv4 addresses and in [0, 128] for * @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. * IPv6 addresses. Otherwise an invalid subnet is created.
*/ */
CSubNet(const CNetAddr& addr, uint8_t mask); CSubNet(const CNetAddr& addr, uint8_t mask);
/** /**
* Construct from a given network start and mask. * Construct from a given network start and mask.
* @param[in] addr Network start. Must be IPv4 or IPv6, otherwise an invalid subnet is * @param[in] addr Network start. Must be IPv4 or IPv6, otherwise an invalid subnet is
* created. * created.
* @param[in] mask Network mask, must be of the same type as `addr` and not contain 0-bits * @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. * followed by 1-bits. Otherwise an invalid subnet is created.
*/ */
CSubNet(const CNetAddr& addr, const CNetAddr& mask); CSubNet(const CNetAddr& addr, const CNetAddr& mask);
/** /**
* Construct a single-host subnet. * Construct a single-host subnet.
* @param[in] addr The sole address to be contained in the subnet, can also be non-IPv[46]. * @param[in] addr The sole address to be contained in the subnet, can also be non-IPv[46].
*/ */
explicit CSubNet(const CNetAddr& addr); explicit CSubNet(const CNetAddr& addr);
bool Match(const CNetAddr &addr) const; bool Match(const CNetAddr &addr) const;
std::string ToString() const; std::string ToString() const;
bool IsValid() const; bool IsValid() const;
friend bool operator==(const CSubNet& a, const CSubNet& b); friend bool operator==(const CSubNet& a, const CSubNet& b);
friend bool operator!=(const CSubNet& a, const CSubNet& b) { return !(a == b); } friend bool operator!=(const CSubNet& a, const CSubNet& b) { return !(a == b); }
friend bool operator<(const CSubNet& a, const CSubNet& b); friend bool operator<(const CSubNet& a, const CSubNet& b);
SERIALIZE_METHODS(CSubNet, obj)
{
READWRITE(obj.network);
if (obj.network.IsIPv4()) {
// Before commit 102867c587f5f7954232fb8ed8e85cda78bb4d32, CSubNet used the last 4 bytes of netmask
// to store the relevant bytes for an IPv4 mask. For compatibility reasons, keep doing so in
// serialized form.
unsigned char dummy[12] = {0};
READWRITE(dummy);
READWRITE(MakeSpan(obj.netmask).first(4));
} else {
READWRITE(obj.netmask);
}
READWRITE(obj.valid);
// Mark invalid if the result doesn't pass sanity checking.
SER_READ(obj, if (obj.valid) obj.valid = obj.SanityCheck());
}
}; };
/** A combination of a network address (CNetAddr) and a (TCP) port */ /** A combination of a network address (CNetAddr) and a (TCP) port */
class CService : public CNetAddr class CService : public CNetAddr
{ {
protected: protected:
uint16_t port; // host order uint16_t port; // host order
public: public:
CService(); CService();
CService(const CNetAddr& ip, uint16_t port); CService(const CNetAddr& ip, uint16_t port);
CService(const struct in_addr& ipv4Addr, uint16_t port); CService(const struct in_addr& ipv4Addr, uint16_t port);
explicit CService(const struct sockaddr_in& addr); explicit CService(const struct sockaddr_in& addr);
void SetPort(uint16_t portIn); void SetPort(uint16_t portIn);
uint16_t GetPort() const; uint16_t GetPort() const;
bool GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const; bool GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const;
bool SetSockAddr(const struct sockaddr* paddr); bool SetSockAddr(const struct sockaddr* paddr);
friend bool operator==(const CService& a, const CService& b); friend bool operator==(const CService& a, const CService& b);
friend bool operator!=(const CService& a, const CService& b) { return !(a == b); } friend bool operator!=(const CService& a, const CService& b) { return !(a == b); }
friend bool operator<(const CService& a, const CService& b); friend bool operator<(const CService& a, const CService& b);
std::vector<unsigned char> GetKey() const; std::vector<unsigned char> GetKey() const;
std::string ToString(bool fUseGetnameinfo = true) const; std::string ToString(bool fUseGetnameinfo = true) const;
std::string ToStringPort() const; std::string ToStringPort() const;
std::string ToStringIPPort(bool fUseGetnameinfo = true) const; std::string ToStringIPPort(bool fUseGetnameinfo = true) const;
CService(const struct in6_addr& ipv6Addr, uint16_t port); CService(const struct in6_addr& ipv6Addr, uint16_t port);
explicit CService(const struct sockaddr_in6& addr); explicit CService(const struct sockaddr_in6& addr);
SERIALIZE_METHODS(CService, obj) SERIALIZE_METHODS(CService, obj)
{ {
READWRITEAS(CNetAddr, obj); READWRITEAS(CNetAddr, obj);
READWRITE(Using<BigEndianFormatter<2>>(obj.port)); READWRITE(Using<BigEndianFormatter<2>>(obj.port));
} }
}; };
bool SanityCheckASMap(const std::vector<bool>& asmap); bool SanityCheckASMap(const std::vector<bool>& asmap);

View File

@ -43,8 +43,7 @@ FUZZ_TARGET_INIT(banman, initialize_banman)
const bool start_with_corrupted_banlist{fuzzed_data_provider.ConsumeBool()}; const bool start_with_corrupted_banlist{fuzzed_data_provider.ConsumeBool()};
if (start_with_corrupted_banlist) { if (start_with_corrupted_banlist) {
const std::string sfx{fuzzed_data_provider.ConsumeBool() ? ".dat" : ".json"}; assert(WriteBinaryFile(banlist_file.string() + ".json",
assert(WriteBinaryFile(banlist_file.string() + sfx,
fuzzed_data_provider.ConsumeRandomLengthString())); fuzzed_data_provider.ConsumeRandomLengthString()));
} else { } else {
const bool force_read_and_write_to_err{fuzzed_data_provider.ConsumeBool()}; const bool force_read_and_write_to_err{fuzzed_data_provider.ConsumeBool()};
@ -93,6 +92,5 @@ FUZZ_TARGET_INIT(banman, initialize_banman)
}); });
} }
} }
fs::remove(banlist_file.string() + ".dat");
fs::remove(banlist_file.string() + ".json"); fs::remove(banlist_file.string() + ".json");
} }

View File

@ -100,231 +100,220 @@ void AssertEqualAfterSerializeDeserialize(const T& obj, const int version = INIT
/* /*
FUZZ_TARGET_DESERIALIZE(block_filter_deserialize, { FUZZ_TARGET_DESERIALIZE(block_filter_deserialize, {
BlockFilter block_filter; BlockFilter block_filter;
DeserializeFromFuzzingInput(buffer, block_filter); DeserializeFromFuzzingInput(buffer, block_filter);
}) })
*/ */
FUZZ_TARGET_DESERIALIZE(addr_info_deserialize, { FUZZ_TARGET_DESERIALIZE(addr_info_deserialize, {
CAddrInfo addr_info; CAddrInfo addr_info;
DeserializeFromFuzzingInput(buffer, addr_info); DeserializeFromFuzzingInput(buffer, addr_info);
}) })
FUZZ_TARGET_DESERIALIZE(block_file_info_deserialize, { FUZZ_TARGET_DESERIALIZE(block_file_info_deserialize, {
CBlockFileInfo block_file_info; CBlockFileInfo block_file_info;
DeserializeFromFuzzingInput(buffer, block_file_info); DeserializeFromFuzzingInput(buffer, block_file_info);
}) })
FUZZ_TARGET_DESERIALIZE(block_header_and_short_txids_deserialize, { FUZZ_TARGET_DESERIALIZE(block_header_and_short_txids_deserialize, {
CBlockHeaderAndShortTxIDs block_header_and_short_txids; CBlockHeaderAndShortTxIDs block_header_and_short_txids;
DeserializeFromFuzzingInput(buffer, block_header_and_short_txids); DeserializeFromFuzzingInput(buffer, block_header_and_short_txids);
}) })
FUZZ_TARGET_DESERIALIZE(fee_rate_deserialize, { FUZZ_TARGET_DESERIALIZE(fee_rate_deserialize, {
CFeeRate fee_rate; CFeeRate fee_rate;
DeserializeFromFuzzingInput(buffer, fee_rate); DeserializeFromFuzzingInput(buffer, fee_rate);
AssertEqualAfterSerializeDeserialize(fee_rate); AssertEqualAfterSerializeDeserialize(fee_rate);
}) })
FUZZ_TARGET_DESERIALIZE(merkle_block_deserialize, { FUZZ_TARGET_DESERIALIZE(merkle_block_deserialize, {
CMerkleBlock merkle_block; CMerkleBlock merkle_block;
DeserializeFromFuzzingInput(buffer, merkle_block); DeserializeFromFuzzingInput(buffer, merkle_block);
}) })
FUZZ_TARGET_DESERIALIZE(out_point_deserialize, { FUZZ_TARGET_DESERIALIZE(out_point_deserialize, {
COutPoint out_point; COutPoint out_point;
DeserializeFromFuzzingInput(buffer, out_point); DeserializeFromFuzzingInput(buffer, out_point);
AssertEqualAfterSerializeDeserialize(out_point); AssertEqualAfterSerializeDeserialize(out_point);
}) })
FUZZ_TARGET_DESERIALIZE(partial_merkle_tree_deserialize, { FUZZ_TARGET_DESERIALIZE(partial_merkle_tree_deserialize, {
CPartialMerkleTree partial_merkle_tree; CPartialMerkleTree partial_merkle_tree;
DeserializeFromFuzzingInput(buffer, partial_merkle_tree); DeserializeFromFuzzingInput(buffer, partial_merkle_tree);
}) })
FUZZ_TARGET_DESERIALIZE(pub_key_deserialize, { FUZZ_TARGET_DESERIALIZE(pub_key_deserialize, {
CPubKey pub_key; CPubKey pub_key;
DeserializeFromFuzzingInput(buffer, pub_key); DeserializeFromFuzzingInput(buffer, pub_key);
AssertEqualAfterSerializeDeserialize(pub_key); AssertEqualAfterSerializeDeserialize(pub_key);
}) })
FUZZ_TARGET_DESERIALIZE(script_deserialize, { FUZZ_TARGET_DESERIALIZE(script_deserialize, {
CScript script; CScript script;
DeserializeFromFuzzingInput(buffer, script); DeserializeFromFuzzingInput(buffer, script);
})
FUZZ_TARGET_DESERIALIZE(subnet_deserialize, {
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, { FUZZ_TARGET_DESERIALIZE(tx_in_deserialize, {
CTxIn tx_in; CTxIn tx_in;
DeserializeFromFuzzingInput(buffer, tx_in); DeserializeFromFuzzingInput(buffer, tx_in);
AssertEqualAfterSerializeDeserialize(tx_in); AssertEqualAfterSerializeDeserialize(tx_in);
}) })
/* /*
FUZZ_TARGET_DESERIALIZE(flat_file_pos_deserialize, { FUZZ_TARGET_DESERIALIZE(flat_file_pos_deserialize, {
FlatFilePos flat_file_pos; FlatFilePos flat_file_pos;
DeserializeFromFuzzingInput(buffer, flat_file_pos); DeserializeFromFuzzingInput(buffer, flat_file_pos);
AssertEqualAfterSerializeDeserialize(flat_file_pos); AssertEqualAfterSerializeDeserialize(flat_file_pos);
}) })
FUZZ_TARGET_DESERIALIZE(key_origin_info_deserialize, { FUZZ_TARGET_DESERIALIZE(key_origin_info_deserialize, {
KeyOriginInfo key_origin_info; KeyOriginInfo key_origin_info;
DeserializeFromFuzzingInput(buffer, key_origin_info); DeserializeFromFuzzingInput(buffer, key_origin_info);
AssertEqualAfterSerializeDeserialize(key_origin_info); AssertEqualAfterSerializeDeserialize(key_origin_info);
}) })
*/ */
FUZZ_TARGET_DESERIALIZE(partially_signed_transaction_deserialize, { FUZZ_TARGET_DESERIALIZE(partially_signed_transaction_deserialize, {
PartiallySignedTransaction partially_signed_transaction; PartiallySignedTransaction partially_signed_transaction;
DeserializeFromFuzzingInput(buffer, partially_signed_transaction); DeserializeFromFuzzingInput(buffer, partially_signed_transaction);
}) })
FUZZ_TARGET_DESERIALIZE(prefilled_transaction_deserialize, { FUZZ_TARGET_DESERIALIZE(prefilled_transaction_deserialize, {
PrefilledTransaction prefilled_transaction; PrefilledTransaction prefilled_transaction;
DeserializeFromFuzzingInput(buffer, prefilled_transaction); DeserializeFromFuzzingInput(buffer, prefilled_transaction);
}) })
FUZZ_TARGET_DESERIALIZE(psbt_input_deserialize, { FUZZ_TARGET_DESERIALIZE(psbt_input_deserialize, {
PSBTInput psbt_input; PSBTInput psbt_input;
DeserializeFromFuzzingInput(buffer, psbt_input); DeserializeFromFuzzingInput(buffer, psbt_input);
}) })
FUZZ_TARGET_DESERIALIZE(psbt_output_deserialize, { FUZZ_TARGET_DESERIALIZE(psbt_output_deserialize, {
PSBTOutput psbt_output; PSBTOutput psbt_output;
DeserializeFromFuzzingInput(buffer, psbt_output); DeserializeFromFuzzingInput(buffer, psbt_output);
}) })
FUZZ_TARGET_DESERIALIZE(block_deserialize, { FUZZ_TARGET_DESERIALIZE(block_deserialize, {
CBlock block; CBlock block;
DeserializeFromFuzzingInput(buffer, block); DeserializeFromFuzzingInput(buffer, block);
}) })
FUZZ_TARGET_DESERIALIZE(blocklocator_deserialize, { FUZZ_TARGET_DESERIALIZE(blocklocator_deserialize, {
CBlockLocator bl; CBlockLocator bl;
DeserializeFromFuzzingInput(buffer, bl); DeserializeFromFuzzingInput(buffer, bl);
}) })
FUZZ_TARGET_DESERIALIZE(blockmerkleroot, { FUZZ_TARGET_DESERIALIZE(blockmerkleroot, {
CBlock block; CBlock block;
DeserializeFromFuzzingInput(buffer, block); DeserializeFromFuzzingInput(buffer, block);
bool mutated; bool mutated;
BlockMerkleRoot(block, &mutated); BlockMerkleRoot(block, &mutated);
}) })
FUZZ_TARGET_DESERIALIZE(addrman_deserialize, { FUZZ_TARGET_DESERIALIZE(addrman_deserialize, {
CAddrMan am; CAddrMan am;
DeserializeFromFuzzingInput(buffer, am); DeserializeFromFuzzingInput(buffer, am);
}) })
FUZZ_TARGET_DESERIALIZE(blockheader_deserialize, { FUZZ_TARGET_DESERIALIZE(blockheader_deserialize, {
CBlockHeader bh; CBlockHeader bh;
DeserializeFromFuzzingInput(buffer, bh); DeserializeFromFuzzingInput(buffer, bh);
}) })
FUZZ_TARGET_DESERIALIZE(banentry_deserialize, { FUZZ_TARGET_DESERIALIZE(banentry_deserialize, {
CBanEntry be; CBanEntry be;
DeserializeFromFuzzingInput(buffer, be); DeserializeFromFuzzingInput(buffer, be);
}) })
FUZZ_TARGET_DESERIALIZE(txundo_deserialize, { FUZZ_TARGET_DESERIALIZE(txundo_deserialize, {
CTxUndo tu; CTxUndo tu;
DeserializeFromFuzzingInput(buffer, tu); DeserializeFromFuzzingInput(buffer, tu);
}) })
FUZZ_TARGET_DESERIALIZE(blockundo_deserialize, { FUZZ_TARGET_DESERIALIZE(blockundo_deserialize, {
CBlockUndo bu; CBlockUndo bu;
DeserializeFromFuzzingInput(buffer, bu); DeserializeFromFuzzingInput(buffer, bu);
}) })
FUZZ_TARGET_DESERIALIZE(coins_deserialize, { FUZZ_TARGET_DESERIALIZE(coins_deserialize, {
Coin coin; Coin coin;
DeserializeFromFuzzingInput(buffer, coin); DeserializeFromFuzzingInput(buffer, coin);
}) })
FUZZ_TARGET_DESERIALIZE(net_address_deserialize, { FUZZ_TARGET_DESERIALIZE(net_address_deserialize, {
CNetAddr na; CNetAddr na;
DeserializeFromFuzzingInput(buffer, na); DeserializeFromFuzzingInput(buffer, na);
if (na.IsAddrV1Compatible()) { if (na.IsAddrV1Compatible()) {
AssertEqualAfterSerializeDeserialize(na); AssertEqualAfterSerializeDeserialize(na);
} }
AssertEqualAfterSerializeDeserialize(na, INIT_PROTO_VERSION | ADDRV2_FORMAT); AssertEqualAfterSerializeDeserialize(na, INIT_PROTO_VERSION | ADDRV2_FORMAT);
}) })
FUZZ_TARGET_DESERIALIZE(net_service_deserialize, { FUZZ_TARGET_DESERIALIZE(net_service_deserialize, {
CService s; CService s;
DeserializeFromFuzzingInput(buffer, s); DeserializeFromFuzzingInput(buffer, s);
if (s.IsAddrV1Compatible()) { if (s.IsAddrV1Compatible()) {
AssertEqualAfterSerializeDeserialize(s); AssertEqualAfterSerializeDeserialize(s);
} }
AssertEqualAfterSerializeDeserialize(s, INIT_PROTO_VERSION | ADDRV2_FORMAT); AssertEqualAfterSerializeDeserialize(s, INIT_PROTO_VERSION | ADDRV2_FORMAT);
CService s1; CService s1;
DeserializeFromFuzzingInput(buffer, s1, INIT_PROTO_VERSION); DeserializeFromFuzzingInput(buffer, s1, INIT_PROTO_VERSION);
AssertEqualAfterSerializeDeserialize(s1, INIT_PROTO_VERSION); AssertEqualAfterSerializeDeserialize(s1, INIT_PROTO_VERSION);
assert(s1.IsAddrV1Compatible()); assert(s1.IsAddrV1Compatible());
CService s2; CService s2;
DeserializeFromFuzzingInput(buffer, s2, INIT_PROTO_VERSION | ADDRV2_FORMAT); DeserializeFromFuzzingInput(buffer, s2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
AssertEqualAfterSerializeDeserialize(s2, INIT_PROTO_VERSION | ADDRV2_FORMAT); AssertEqualAfterSerializeDeserialize(s2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
}) })
FUZZ_TARGET_DESERIALIZE(messageheader_deserialize, { FUZZ_TARGET_DESERIALIZE(messageheader_deserialize, {
CMessageHeader mh; CMessageHeader mh;
DeserializeFromFuzzingInput(buffer, mh); DeserializeFromFuzzingInput(buffer, mh);
(void)mh.IsCommandValid(); (void)mh.IsCommandValid();
}) })
FUZZ_TARGET_DESERIALIZE(address_deserialize_v1_notime, { FUZZ_TARGET_DESERIALIZE(address_deserialize_v1_notime, {
CAddress a; CAddress a;
DeserializeFromFuzzingInput(buffer, a, INIT_PROTO_VERSION); DeserializeFromFuzzingInput(buffer, a, INIT_PROTO_VERSION);
// A CAddress without nTime (as is expected under INIT_PROTO_VERSION) will roundtrip // A CAddress without nTime (as is expected under INIT_PROTO_VERSION) will roundtrip
// in all 5 formats (with/without nTime, v1/v2, network/disk) // in all 5 formats (with/without nTime, v1/v2, network/disk)
AssertEqualAfterSerializeDeserialize(a, INIT_PROTO_VERSION); AssertEqualAfterSerializeDeserialize(a, INIT_PROTO_VERSION);
AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION); AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION);
AssertEqualAfterSerializeDeserialize(a, 0, SER_DISK); AssertEqualAfterSerializeDeserialize(a, 0, SER_DISK);
AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION | ADDRV2_FORMAT); AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION | ADDRV2_FORMAT);
AssertEqualAfterSerializeDeserialize(a, ADDRV2_FORMAT, SER_DISK); AssertEqualAfterSerializeDeserialize(a, ADDRV2_FORMAT, SER_DISK);
}) })
FUZZ_TARGET_DESERIALIZE(address_deserialize_v1_withtime, { FUZZ_TARGET_DESERIALIZE(address_deserialize_v1_withtime, {
CAddress a; CAddress a;
DeserializeFromFuzzingInput(buffer, a, PROTOCOL_VERSION); DeserializeFromFuzzingInput(buffer, a, PROTOCOL_VERSION);
// A CAddress in V1 mode will roundtrip in all 4 formats that have nTime. // A CAddress in V1 mode will roundtrip in all 4 formats that have nTime.
AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION); AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION);
AssertEqualAfterSerializeDeserialize(a, 0, SER_DISK); AssertEqualAfterSerializeDeserialize(a, 0, SER_DISK);
AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION | ADDRV2_FORMAT); AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION | ADDRV2_FORMAT);
AssertEqualAfterSerializeDeserialize(a, ADDRV2_FORMAT, SER_DISK); AssertEqualAfterSerializeDeserialize(a, ADDRV2_FORMAT, SER_DISK);
}) })
FUZZ_TARGET_DESERIALIZE(address_deserialize_v2, { FUZZ_TARGET_DESERIALIZE(address_deserialize_v2, {
CAddress a; CAddress a;
DeserializeFromFuzzingInput(buffer, a, PROTOCOL_VERSION | ADDRV2_FORMAT); DeserializeFromFuzzingInput(buffer, a, PROTOCOL_VERSION | ADDRV2_FORMAT);
// A CAddress in V2 mode will roundtrip in both V2 formats, and also in the V1 formats // A CAddress in V2 mode will roundtrip in both V2 formats, and also in the V1 formats
// with time if it's V1 compatible. // with time if it's V1 compatible.
if (a.IsAddrV1Compatible()) { if (a.IsAddrV1Compatible()) {
AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION); AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION);
AssertEqualAfterSerializeDeserialize(a, 0, SER_DISK); AssertEqualAfterSerializeDeserialize(a, 0, SER_DISK);
} }
AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION | ADDRV2_FORMAT); AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION | ADDRV2_FORMAT);
AssertEqualAfterSerializeDeserialize(a, ADDRV2_FORMAT, SER_DISK); AssertEqualAfterSerializeDeserialize(a, ADDRV2_FORMAT, SER_DISK);
}) })
FUZZ_TARGET_DESERIALIZE(inv_deserialize, { FUZZ_TARGET_DESERIALIZE(inv_deserialize, {
CInv i; CInv i;
DeserializeFromFuzzingInput(buffer, i); DeserializeFromFuzzingInput(buffer, i);
}) })
FUZZ_TARGET_DESERIALIZE(bloomfilter_deserialize, { FUZZ_TARGET_DESERIALIZE(bloomfilter_deserialize, {
CBloomFilter bf; CBloomFilter bf;
DeserializeFromFuzzingInput(buffer, bf); DeserializeFromFuzzingInput(buffer, bf);
}) })
FUZZ_TARGET_DESERIALIZE(diskblockindex_deserialize, { FUZZ_TARGET_DESERIALIZE(diskblockindex_deserialize, {
CDiskBlockIndex dbi; CDiskBlockIndex dbi;
DeserializeFromFuzzingInput(buffer, dbi); DeserializeFromFuzzingInput(buffer, dbi);
}) })
FUZZ_TARGET_DESERIALIZE(txoutcompressor_deserialize, { FUZZ_TARGET_DESERIALIZE(txoutcompressor_deserialize, {
CTxOut to; CTxOut to;
auto toc = Using<TxOutCompression>(to); auto toc = Using<TxOutCompression>(to);
DeserializeFromFuzzingInput(buffer, toc); DeserializeFromFuzzingInput(buffer, toc);
}) })
FUZZ_TARGET_DESERIALIZE(blocktransactions_deserialize, { FUZZ_TARGET_DESERIALIZE(blocktransactions_deserialize, {
BlockTransactions bt; BlockTransactions bt;
DeserializeFromFuzzingInput(buffer, bt); DeserializeFromFuzzingInput(buffer, bt);
}) })
FUZZ_TARGET_DESERIALIZE(blocktransactionsrequest_deserialize, { FUZZ_TARGET_DESERIALIZE(blocktransactionsrequest_deserialize, {
BlockTransactionsRequest btr; BlockTransactionsRequest btr;
DeserializeFromFuzzingInput(buffer, btr); DeserializeFromFuzzingInput(buffer, btr);
}) })
FUZZ_TARGET_DESERIALIZE(snapshotmetadata_deserialize, { FUZZ_TARGET_DESERIALIZE(snapshotmetadata_deserialize, {
SnapshotMetadata snapshot_metadata; SnapshotMetadata snapshot_metadata;
DeserializeFromFuzzingInput(buffer, snapshot_metadata); DeserializeFromFuzzingInput(buffer, snapshot_metadata);
}) })
FUZZ_TARGET_DESERIALIZE(uint160_deserialize, { FUZZ_TARGET_DESERIALIZE(uint160_deserialize, {
uint160 u160; uint160 u160;
DeserializeFromFuzzingInput(buffer, u160); DeserializeFromFuzzingInput(buffer, u160);
AssertEqualAfterSerializeDeserialize(u160); AssertEqualAfterSerializeDeserialize(u160);
}) })
FUZZ_TARGET_DESERIALIZE(uint256_deserialize, { FUZZ_TARGET_DESERIALIZE(uint256_deserialize, {
uint256 u256; uint256 u256;
DeserializeFromFuzzingInput(buffer, u256); DeserializeFromFuzzingInput(buffer, u256);
AssertEqualAfterSerializeDeserialize(u256); AssertEqualAfterSerializeDeserialize(u256);
}) })
// Classes intentionally not covered in this file since their deserialization code is // Classes intentionally not covered in this file since their deserialization code is
// fuzzed elsewhere: // fuzzed elsewhere:
// * Deserialization of CTxOut is fuzzed in test/fuzz/tx_out.cpp // * Deserialization of CTxOut is fuzzed in test/fuzz/tx_out.cpp
// * Deserialization of CMutableTransaction is fuzzed in src/test/fuzz/transaction.cpp // * Deserialization of CMutableTransaction is fuzzed in src/test/fuzz/transaction.cpp