10
10
11
11
class CTxMemPool ;
12
12
13
- // Dumb helper to handle CTransaction compression at serialize-time
14
- struct TransactionCompressor {
15
- private:
16
- CTransactionRef& tx;
17
- public:
18
- explicit TransactionCompressor (CTransactionRef& txIn) : tx(txIn) {}
13
+ // Transaction compression schemes for compact block relay can be introduced by writing
14
+ // an actual formatter here.
15
+ using TransactionCompression = DefaultFormatter;
19
16
20
- ADD_SERIALIZE_METHODS;
17
+ class DifferenceFormatter
18
+ {
19
+ uint64_t m_shift = 0 ;
21
20
22
- template <typename Stream, typename Operation>
23
- inline void SerializationOp (Stream& s, Operation ser_action) {
24
- READWRITE (tx); // TODO: Compress tx encoding
21
+ public:
22
+ template <typename Stream, typename I>
23
+ void Ser (Stream& s, I v)
24
+ {
25
+ if (v < m_shift || v >= std::numeric_limits<uint64_t >::max ()) throw std::ios_base::failure (" differential value overflow" );
26
+ WriteCompactSize (s, v - m_shift);
27
+ m_shift = uint64_t (v) + 1 ;
28
+ }
29
+ template <typename Stream, typename I>
30
+ void Unser (Stream& s, I& v)
31
+ {
32
+ uint64_t n = ReadCompactSize (s);
33
+ m_shift += n;
34
+ if (m_shift < n || m_shift >= std::numeric_limits<uint64_t >::max () || m_shift < std::numeric_limits<I>::min () || m_shift > std::numeric_limits<I>::max ()) throw std::ios_base::failure (" differential value overflow" );
35
+ v = I (m_shift++);
25
36
}
26
37
};
27
38
@@ -31,39 +42,9 @@ class BlockTransactionsRequest {
31
42
uint256 blockhash;
32
43
std::vector<uint16_t > indexes;
33
44
34
- ADD_SERIALIZE_METHODS;
35
-
36
- template <typename Stream, typename Operation>
37
- inline void SerializationOp (Stream& s, Operation ser_action) {
38
- READWRITE (blockhash);
39
- uint64_t indexes_size = (uint64_t )indexes.size ();
40
- READWRITE (COMPACTSIZE (indexes_size));
41
- if (ser_action.ForRead ()) {
42
- size_t i = 0 ;
43
- while (indexes.size () < indexes_size) {
44
- indexes.resize (std::min ((uint64_t )(1000 + indexes.size ()), indexes_size));
45
- for (; i < indexes.size (); i++) {
46
- uint64_t index = 0 ;
47
- READWRITE (COMPACTSIZE (index));
48
- if (index > std::numeric_limits<uint16_t >::max ())
49
- throw std::ios_base::failure (" index overflowed 16 bits" );
50
- indexes[i] = index;
51
- }
52
- }
53
-
54
- int32_t offset = 0 ;
55
- for (size_t j = 0 ; j < indexes.size (); j++) {
56
- if (int32_t (indexes[j]) + offset > std::numeric_limits<uint16_t >::max ())
57
- throw std::ios_base::failure (" indexes overflowed 16 bits" );
58
- indexes[j] = indexes[j] + offset;
59
- offset = int32_t (indexes[j]) + 1 ;
60
- }
61
- } else {
62
- for (size_t i = 0 ; i < indexes.size (); i++) {
63
- uint64_t index = indexes[i] - (i == 0 ? 0 : (indexes[i - 1 ] + 1 ));
64
- READWRITE (COMPACTSIZE (index));
65
- }
66
- }
45
+ SERIALIZE_METHODS (BlockTransactionsRequest, obj)
46
+ {
47
+ READWRITE (obj.blockhash , Using<VectorFormatter<DifferenceFormatter>>(obj.indexes ));
67
48
}
68
49
};
69
50
@@ -77,24 +58,9 @@ class BlockTransactions {
77
58
explicit BlockTransactions (const BlockTransactionsRequest& req) :
78
59
blockhash(req.blockhash), txn(req.indexes.size()) {}
79
60
80
- ADD_SERIALIZE_METHODS;
81
-
82
- template <typename Stream, typename Operation>
83
- inline void SerializationOp (Stream& s, Operation ser_action) {
84
- READWRITE (blockhash);
85
- uint64_t txn_size = (uint64_t )txn.size ();
86
- READWRITE (COMPACTSIZE (txn_size));
87
- if (ser_action.ForRead ()) {
88
- size_t i = 0 ;
89
- while (txn.size () < txn_size) {
90
- txn.resize (std::min ((uint64_t )(1000 + txn.size ()), txn_size));
91
- for (; i < txn.size (); i++)
92
- READWRITE (TransactionCompressor (txn[i]));
93
- }
94
- } else {
95
- for (size_t i = 0 ; i < txn.size (); i++)
96
- READWRITE (TransactionCompressor (txn[i]));
97
- }
61
+ SERIALIZE_METHODS (BlockTransactions, obj)
62
+ {
63
+ READWRITE (obj.blockhash , Using<VectorFormatter<TransactionCompression>>(obj.txn ));
98
64
}
99
65
};
100
66
@@ -105,17 +71,7 @@ struct PrefilledTransaction {
105
71
uint16_t index;
106
72
CTransactionRef tx;
107
73
108
- ADD_SERIALIZE_METHODS;
109
-
110
- template <typename Stream, typename Operation>
111
- inline void SerializationOp (Stream& s, Operation ser_action) {
112
- uint64_t idx = index;
113
- READWRITE (COMPACTSIZE (idx));
114
- if (idx > std::numeric_limits<uint16_t >::max ())
115
- throw std::ios_base::failure (" index overflowed 16-bits" );
116
- index = idx;
117
- READWRITE (TransactionCompressor (tx));
118
- }
74
+ SERIALIZE_METHODS (PrefilledTransaction, obj) { READWRITE (COMPACTSIZE (obj.index ), Using<TransactionCompression>(obj.tx )); }
119
75
};
120
76
121
77
typedef enum ReadStatus_t
@@ -153,43 +109,15 @@ class CBlockHeaderAndShortTxIDs {
153
109
154
110
size_t BlockTxCount () const { return shorttxids.size () + prefilledtxn.size (); }
155
111
156
- ADD_SERIALIZE_METHODS;
157
-
158
- template <typename Stream, typename Operation>
159
- inline void SerializationOp (Stream& s, Operation ser_action) {
160
- READWRITE (header);
161
- READWRITE (nonce);
162
-
163
- uint64_t shorttxids_size = (uint64_t )shorttxids.size ();
164
- READWRITE (COMPACTSIZE (shorttxids_size));
112
+ SERIALIZE_METHODS (CBlockHeaderAndShortTxIDs, obj)
113
+ {
114
+ READWRITE (obj.header , obj.nonce , Using<VectorFormatter<CustomUintFormatter<SHORTTXIDS_LENGTH>>>(obj.shorttxids ), obj.prefilledtxn );
165
115
if (ser_action.ForRead ()) {
166
- size_t i = 0 ;
167
- while (shorttxids.size () < shorttxids_size) {
168
- shorttxids.resize (std::min ((uint64_t )(1000 + shorttxids.size ()), shorttxids_size));
169
- for (; i < shorttxids.size (); i++) {
170
- uint32_t lsb = 0 ; uint16_t msb = 0 ;
171
- READWRITE (lsb);
172
- READWRITE (msb);
173
- shorttxids[i] = (uint64_t (msb) << 32 ) | uint64_t (lsb);
174
- static_assert (SHORTTXIDS_LENGTH == 6 , " shorttxids serialization assumes 6-byte shorttxids" );
175
- }
176
- }
177
- } else {
178
- for (size_t i = 0 ; i < shorttxids.size (); i++) {
179
- uint32_t lsb = shorttxids[i] & 0xffffffff ;
180
- uint16_t msb = (shorttxids[i] >> 32 ) & 0xffff ;
181
- READWRITE (lsb);
182
- READWRITE (msb);
116
+ if (obj.BlockTxCount () > std::numeric_limits<uint16_t >::max ()) {
117
+ throw std::ios_base::failure (" indexes overflowed 16 bits" );
183
118
}
119
+ obj.FillShortTxIDSelector ();
184
120
}
185
-
186
- READWRITE (prefilledtxn);
187
-
188
- if (BlockTxCount () > std::numeric_limits<uint16_t >::max ())
189
- throw std::ios_base::failure (" indexes overflowed 16 bits" );
190
-
191
- if (ser_action.ForRead ())
192
- FillShortTxIDSelector ();
193
121
}
194
122
};
195
123
0 commit comments