Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2015 The Bitcoin Core developers
3 : // Copyright (c) 2016 BitPay Inc.
4 : // Copyright (c) 2023-2026 The Dash Core developers
5 : // Distributed under the MIT software license, see the accompanying
6 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
7 :
8 : #ifndef BITCOIN_INDEX_ADDRESSINDEX_TYPES_H
9 : #define BITCOIN_INDEX_ADDRESSINDEX_TYPES_H
10 :
11 : #include <consensus/amount.h>
12 : #include <script/script.h>
13 : #include <serialize.h>
14 : #include <uint256.h>
15 : #include <util/std23.h>
16 :
17 : #include <chrono>
18 : #include <tuple>
19 : #include <vector>
20 :
21 : struct CAddressIndexKey;
22 : struct CMempoolAddressDelta;
23 : struct CMempoolAddressDeltaKey;
24 :
25 : enum class AddressType : uint8_t {
26 : P2PK_OR_P2PKH = 1,
27 : P2SH = 2,
28 :
29 : UNKNOWN = 0
30 : };
31 : template<> struct is_serializable_enum<AddressType> : std::true_type {};
32 :
33 : using CAddressIndexEntry = std::pair<CAddressIndexKey, CAmount>;
34 : using CMempoolAddressDeltaEntry = std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta>;
35 :
36 : struct CAddressUnspentKey;
37 : struct CAddressUnspentValue;
38 : using CAddressUnspentIndexEntry = std::pair<CAddressUnspentKey, CAddressUnspentValue>;
39 :
40 : struct CMempoolAddressDelta {
41 : public:
42 : std::chrono::seconds m_time;
43 : CAmount m_amount;
44 : uint256 m_prev_hash;
45 0 : uint32_t m_prev_out{0};
46 :
47 : public:
48 0 : CMempoolAddressDelta(std::chrono::seconds time, CAmount amount, uint256 prev_hash, uint32_t prev_out) :
49 0 : m_time{time},
50 0 : m_amount{amount},
51 0 : m_prev_hash{prev_hash},
52 0 : m_prev_out{prev_out}
53 0 : {
54 0 : }
55 :
56 0 : CMempoolAddressDelta(std::chrono::seconds time, CAmount amount) :
57 0 : m_time{time},
58 0 : m_amount{amount}
59 0 : {
60 0 : }
61 : };
62 :
63 : struct CMempoolAddressDeltaKey {
64 : public:
65 : AddressType m_address_type{AddressType::UNKNOWN};
66 : uint160 m_address_bytes;
67 : uint256 m_tx_hash;
68 0 : uint32_t m_tx_index{0};
69 0 : bool m_tx_spent{false};
70 :
71 : public:
72 0 : CMempoolAddressDeltaKey(AddressType address_type, uint160 address_bytes, uint256 tx_hash, uint32_t tx_index,
73 : bool tx_spent) :
74 0 : m_address_type{address_type},
75 0 : m_address_bytes{address_bytes},
76 0 : m_tx_hash{tx_hash},
77 0 : m_tx_index{tx_index},
78 0 : m_tx_spent{tx_spent} {};
79 :
80 0 : CMempoolAddressDeltaKey(AddressType address_type, uint160 address_bytes) :
81 0 : m_address_type{address_type},
82 0 : m_address_bytes{address_bytes} {};
83 : };
84 :
85 : struct CMempoolAddressDeltaKeyCompare {
86 0 : bool operator()(const CMempoolAddressDeltaKey& a, const CMempoolAddressDeltaKey& b) const
87 : {
88 0 : auto to_tuple = [](const CMempoolAddressDeltaKey& obj) {
89 0 : return std::tie(obj.m_address_type, obj.m_address_bytes, obj.m_tx_hash, obj.m_tx_index, obj.m_tx_spent);
90 : };
91 0 : return to_tuple(a) < to_tuple(b);
92 : }
93 : };
94 :
95 : struct CAddressIndexKey {
96 : public:
97 0 : AddressType m_address_type{AddressType::UNKNOWN};
98 : uint160 m_address_bytes;
99 0 : int32_t m_block_height{0};
100 0 : uint32_t m_block_tx_pos{0};
101 : uint256 m_tx_hash;
102 0 : uint32_t m_tx_index{0};
103 0 : bool m_tx_spent{false};
104 :
105 : public:
106 0 : CAddressIndexKey() { SetNull(); }
107 :
108 0 : CAddressIndexKey(AddressType address_type, uint160 address_bytes, int32_t block_height, uint32_t block_tx_pos,
109 : uint256 tx_hash, uint32_t tx_index, bool tx_spent) :
110 0 : m_address_type{address_type},
111 0 : m_address_bytes{address_bytes},
112 0 : m_block_height{block_height},
113 0 : m_block_tx_pos{block_tx_pos},
114 0 : m_tx_hash{tx_hash},
115 0 : m_tx_index{tx_index},
116 0 : m_tx_spent{tx_spent} {};
117 :
118 0 : void SetNull()
119 : {
120 0 : m_address_type = AddressType::UNKNOWN;
121 0 : m_address_bytes.SetNull();
122 0 : m_block_height = 0;
123 0 : m_block_tx_pos = 0;
124 0 : m_tx_hash.SetNull();
125 0 : m_tx_index = 0;
126 0 : m_tx_spent = false;
127 0 : }
128 :
129 : public:
130 : size_t GetSerializeSize(int nType, int nVersion) const { return 66; }
131 :
132 : template <typename Stream>
133 0 : void Serialize(Stream& s) const
134 : {
135 0 : ser_writedata8(s, std23::to_underlying(m_address_type));
136 0 : m_address_bytes.Serialize(s);
137 : // Heights are stored big-endian for key sorting in LevelDB
138 0 : ser_writedata32be(s, m_block_height);
139 0 : ser_writedata32be(s, m_block_tx_pos);
140 0 : m_tx_hash.Serialize(s);
141 0 : ser_writedata32(s, m_tx_index);
142 0 : ser_writedata8(s, static_cast<uint8_t>(m_tx_spent));
143 0 : }
144 :
145 : template <typename Stream>
146 0 : void Unserialize(Stream& s)
147 : {
148 0 : m_address_type = static_cast<AddressType>(ser_readdata8(s));
149 0 : m_address_bytes.Unserialize(s);
150 0 : m_block_height = ser_readdata32be(s);
151 0 : m_block_tx_pos = ser_readdata32be(s);
152 0 : m_tx_hash.Unserialize(s);
153 0 : m_tx_index = ser_readdata32(s);
154 0 : m_tx_spent = static_cast<bool>(ser_readdata8(s));
155 0 : }
156 : };
157 :
158 : struct CAddressIndexIteratorKey {
159 : public:
160 : AddressType m_address_type{AddressType::UNKNOWN};
161 : uint160 m_address_bytes;
162 :
163 : public:
164 : CAddressIndexIteratorKey() { SetNull(); }
165 :
166 0 : CAddressIndexIteratorKey(AddressType address_type, uint160 address_bytes) :
167 0 : m_address_type{address_type},
168 0 : m_address_bytes{address_bytes} {};
169 :
170 : void SetNull()
171 : {
172 : m_address_type = AddressType::UNKNOWN;
173 : m_address_bytes.SetNull();
174 : }
175 :
176 : public:
177 : size_t GetSerializeSize(int nType, int nVersion) const { return 21; }
178 :
179 : template <typename Stream>
180 0 : void Serialize(Stream& s) const
181 : {
182 0 : ser_writedata8(s, std23::to_underlying(m_address_type));
183 0 : m_address_bytes.Serialize(s);
184 0 : }
185 :
186 : template <typename Stream>
187 : void Unserialize(Stream& s)
188 : {
189 : m_address_type = static_cast<AddressType>(ser_readdata8(s));
190 : m_address_bytes.Unserialize(s);
191 : }
192 : };
193 :
194 : struct CAddressIndexIteratorHeightKey {
195 : public:
196 : AddressType m_address_type{AddressType::UNKNOWN};
197 : uint160 m_address_bytes;
198 : int32_t m_block_height{0};
199 :
200 : public:
201 : CAddressIndexIteratorHeightKey() { SetNull(); }
202 :
203 0 : CAddressIndexIteratorHeightKey(AddressType address_type, uint160 address_bytes, int32_t block_height) :
204 0 : m_address_type{address_type},
205 0 : m_address_bytes{address_bytes},
206 0 : m_block_height{block_height} {};
207 :
208 : void SetNull()
209 : {
210 : m_address_type = AddressType::UNKNOWN;
211 : m_address_bytes.SetNull();
212 : m_block_height = 0;
213 : }
214 :
215 : public:
216 : size_t GetSerializeSize(int nType, int nVersion) const { return 25; }
217 :
218 : template <typename Stream>
219 0 : void Serialize(Stream& s) const
220 : {
221 0 : ser_writedata8(s, std23::to_underlying(m_address_type));
222 0 : m_address_bytes.Serialize(s);
223 0 : ser_writedata32be(s, m_block_height);
224 0 : }
225 :
226 : template <typename Stream>
227 : void Unserialize(Stream& s)
228 : {
229 : m_address_type = static_cast<AddressType>(ser_readdata8(s));
230 : m_address_bytes.Unserialize(s);
231 : m_block_height = ser_readdata32be(s);
232 : }
233 : };
234 :
235 : struct CAddressUnspentKey {
236 : public:
237 0 : AddressType m_address_type{AddressType::UNKNOWN};
238 : uint160 m_address_bytes;
239 : uint256 m_tx_hash;
240 0 : uint32_t m_tx_index{0};
241 :
242 : public:
243 0 : CAddressUnspentKey() { SetNull(); }
244 :
245 0 : CAddressUnspentKey(AddressType address_type, uint160 address_bytes, uint256 tx_hash, uint32_t tx_index) :
246 0 : m_address_type{address_type},
247 0 : m_address_bytes{address_bytes},
248 0 : m_tx_hash{tx_hash},
249 0 : m_tx_index{tx_index} {};
250 :
251 0 : void SetNull()
252 : {
253 0 : m_address_type = AddressType::UNKNOWN;
254 0 : m_address_bytes.SetNull();
255 0 : m_tx_hash.SetNull();
256 0 : m_tx_index = 0;
257 0 : }
258 :
259 : public:
260 : size_t GetSerializeSize(int nType, int nVersion) const { return 57; }
261 :
262 : template <typename Stream>
263 0 : void Serialize(Stream& s) const
264 : {
265 0 : ser_writedata8(s, std23::to_underlying(m_address_type));
266 0 : m_address_bytes.Serialize(s);
267 0 : m_tx_hash.Serialize(s);
268 0 : ser_writedata32(s, m_tx_index);
269 0 : }
270 :
271 : template <typename Stream>
272 0 : void Unserialize(Stream& s)
273 : {
274 0 : m_address_type = static_cast<AddressType>(ser_readdata8(s));
275 0 : m_address_bytes.Unserialize(s);
276 0 : m_tx_hash.Unserialize(s);
277 0 : m_tx_index = ser_readdata32(s);
278 0 : }
279 : };
280 :
281 : struct CAddressUnspentValue {
282 : public:
283 0 : CAmount m_amount{-1};
284 : CScript m_tx_script;
285 0 : int32_t m_block_height{0};
286 :
287 : public:
288 0 : CAddressUnspentValue() { SetNull(); }
289 :
290 0 : CAddressUnspentValue(CAmount amount, CScript tx_script, int32_t block_height) :
291 0 : m_amount{amount},
292 0 : m_tx_script{tx_script},
293 0 : m_block_height{block_height} {};
294 :
295 0 : void SetNull()
296 : {
297 0 : m_amount = -1;
298 0 : m_tx_script.clear();
299 0 : m_block_height = 0;
300 0 : }
301 :
302 0 : bool IsNull() const { return (m_amount == -1); }
303 :
304 : public:
305 0 : SERIALIZE_METHODS(CAddressUnspentValue, obj) { READWRITE(obj.m_amount, obj.m_tx_script, obj.m_block_height); }
306 : };
307 :
308 : #endif // BITCOIN_INDEX_ADDRESSINDEX_TYPES_H
|