@@ -82,58 +82,6 @@ class Coin
82
82
}
83
83
};
84
84
85
- /* *
86
- * Pruned version of CTransaction: only retains metadata and unspent transaction outputs
87
- *
88
- * Serialized format:
89
- * - VARINT(nVersion)
90
- * - VARINT(nCode)
91
- * - unspentness bitvector, for vout[2] and further; least significant byte first
92
- * - the non-spent CTxOuts (via CTxOutCompressor)
93
- * - VARINT(nHeight)
94
- *
95
- * The nCode value consists of:
96
- * - bit 0: IsCoinBase()
97
- * - bit 1: vout[0] is not spent
98
- * - bit 2: vout[1] is not spent
99
- * - The higher bits encode N, the number of non-zero bytes in the following bitvector.
100
- * - In case both bit 1 and bit 2 are unset, they encode N-1, as there must be at
101
- * least one non-spent output).
102
- *
103
- * Example: 0104835800816115944e077fe7c803cfa57f29b36bf87c1d358bb85e
104
- * <><><--------------------------------------------><---->
105
- * | \ | /
106
- * version code vout[1] height
107
- *
108
- * - version = 1
109
- * - code = 4 (vout[1] is not spent, and 0 non-zero bytes of bitvector follow)
110
- * - unspentness bitvector: as 0 non-zero bytes follow, it has length 0
111
- * - vout[1]: 835800816115944e077fe7c803cfa57f29b36bf87c1d35
112
- * * 8358: compact amount representation for 60000000000 (600 BTC)
113
- * * 00: special txout type pay-to-pubkey-hash
114
- * * 816115944e077fe7c803cfa57f29b36bf87c1d35: address uint160
115
- * - height = 203998
116
- *
117
- *
118
- * Example: 0109044086ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4eebbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa486af3b
119
- * <><><--><--------------------------------------------------><----------------------------------------------><---->
120
- * / \ \ | | /
121
- * version code unspentness vout[4] vout[16] height
122
- *
123
- * - version = 1
124
- * - code = 9 (coinbase, neither vout[0] or vout[1] are unspent,
125
- * 2 (1, +1 because both bit 1 and bit 2 are unset) non-zero bitvector bytes follow)
126
- * - unspentness bitvector: bits 2 (0x04) and 14 (0x4000) are set, so vout[2+2] and vout[14+2] are unspent
127
- * - vout[4]: 86ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4ee
128
- * * 86ef97d579: compact amount representation for 234925952 (2.35 BTC)
129
- * * 00: special txout type pay-to-pubkey-hash
130
- * * 61b01caab50f1b8e9c50a5057eb43c2d9563a4ee: address uint160
131
- * - vout[16]: bbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa4
132
- * * bbd123: compact amount representation for 110397 (0.001 BTC)
133
- * * 00: special txout type pay-to-pubkey-hash
134
- * * 8c988f1a4a4de2161e0f50aac7f17e7f9555caa4: address uint160
135
- * - height = 120891
136
- */
137
85
class CCoins
138
86
{
139
87
public:
@@ -146,98 +94,9 @@ class CCoins
146
94
// ! at which height this transaction was included in the active block chain
147
95
int nHeight;
148
96
149
- void FromTx (const CTransaction &tx, int nHeightIn) {
150
- fCoinBase = tx.IsCoinBase ();
151
- vout = tx.vout ;
152
- nHeight = nHeightIn;
153
- ClearUnspendable ();
154
- }
155
-
156
- // ! construct a CCoins from a CTransaction, at a given height
157
- CCoins (const CTransaction &tx, int nHeightIn) {
158
- FromTx (tx, nHeightIn);
159
- }
160
-
161
- void Clear () {
162
- fCoinBase = false ;
163
- std::vector<CTxOut>().swap (vout);
164
- nHeight = 0 ;
165
- }
166
-
167
97
// ! empty constructor
168
98
CCoins () : fCoinBase (false ), vout(0 ), nHeight(0 ) { }
169
99
170
- // !remove spent outputs at the end of vout
171
- void Cleanup () {
172
- while (vout.size () > 0 && vout.back ().IsNull ())
173
- vout.pop_back ();
174
- if (vout.empty ())
175
- std::vector<CTxOut>().swap (vout);
176
- }
177
-
178
- void ClearUnspendable () {
179
- BOOST_FOREACH (CTxOut &txout, vout) {
180
- if (txout.scriptPubKey .IsUnspendable ())
181
- txout.SetNull ();
182
- }
183
- Cleanup ();
184
- }
185
-
186
- void swap (CCoins &to) {
187
- std::swap (to.fCoinBase , fCoinBase );
188
- to.vout .swap (vout);
189
- std::swap (to.nHeight , nHeight);
190
- }
191
-
192
- // ! equality test
193
- friend bool operator ==(const CCoins &a, const CCoins &b) {
194
- // Empty CCoins objects are always equal.
195
- if (a.IsPruned () && b.IsPruned ())
196
- return true ;
197
- return a.fCoinBase == b.fCoinBase &&
198
- a.nHeight == b.nHeight &&
199
- a.vout == b.vout ;
200
- }
201
- friend bool operator !=(const CCoins &a, const CCoins &b) {
202
- return !(a == b);
203
- }
204
-
205
- void CalcMaskSize (unsigned int &nBytes, unsigned int &nNonzeroBytes) const ;
206
-
207
- bool IsCoinBase () const {
208
- return fCoinBase ;
209
- }
210
-
211
- template <typename Stream>
212
- void Serialize (Stream &s) const {
213
- unsigned int nMaskSize = 0 , nMaskCode = 0 ;
214
- CalcMaskSize (nMaskSize, nMaskCode);
215
- bool fFirst = vout.size () > 0 && !vout[0 ].IsNull ();
216
- bool fSecond = vout.size () > 1 && !vout[1 ].IsNull ();
217
- assert (fFirst || fSecond || nMaskCode);
218
- unsigned int nCode = 8 *(nMaskCode - (fFirst || fSecond ? 0 : 1 )) + (fCoinBase ? 1 : 0 ) + (fFirst ? 2 : 0 ) + (fSecond ? 4 : 0 );
219
- // version
220
- int nVersionDummy = 0 ;
221
- ::Serialize (s, VARINT(nVersionDummy));
222
- // header code
223
- ::Serialize (s, VARINT(nCode));
224
- // spentness bitmask
225
- for (unsigned int b = 0 ; b<nMaskSize; b++) {
226
- unsigned char chAvail = 0 ;
227
- for (unsigned int i = 0 ; i < 8 && 2 +b*8 +i < vout.size (); i++)
228
- if (!vout[2 +b*8 +i].IsNull ())
229
- chAvail |= (1 << i);
230
- ::Serialize (s, chAvail);
231
- }
232
- // txouts themself
233
- for (unsigned int i = 0 ; i < vout.size (); i++) {
234
- if (!vout[i].IsNull ())
235
- ::Serialize (s, CTxOutCompressor(REF(vout[i])));
236
- }
237
- // coinbase height
238
- ::Serialize (s, VARINT(nHeight));
239
- }
240
-
241
100
template <typename Stream>
242
101
void Unserialize (Stream &s) {
243
102
unsigned int nCode = 0 ;
@@ -270,32 +129,6 @@ class CCoins
270
129
}
271
130
// coinbase height
272
131
::Unserialize (s, VARINT(nHeight));
273
- Cleanup ();
274
- }
275
-
276
- // ! mark a vout spent
277
- bool Spend (uint32_t nPos);
278
-
279
- // ! check whether a particular output is still available
280
- bool IsAvailable (unsigned int nPos) const {
281
- return (nPos < vout.size () && !vout[nPos].IsNull ());
282
- }
283
-
284
- // ! check whether the entire CCoins is spent
285
- // ! note that only !IsPruned() CCoins can be serialized
286
- bool IsPruned () const {
287
- BOOST_FOREACH (const CTxOut &out, vout)
288
- if (!out.IsNull ())
289
- return false ;
290
- return true ;
291
- }
292
-
293
- size_t DynamicMemoryUsage () const {
294
- size_t ret = memusage::DynamicUsage (vout);
295
- BOOST_FOREACH (const CTxOut &out, vout) {
296
- ret += RecursiveDynamicUsage (out.scriptPubKey );
297
- }
298
- return ret;
299
132
}
300
133
};
301
134
0 commit comments