|
1 | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto
|
2 | 2 | // Copyright (c) 2009-2015 The Bitcoin Core developers
|
| 3 | +// Copyright (c) 2016 BitPay, Inc. |
| 4 | +// Copyright (c) 2023 The Dash Core developers |
3 | 5 | // Distributed under the MIT software license, see the accompanying
|
4 | 6 | // file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
5 | 7 |
|
6 | 8 | #ifndef BITCOIN_ADDRESSINDEX_H
|
7 | 9 | #define BITCOIN_ADDRESSINDEX_H
|
8 | 10 |
|
9 |
| -#include <uint256.h> |
10 | 11 | #include <amount.h>
|
| 12 | +#include <serialize.h> |
| 13 | +#include <uint256.h> |
| 14 | +#include <util/underlying.h> |
11 | 15 |
|
12 | 16 | #include <chrono>
|
| 17 | +#include <tuple> |
| 18 | + |
| 19 | +class CScript; |
| 20 | + |
| 21 | +enum class AddressType : uint8_t { |
| 22 | + P2PK_OR_P2PKH = 1, |
| 23 | + P2SH = 2, |
| 24 | + |
| 25 | + UNKNOWN = 0 |
| 26 | +}; |
| 27 | +template<> struct is_serializable_enum<AddressType> : std::true_type {}; |
13 | 28 |
|
14 | 29 | struct CMempoolAddressDelta
|
15 | 30 | {
|
16 |
| - std::chrono::seconds time; |
17 |
| - CAmount amount; |
18 |
| - uint256 prevhash; |
19 |
| - unsigned int prevout; |
| 31 | +public: |
| 32 | + std::chrono::seconds m_time; |
| 33 | + CAmount m_amount; |
| 34 | + uint256 m_prev_hash; |
| 35 | + uint32_t m_prev_out{0}; |
20 | 36 |
|
21 |
| - CMempoolAddressDelta(std::chrono::seconds t, CAmount a, uint256 hash, unsigned int out) { |
22 |
| - time = t; |
23 |
| - amount = a; |
24 |
| - prevhash = hash; |
25 |
| - prevout = out; |
26 |
| - } |
| 37 | +public: |
| 38 | + CMempoolAddressDelta(std::chrono::seconds time, CAmount amount, uint256 prev_hash, uint32_t prev_out) : |
| 39 | + m_time{time}, m_amount{amount}, m_prev_hash{prev_hash}, m_prev_out{prev_out} {} |
27 | 40 |
|
28 |
| - CMempoolAddressDelta(std::chrono::seconds t, CAmount a) { |
29 |
| - time = t; |
30 |
| - amount = a; |
31 |
| - prevhash.SetNull(); |
32 |
| - prevout = 0; |
33 |
| - } |
| 41 | + CMempoolAddressDelta(std::chrono::seconds time, CAmount amount) : |
| 42 | + m_time{time}, m_amount{amount} {} |
34 | 43 | };
|
35 | 44 |
|
36 | 45 | struct CMempoolAddressDeltaKey
|
37 | 46 | {
|
38 |
| - int type; |
39 |
| - uint160 addressBytes; |
40 |
| - uint256 txhash; |
41 |
| - unsigned int index; |
42 |
| - int spending; |
43 |
| - |
44 |
| - CMempoolAddressDeltaKey(int addressType, uint160 addressHash, uint256 hash, unsigned int i, int s) { |
45 |
| - type = addressType; |
46 |
| - addressBytes = addressHash; |
47 |
| - txhash = hash; |
48 |
| - index = i; |
49 |
| - spending = s; |
50 |
| - } |
51 |
| - |
52 |
| - CMempoolAddressDeltaKey(int addressType, uint160 addressHash) { |
53 |
| - type = addressType; |
54 |
| - addressBytes = addressHash; |
55 |
| - txhash.SetNull(); |
56 |
| - index = 0; |
57 |
| - spending = 0; |
58 |
| - } |
| 47 | +public: |
| 48 | + AddressType m_address_type{AddressType::UNKNOWN}; |
| 49 | + uint160 m_address_bytes; |
| 50 | + uint256 m_tx_hash; |
| 51 | + uint32_t m_tx_index{0}; |
| 52 | + bool m_tx_spent{false}; |
| 53 | + |
| 54 | +public: |
| 55 | + CMempoolAddressDeltaKey(AddressType address_type, uint160 address_bytes, uint256 tx_hash, uint32_t tx_index, bool tx_spent) : |
| 56 | + m_address_type{address_type}, |
| 57 | + m_address_bytes{address_bytes}, |
| 58 | + m_tx_hash{tx_hash}, |
| 59 | + m_tx_index{tx_index}, |
| 60 | + m_tx_spent{tx_spent} {}; |
| 61 | + |
| 62 | + CMempoolAddressDeltaKey(AddressType address_type, uint160 address_bytes) : |
| 63 | + m_address_type{address_type}, |
| 64 | + m_address_bytes{address_bytes} {}; |
59 | 65 | };
|
60 | 66 |
|
61 | 67 | struct CMempoolAddressDeltaKeyCompare
|
62 | 68 | {
|
63 | 69 | bool operator()(const CMempoolAddressDeltaKey& a, const CMempoolAddressDeltaKey& b) const {
|
64 |
| - if (a.type == b.type) { |
65 |
| - if (a.addressBytes == b.addressBytes) { |
66 |
| - if (a.txhash == b.txhash) { |
67 |
| - if (a.index == b.index) { |
68 |
| - return a.spending < b.spending; |
69 |
| - } else { |
70 |
| - return a.index < b.index; |
71 |
| - } |
72 |
| - } else { |
73 |
| - return a.txhash < b.txhash; |
74 |
| - } |
75 |
| - } else { |
76 |
| - return a.addressBytes < b.addressBytes; |
77 |
| - } |
78 |
| - } else { |
79 |
| - return a.type < b.type; |
80 |
| - } |
| 70 | + auto to_tuple = [](const CMempoolAddressDeltaKey& obj) { |
| 71 | + return std::tie(obj.m_address_type, obj.m_address_bytes, obj.m_tx_hash, obj.m_tx_index, obj.m_tx_spent); |
| 72 | + }; |
| 73 | + return to_tuple(a) < to_tuple(b); |
| 74 | + } |
| 75 | +}; |
| 76 | + |
| 77 | +struct CAddressIndexKey { |
| 78 | +public: |
| 79 | + AddressType m_address_type{AddressType::UNKNOWN}; |
| 80 | + uint160 m_address_bytes; |
| 81 | + int32_t m_block_height{0}; |
| 82 | + uint32_t m_block_tx_pos{0}; |
| 83 | + uint256 m_tx_hash; |
| 84 | + uint32_t m_tx_index{0}; |
| 85 | + bool m_tx_spent{false}; |
| 86 | + |
| 87 | +public: |
| 88 | + CAddressIndexKey() { |
| 89 | + SetNull(); |
| 90 | + } |
| 91 | + |
| 92 | + CAddressIndexKey(AddressType address_type, uint160 address_bytes, int32_t block_height, uint32_t block_tx_pos, uint256 tx_hash, |
| 93 | + uint32_t tx_index, bool tx_spent) : |
| 94 | + m_address_type{address_type}, |
| 95 | + m_address_bytes{address_bytes}, |
| 96 | + m_block_height{block_height}, |
| 97 | + m_block_tx_pos{block_tx_pos}, |
| 98 | + m_tx_hash{tx_hash}, |
| 99 | + m_tx_index{tx_index}, |
| 100 | + m_tx_spent{tx_spent} {}; |
| 101 | + |
| 102 | + void SetNull() { |
| 103 | + m_address_type = AddressType::UNKNOWN; |
| 104 | + m_address_bytes.SetNull(); |
| 105 | + m_block_height = 0; |
| 106 | + m_block_tx_pos = 0; |
| 107 | + m_tx_hash.SetNull(); |
| 108 | + m_tx_index = 0; |
| 109 | + m_tx_spent = false; |
| 110 | + } |
| 111 | + |
| 112 | +public: |
| 113 | + size_t GetSerializeSize(int nType, int nVersion) const { |
| 114 | + return 66; |
| 115 | + } |
| 116 | + |
| 117 | + template<typename Stream> |
| 118 | + void Serialize(Stream& s) const { |
| 119 | + ser_writedata8(s, ToUnderlying(m_address_type)); |
| 120 | + m_address_bytes.Serialize(s); |
| 121 | + // Heights are stored big-endian for key sorting in LevelDB |
| 122 | + ser_writedata32be(s, m_block_height); |
| 123 | + ser_writedata32be(s, m_block_tx_pos); |
| 124 | + m_tx_hash.Serialize(s); |
| 125 | + ser_writedata32(s, m_tx_index); |
| 126 | + ser_writedata8(s, static_cast<uint8_t>(m_tx_spent)); |
| 127 | + } |
| 128 | + |
| 129 | + template<typename Stream> |
| 130 | + void Unserialize(Stream& s) { |
| 131 | + m_address_type = static_cast<AddressType>(ser_readdata8(s)); |
| 132 | + m_address_bytes.Unserialize(s); |
| 133 | + m_block_height = ser_readdata32be(s); |
| 134 | + m_block_tx_pos = ser_readdata32be(s); |
| 135 | + m_tx_hash.Unserialize(s); |
| 136 | + m_tx_index = ser_readdata32(s); |
| 137 | + m_tx_spent = static_cast<bool>(ser_readdata8(s)); |
81 | 138 | }
|
82 | 139 | };
|
83 | 140 |
|
| 141 | +struct CAddressIndexIteratorKey { |
| 142 | +public: |
| 143 | + AddressType m_address_type{AddressType::UNKNOWN}; |
| 144 | + uint160 m_address_bytes; |
| 145 | + |
| 146 | +public: |
| 147 | + CAddressIndexIteratorKey() { |
| 148 | + SetNull(); |
| 149 | + } |
| 150 | + |
| 151 | + CAddressIndexIteratorKey(AddressType address_type, uint160 address_bytes) : |
| 152 | + m_address_type{address_type}, m_address_bytes{address_bytes} {}; |
| 153 | + |
| 154 | + void SetNull() { |
| 155 | + m_address_type = AddressType::UNKNOWN; |
| 156 | + m_address_bytes.SetNull(); |
| 157 | + } |
| 158 | + |
| 159 | +public: |
| 160 | + size_t GetSerializeSize(int nType, int nVersion) const { |
| 161 | + return 21; |
| 162 | + } |
| 163 | + |
| 164 | + template<typename Stream> |
| 165 | + void Serialize(Stream& s) const { |
| 166 | + ser_writedata8(s, ToUnderlying(m_address_type)); |
| 167 | + m_address_bytes.Serialize(s); |
| 168 | + } |
| 169 | + |
| 170 | + template<typename Stream> |
| 171 | + void Unserialize(Stream& s) { |
| 172 | + m_address_type = static_cast<AddressType>(ser_readdata8(s)); |
| 173 | + m_address_bytes.Unserialize(s); |
| 174 | + } |
| 175 | +}; |
| 176 | + |
| 177 | +struct CAddressIndexIteratorHeightKey { |
| 178 | +public: |
| 179 | + AddressType m_address_type{AddressType::UNKNOWN}; |
| 180 | + uint160 m_address_bytes; |
| 181 | + int32_t m_block_height{0}; |
| 182 | + |
| 183 | +public: |
| 184 | + CAddressIndexIteratorHeightKey() { |
| 185 | + SetNull(); |
| 186 | + } |
| 187 | + |
| 188 | + CAddressIndexIteratorHeightKey(AddressType address_type, uint160 address_bytes, int32_t block_height) : |
| 189 | + m_address_type{address_type}, m_address_bytes{address_bytes}, m_block_height{block_height} {}; |
| 190 | + |
| 191 | + void SetNull() { |
| 192 | + m_address_type = AddressType::UNKNOWN; |
| 193 | + m_address_bytes.SetNull(); |
| 194 | + m_block_height = 0; |
| 195 | + } |
| 196 | + |
| 197 | +public: |
| 198 | + size_t GetSerializeSize(int nType, int nVersion) const { |
| 199 | + return 25; |
| 200 | + } |
| 201 | + |
| 202 | + template<typename Stream> |
| 203 | + void Serialize(Stream& s) const { |
| 204 | + ser_writedata8(s, ToUnderlying(m_address_type)); |
| 205 | + m_address_bytes.Serialize(s); |
| 206 | + ser_writedata32be(s, m_block_height); |
| 207 | + } |
| 208 | + |
| 209 | + template<typename Stream> |
| 210 | + void Unserialize(Stream& s) { |
| 211 | + m_address_type = static_cast<AddressType>(ser_readdata8(s)); |
| 212 | + m_address_bytes.Unserialize(s); |
| 213 | + m_block_height = ser_readdata32be(s); |
| 214 | + } |
| 215 | +}; |
| 216 | + |
| 217 | +bool AddressBytesFromScript(const CScript& script, AddressType& address_type, uint160& address_bytes); |
| 218 | + |
84 | 219 | #endif // BITCOIN_ADDRESSINDEX_H
|
0 commit comments