]> Git Repo - VerusCoin.git/blame - src/main.h
Remove headers.h
[VerusCoin.git] / src / main.h
CommitLineData
0a61b0df 1// Copyright (c) 2009-2010 Satoshi Nakamoto
88216419 2// Copyright (c) 2009-2012 The Bitcoin developers
0a61b0df 3// Distributed under the MIT/X11 software license, see the accompanying
4// file license.txt or http://www.opensource.org/licenses/mit-license.php.
223b6f1b
WL
5#ifndef BITCOIN_MAIN_H
6#define BITCOIN_MAIN_H
7
8#include "bignum.h"
9#include "net.h"
10#include "key.h"
223b6f1b 11#include "script.h"
a20c0d0f 12#include "version.h"
223b6f1b 13
52d3a481
WL
14#ifdef WIN32
15#include <io.h> /* for _commit */
16#endif
17
223b6f1b 18#include <list>
0a61b0df 19
0a61b0df 20class CBlock;
21class CBlockIndex;
22class CWalletTx;
e89b9f6a 23class CWallet;
0a61b0df 24class CKeyItem;
64c7ee7e
PW
25class CReserveKey;
26class CWalletDB;
0a61b0df 27
40c2614e
JL
28class CAddress;
29class CInv;
30class CRequestTracker;
31class CNode;
40c2614e 32
0a61b0df 33static const unsigned int MAX_BLOCK_SIZE = 1000000;
3df62878 34static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
f1e1fb4b 35static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
142e6041 36static const int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100;
bde280b9
WL
37static const int64 MIN_TX_FEE = 50000;
38static const int64 MIN_RELAY_TX_FEE = 10000;
39static const int64 MAX_MONEY = 21000000 * COIN;
40inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
0a61b0df 41static const int COINBASE_MATURITY = 100;
aa496b75
WL
42// Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp.
43static const int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
8bb5edc1
MC
44#ifdef USE_UPNP
45static const int fHaveUPnP = true;
46#else
47static const int fHaveUPnP = false;
48#endif
0a61b0df 49
50
7bf8b7c2 51extern CScript COINBASE_FLAGS;
52a3d263
FV
52
53
0a61b0df 54
55
56
57
58extern CCriticalSection cs_main;
223b6f1b 59extern std::map<uint256, CBlockIndex*> mapBlockIndex;
5cbf7532 60extern uint256 hashGenesisBlock;
0a61b0df 61extern CBlockIndex* pindexGenesisBlock;
62extern int nBestHeight;
63extern CBigNum bnBestChainWork;
64extern CBigNum bnBestInvalidWork;
65extern uint256 hashBestChain;
66extern CBlockIndex* pindexBest;
340f0876 67extern uint64 nPooledTx;
0a61b0df 68extern unsigned int nTransactionsUpdated;
340f0876
LD
69extern uint64 nLastBlockTx;
70extern uint64 nLastBlockSize;
2bc4fd60 71extern const std::string strMessageMagic;
0a61b0df 72extern double dHashesPerSec;
bde280b9
WL
73extern int64 nHPSTimerStart;
74extern int64 nTimeBestReceived;
64c7ee7e
PW
75extern CCriticalSection cs_setpwalletRegistered;
76extern std::set<CWallet*> setpwalletRegistered;
0a61b0df 77
78// Settings
bde280b9 79extern int64 nTransactionFee;
0a61b0df 80
81
82
83
84
1512d5ce
JL
85class CReserveKey;
86class CTxDB;
87class CTxIndex;
0a61b0df 88
64c7ee7e
PW
89void RegisterWallet(CWallet* pwalletIn);
90void UnregisterWallet(CWallet* pwalletIn);
074d584a 91bool ProcessBlock(CNode* pfrom, CBlock* pblock);
bde280b9 92bool CheckDiskSpace(uint64 nAdditionalBytes=0);
0a61b0df 93FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
94FILE* AppendBlockFile(unsigned int& nFileRet);
0a61b0df 95bool LoadBlockIndex(bool fAllowNew=true);
96void PrintBlockTree();
97bool ProcessMessages(CNode* pfrom);
0a61b0df 98bool SendMessages(CNode* pto, bool fSendTrickle);
64c7ee7e 99void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
776d0f34 100CBlock* CreateNewBlock(CReserveKey& reservekey);
83f4cd15 101void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
776d0f34 102void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
64c7ee7e 103bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
0a61b0df 104bool CheckProofOfWork(uint256 hash, unsigned int nBits);
bde280b9 105unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
d33cc2b5 106int GetNumBlocksOfPeers();
0a61b0df 107bool IsInitialBlockDownload();
223b6f1b 108std::string GetWarnings(std::string strFor);
0a61b0df 109
110
111
112
113
114
115
116
117
118
119
120
64c7ee7e
PW
121bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
122
6b8de05d 123/** Position on disk for a particular transaction. */
0a61b0df 124class CDiskTxPos
125{
126public:
127 unsigned int nFile;
128 unsigned int nBlockPos;
129 unsigned int nTxPos;
130
131 CDiskTxPos()
132 {
133 SetNull();
134 }
135
136 CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn)
137 {
138 nFile = nFileIn;
139 nBlockPos = nBlockPosIn;
140 nTxPos = nTxPosIn;
141 }
142
143 IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
144 void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; }
145 bool IsNull() const { return (nFile == -1); }
146
147 friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
148 {
149 return (a.nFile == b.nFile &&
150 a.nBlockPos == b.nBlockPos &&
151 a.nTxPos == b.nTxPos);
152 }
153
154 friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b)
155 {
156 return !(a == b);
157 }
158
223b6f1b 159 std::string ToString() const
0a61b0df 160 {
161 if (IsNull())
52d3a481 162 return "null";
0a61b0df 163 else
164 return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos);
165 }
166
167 void print() const
168 {
169 printf("%s", ToString().c_str());
170 }
171};
172
173
174
6b8de05d 175/** An inpoint - a combination of a transaction and an index n into its vin */
0a61b0df 176class CInPoint
177{
178public:
179 CTransaction* ptx;
180 unsigned int n;
181
182 CInPoint() { SetNull(); }
183 CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
184 void SetNull() { ptx = NULL; n = -1; }
185 bool IsNull() const { return (ptx == NULL && n == -1); }
186};
187
188
189
6b8de05d 190/** An outpoint - a combination of a transaction hash and an index n into its vout */
0a61b0df 191class COutPoint
192{
193public:
194 uint256 hash;
195 unsigned int n;
196
197 COutPoint() { SetNull(); }
198 COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
199 IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
200 void SetNull() { hash = 0; n = -1; }
201 bool IsNull() const { return (hash == 0 && n == -1); }
202
203 friend bool operator<(const COutPoint& a, const COutPoint& b)
204 {
205 return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
206 }
207
208 friend bool operator==(const COutPoint& a, const COutPoint& b)
209 {
210 return (a.hash == b.hash && a.n == b.n);
211 }
212
213 friend bool operator!=(const COutPoint& a, const COutPoint& b)
214 {
215 return !(a == b);
216 }
217
223b6f1b 218 std::string ToString() const
0a61b0df 219 {
b22c8842 220 return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,10).c_str(), n);
0a61b0df 221 }
222
223 void print() const
224 {
225 printf("%s\n", ToString().c_str());
226 }
227};
228
229
230
231
6b8de05d
PW
232/** An input of a transaction. It contains the location of the previous
233 * transaction's output that it claims and a signature that matches the
234 * output's public key.
235 */
0a61b0df 236class CTxIn
237{
238public:
239 COutPoint prevout;
240 CScript scriptSig;
241 unsigned int nSequence;
242
243 CTxIn()
244 {
26ce92b3 245 nSequence = std::numeric_limits<unsigned int>::max();
0a61b0df 246 }
247
26ce92b3 248 explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max())
0a61b0df 249 {
250 prevout = prevoutIn;
251 scriptSig = scriptSigIn;
252 nSequence = nSequenceIn;
253 }
254
26ce92b3 255 CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max())
0a61b0df 256 {
257 prevout = COutPoint(hashPrevTx, nOut);
258 scriptSig = scriptSigIn;
259 nSequence = nSequenceIn;
260 }
261
262 IMPLEMENT_SERIALIZE
263 (
264 READWRITE(prevout);
265 READWRITE(scriptSig);
266 READWRITE(nSequence);
267 )
268
269 bool IsFinal() const
270 {
26ce92b3 271 return (nSequence == std::numeric_limits<unsigned int>::max());
0a61b0df 272 }
273
274 friend bool operator==(const CTxIn& a, const CTxIn& b)
275 {
276 return (a.prevout == b.prevout &&
277 a.scriptSig == b.scriptSig &&
278 a.nSequence == b.nSequence);
279 }
280
281 friend bool operator!=(const CTxIn& a, const CTxIn& b)
282 {
283 return !(a == b);
284 }
285
223b6f1b 286 std::string ToString() const
0a61b0df 287 {
223b6f1b 288 std::string str;
52d3a481 289 str += "CTxIn(";
0a61b0df 290 str += prevout.ToString();
291 if (prevout.IsNull())
f1e1fb4b 292 str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
0a61b0df 293 else
294 str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
26ce92b3 295 if (nSequence != std::numeric_limits<unsigned int>::max())
0a61b0df 296 str += strprintf(", nSequence=%u", nSequence);
297 str += ")";
298 return str;
299 }
300
301 void print() const
302 {
303 printf("%s\n", ToString().c_str());
304 }
0a61b0df 305};
306
307
308
309
6b8de05d
PW
310/** An output of a transaction. It contains the public key that the next input
311 * must be able to sign with to claim it.
312 */
0a61b0df 313class CTxOut
314{
315public:
bde280b9 316 int64 nValue;
0a61b0df 317 CScript scriptPubKey;
318
319 CTxOut()
320 {
321 SetNull();
322 }
323
bde280b9 324 CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
0a61b0df 325 {
326 nValue = nValueIn;
327 scriptPubKey = scriptPubKeyIn;
328 }
329
330 IMPLEMENT_SERIALIZE
331 (
332 READWRITE(nValue);
333 READWRITE(scriptPubKey);
334 )
335
336 void SetNull()
337 {
338 nValue = -1;
339 scriptPubKey.clear();
340 }
341
342 bool IsNull()
343 {
344 return (nValue == -1);
345 }
346
347 uint256 GetHash() const
348 {
349 return SerializeHash(*this);
350 }
351
0a61b0df 352 friend bool operator==(const CTxOut& a, const CTxOut& b)
353 {
354 return (a.nValue == b.nValue &&
355 a.scriptPubKey == b.scriptPubKey);
356 }
357
358 friend bool operator!=(const CTxOut& a, const CTxOut& b)
359 {
360 return !(a == b);
361 }
362
223b6f1b 363 std::string ToString() const
0a61b0df 364 {
365 if (scriptPubKey.size() < 6)
366 return "CTxOut(error)";
10384941 367 return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30).c_str());
0a61b0df 368 }
369
370 void print() const
371 {
372 printf("%s\n", ToString().c_str());
373 }
374};
375
376
377
378
dbbf1d4a
LD
379enum GetMinFee_mode
380{
381 GMF_BLOCK,
382 GMF_RELAY,
383 GMF_SEND,
384};
385
8d7849b6
GA
386typedef std::map<uint256, std::pair<CTxIndex, CTransaction> > MapPrevTx;
387
6b8de05d
PW
388/** The basic transaction that is broadcasted on the network and contained in
389 * blocks. A transaction can contain multiple inputs and outputs.
390 */
0a61b0df 391class CTransaction
392{
393public:
394 int nVersion;
223b6f1b
WL
395 std::vector<CTxIn> vin;
396 std::vector<CTxOut> vout;
0a61b0df 397 unsigned int nLockTime;
398
3e52aaf2
GA
399 // Denial-of-service detection:
400 mutable int nDoS;
401 bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
0a61b0df 402
403 CTransaction()
404 {
405 SetNull();
406 }
407
408 IMPLEMENT_SERIALIZE
409 (
410 READWRITE(this->nVersion);
411 nVersion = this->nVersion;
412 READWRITE(vin);
413 READWRITE(vout);
414 READWRITE(nLockTime);
415 )
416
417 void SetNull()
418 {
419 nVersion = 1;
420 vin.clear();
421 vout.clear();
422 nLockTime = 0;
3e52aaf2 423 nDoS = 0; // Denial-of-service prevention
0a61b0df 424 }
425
426 bool IsNull() const
427 {
428 return (vin.empty() && vout.empty());
429 }
430
431 uint256 GetHash() const
432 {
433 return SerializeHash(*this);
434 }
435
bde280b9 436 bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
0a61b0df 437 {
438 // Time based nLockTime implemented in 0.1.6
439 if (nLockTime == 0)
440 return true;
441 if (nBlockHeight == 0)
442 nBlockHeight = nBestHeight;
443 if (nBlockTime == 0)
444 nBlockTime = GetAdjustedTime();
bde280b9 445 if ((int64)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
0a61b0df 446 return true;
223b6f1b 447 BOOST_FOREACH(const CTxIn& txin, vin)
0a61b0df 448 if (!txin.IsFinal())
449 return false;
450 return true;
451 }
452
453 bool IsNewerThan(const CTransaction& old) const
454 {
455 if (vin.size() != old.vin.size())
456 return false;
c376ac35 457 for (unsigned int i = 0; i < vin.size(); i++)
0a61b0df 458 if (vin[i].prevout != old.vin[i].prevout)
459 return false;
460
461 bool fNewer = false;
26ce92b3 462 unsigned int nLowest = std::numeric_limits<unsigned int>::max();
c376ac35 463 for (unsigned int i = 0; i < vin.size(); i++)
0a61b0df 464 {
465 if (vin[i].nSequence != old.vin[i].nSequence)
466 {
467 if (vin[i].nSequence <= nLowest)
468 {
469 fNewer = false;
470 nLowest = vin[i].nSequence;
471 }
472 if (old.vin[i].nSequence < nLowest)
473 {
474 fNewer = true;
475 nLowest = old.vin[i].nSequence;
476 }
477 }
478 }
479 return fNewer;
480 }
481
482 bool IsCoinBase() const
483 {
484 return (vin.size() == 1 && vin[0].prevout.IsNull());
485 }
486
8d7849b6
GA
487 /** Check for standard transaction types
488 @return True if all outputs (scriptPubKeys) use only standard transaction forms
489 */
e679ec96 490 bool IsStandard() const;
922e8e29 491
8d7849b6
GA
492 /** Check for standard transaction types
493 @param[in] mapInputs Map of previous transactions that have outputs we're spending
494 @return True if all inputs (scriptSigs) use only standard transaction forms
495 @see CTransaction::FetchInputs
496 */
497 bool AreInputsStandard(const MapPrevTx& mapInputs) const;
498
499 /** Count ECDSA signature operations the old-fashioned (pre-0.6) way
500 @return number of sigops this transaction's outputs will produce when spent
501 @see CTransaction::FetchInputs
502 */
922e8e29 503 int GetLegacySigOpCount() const;
a206a239 504
137d0685 505 /** Count ECDSA signature operations in pay-to-script-hash inputs.
8d7849b6
GA
506
507 @param[in] mapInputs Map of previous transactions that have outputs we're spending
508 @return maximum number of sigops required to validate this transaction's inputs
509 @see CTransaction::FetchInputs
510 */
137d0685 511 int GetP2SHSigOpCount(const MapPrevTx& mapInputs) const;
8d7849b6
GA
512
513 /** Amount of bitcoins spent by this transaction.
514 @return sum of all outputs (note: does not include fees)
515 */
bde280b9 516 int64 GetValueOut() const
0a61b0df 517 {
bde280b9 518 int64 nValueOut = 0;
223b6f1b 519 BOOST_FOREACH(const CTxOut& txout, vout)
0a61b0df 520 {
521 nValueOut += txout.nValue;
522 if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
223b6f1b 523 throw std::runtime_error("CTransaction::GetValueOut() : value out of range");
0a61b0df 524 }
525 return nValueOut;
526 }
527
8d7849b6
GA
528 /** Amount of bitcoins coming in to this transaction
529 Note that lightweight clients may not know anything besides the hash of previous transactions,
530 so may not be able to calculate this.
531
532 @param[in] mapInputs Map of previous transactions that have outputs we're spending
533 @return Sum of value of all inputs (scriptSigs)
534 @see CTransaction::FetchInputs
535 */
536 int64 GetValueIn(const MapPrevTx& mapInputs) const;
537
395c1f44
GA
538 static bool AllowFree(double dPriority)
539 {
540 // Large (in bytes) low-priority (new, small-coin) transactions
541 // need a fee.
542 return dPriority > COIN * 144 / 250;
543 }
544
bde280b9 545 int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, enum GetMinFee_mode mode=GMF_BLOCK) const
0a61b0df 546 {
2bfda1be 547 // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE
bde280b9 548 int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
2bfda1be 549
0a61b0df 550 unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
9b8eb4d6 551 unsigned int nNewBlockSize = nBlockSize + nBytes;
bde280b9 552 int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
0a61b0df 553
f35e21e2 554 if (fAllowFree)
555 {
298a7714 556 if (nBlockSize == 1)
557 {
558 // Transactions under 10K are free
559 // (about 4500bc if made of 50bc inputs)
560 if (nBytes < 10000)
561 nMinFee = 0;
562 }
563 else
564 {
565 // Free transaction area
566 if (nNewBlockSize < 27000)
567 nMinFee = 0;
568 }
f35e21e2 569 }
0a61b0df 570
2bfda1be
PW
571 // To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01
572 if (nMinFee < nBaseFee)
da7bbd9d 573 {
223b6f1b 574 BOOST_FOREACH(const CTxOut& txout, vout)
0a61b0df 575 if (txout.nValue < CENT)
2bfda1be 576 nMinFee = nBaseFee;
da7bbd9d 577 }
0a61b0df 578
f1e1fb4b 579 // Raise the price as the block approaches full
9b8eb4d6 580 if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
581 {
582 if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN)
583 return MAX_MONEY;
584 nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize);
585 }
586
f1e1fb4b 587 if (!MoneyRange(nMinFee))
588 nMinFee = MAX_MONEY;
0a61b0df 589 return nMinFee;
590 }
591
592
0a61b0df 593 bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
594 {
595 CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
596 if (!filein)
597 return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
598
599 // Read transaction
600 if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
601 return error("CTransaction::ReadFromDisk() : fseek failed");
602 filein >> *this;
603
604 // Return file pointer
605 if (pfileRet)
606 {
607 if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
608 return error("CTransaction::ReadFromDisk() : second fseek failed");
609 *pfileRet = filein.release();
610 }
611 return true;
612 }
613
0a61b0df 614 friend bool operator==(const CTransaction& a, const CTransaction& b)
615 {
616 return (a.nVersion == b.nVersion &&
617 a.vin == b.vin &&
618 a.vout == b.vout &&
619 a.nLockTime == b.nLockTime);
620 }
621
622 friend bool operator!=(const CTransaction& a, const CTransaction& b)
623 {
624 return !(a == b);
625 }
626
627
223b6f1b 628 std::string ToString() const
0a61b0df 629 {
223b6f1b 630 std::string str;
0a61b0df 631 str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
b22c8842 632 GetHash().ToString().substr(0,10).c_str(),
0a61b0df 633 nVersion,
634 vin.size(),
635 vout.size(),
636 nLockTime);
c376ac35 637 for (unsigned int i = 0; i < vin.size(); i++)
0a61b0df 638 str += " " + vin[i].ToString() + "\n";
c376ac35 639 for (unsigned int i = 0; i < vout.size(); i++)
0a61b0df 640 str += " " + vout[i].ToString() + "\n";
641 return str;
642 }
643
644 void print() const
645 {
646 printf("%s", ToString().c_str());
647 }
648
649
461764cb 650 bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet);
651 bool ReadFromDisk(CTxDB& txdb, COutPoint prevout);
652 bool ReadFromDisk(COutPoint prevout);
0a61b0df 653 bool DisconnectInputs(CTxDB& txdb);
2a45a494 654
8d7849b6
GA
655 /** Fetch from memory and/or disk. inputsRet keys are transaction hashes.
656
657 @param[in] txdb Transaction database
658 @param[in] mapTestPool List of pending changes to the transaction index database
659 @param[in] fBlock True if being called to add a new best-block to the chain
660 @param[in] fMiner True if being called by CreateNewBlock
661 @param[out] inputsRet Pointers to this transaction's inputs
149f580c 662 @param[out] fInvalid returns true if transaction is invalid
8d7849b6
GA
663 @return Returns true if all inputs are in txdb or mapTestPool
664 */
e679ec96 665 bool FetchInputs(CTxDB& txdb, const std::map<uint256, CTxIndex>& mapTestPool,
149f580c 666 bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid);
8d7849b6
GA
667
668 /** Sanity check previous transactions, then, if all checks succeed,
669 mark them as spent by this transaction.
670
671 @param[in] inputs Previous transactions (from FetchInputs)
672 @param[out] mapTestPool Keeps track of inputs that need to be updated on disk
673 @param[in] posThisTx Position of this transaction on disk
674 @param[in] pindexBlock
675 @param[in] fBlock true if called from ConnectBlock
676 @param[in] fMiner true if called from CreateNewBlock
137d0685 677 @param[in] fStrictPayToScriptHash true if fully validating p2sh transactions
8d7849b6
GA
678 @return Returns true if all checks succeed
679 */
680 bool ConnectInputs(MapPrevTx inputs,
922e8e29 681 std::map<uint256, CTxIndex>& mapTestPool, const CDiskTxPos& posThisTx,
137d0685 682 const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash=true);
0a61b0df 683 bool ClientConnectInputs();
a790fa46 684 bool CheckTransaction() const;
f1e1fb4b 685 bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
8d7849b6 686
0a61b0df 687protected:
8d7849b6 688 const CTxOut& GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const;
f1e1fb4b 689 bool AddToMemoryPoolUnchecked();
0a61b0df 690public:
691 bool RemoveFromMemoryPool();
692};
693
694
695
696
697
6b8de05d 698/** A transaction with a merkle branch linking it to the block chain. */
0a61b0df 699class CMerkleTx : public CTransaction
700{
701public:
702 uint256 hashBlock;
223b6f1b 703 std::vector<uint256> vMerkleBranch;
0a61b0df 704 int nIndex;
705
706 // memory only
a790fa46 707 mutable char fMerkleVerified;
0a61b0df 708
709
710 CMerkleTx()
711 {
712 Init();
713 }
714
715 CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
716 {
717 Init();
718 }
719
720 void Init()
721 {
722 hashBlock = 0;
723 nIndex = -1;
724 fMerkleVerified = false;
0a61b0df 725 }
726
335e878b 727
0a61b0df 728 IMPLEMENT_SERIALIZE
729 (
730 nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
731 nVersion = this->nVersion;
732 READWRITE(hashBlock);
733 READWRITE(vMerkleBranch);
734 READWRITE(nIndex);
735 )
736
0a61b0df 737
738 int SetMerkleBranch(const CBlock* pblock=NULL);
30ab2c9c
PW
739 int GetDepthInMainChain(CBlockIndex* &pindexRet) const;
740 int GetDepthInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
0a61b0df 741 bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
742 int GetBlocksToMaturity() const;
f1e1fb4b 743 bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
e89b9f6a 744 bool AcceptToMemoryPool();
0a61b0df 745};
746
747
748
749
6b8de05d
PW
750/** A txdb record that contains the disk location of a transaction and the
751 * locations of transactions that spend its outputs. vSpent is really only
752 * used as a flag, but having the location is very helpful for debugging.
753 */
0a61b0df 754class CTxIndex
755{
756public:
757 CDiskTxPos pos;
223b6f1b 758 std::vector<CDiskTxPos> vSpent;
0a61b0df 759
760 CTxIndex()
761 {
762 SetNull();
763 }
764
765 CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
766 {
767 pos = posIn;
768 vSpent.resize(nOutputs);
769 }
770
771 IMPLEMENT_SERIALIZE
772 (
773 if (!(nType & SER_GETHASH))
774 READWRITE(nVersion);
775 READWRITE(pos);
776 READWRITE(vSpent);
777 )
778
779 void SetNull()
780 {
781 pos.SetNull();
782 vSpent.clear();
783 }
784
785 bool IsNull()
786 {
787 return pos.IsNull();
788 }
789
790 friend bool operator==(const CTxIndex& a, const CTxIndex& b)
791 {
f1e1fb4b 792 return (a.pos == b.pos &&
793 a.vSpent == b.vSpent);
0a61b0df 794 }
795
796 friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
797 {
798 return !(a == b);
799 }
395c1f44 800 int GetDepthInMainChain() const;
30ab2c9c 801
0a61b0df 802};
803
804
805
806
807
6b8de05d
PW
808/** Nodes collect new transactions into a block, hash them into a hash tree,
809 * and scan through nonce values to make the block's hash satisfy proof-of-work
810 * requirements. When they solve the proof-of-work, they broadcast the block
811 * to everyone and the block is added to the block chain. The first transaction
812 * in the block is a special one that creates a new coin owned by the creator
813 * of the block.
814 *
815 * Blocks are appended to blk0001.dat files on disk. Their location on disk
816 * is indexed by CBlockIndex objects in memory.
817 */
0a61b0df 818class CBlock
819{
820public:
821 // header
822 int nVersion;
823 uint256 hashPrevBlock;
824 uint256 hashMerkleRoot;
825 unsigned int nTime;
826 unsigned int nBits;
827 unsigned int nNonce;
828
829 // network and disk
223b6f1b 830 std::vector<CTransaction> vtx;
0a61b0df 831
832 // memory only
223b6f1b 833 mutable std::vector<uint256> vMerkleTree;
0a61b0df 834
3e52aaf2
GA
835 // Denial-of-service detection:
836 mutable int nDoS;
837 bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
0a61b0df 838
839 CBlock()
840 {
841 SetNull();
842 }
843
844 IMPLEMENT_SERIALIZE
845 (
846 READWRITE(this->nVersion);
847 nVersion = this->nVersion;
848 READWRITE(hashPrevBlock);
849 READWRITE(hashMerkleRoot);
850 READWRITE(nTime);
851 READWRITE(nBits);
852 READWRITE(nNonce);
853
854 // ConnectBlock depends on vtx being last so it can calculate offset
855 if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
856 READWRITE(vtx);
857 else if (fRead)
858 const_cast<CBlock*>(this)->vtx.clear();
859 )
860
861 void SetNull()
862 {
863 nVersion = 1;
864 hashPrevBlock = 0;
865 hashMerkleRoot = 0;
866 nTime = 0;
867 nBits = 0;
868 nNonce = 0;
869 vtx.clear();
870 vMerkleTree.clear();
3e52aaf2 871 nDoS = 0;
0a61b0df 872 }
873
874 bool IsNull() const
875 {
876 return (nBits == 0);
877 }
878
879 uint256 GetHash() const
880 {
881 return Hash(BEGIN(nVersion), END(nNonce));
882 }
883
bde280b9 884 int64 GetBlockTime() const
0a61b0df 885 {
bde280b9 886 return (int64)nTime;
0a61b0df 887 }
888
0f8cb5db 889 void UpdateTime(const CBlockIndex* pindexPrev);
f1e1fb4b 890
0a61b0df 891
892 uint256 BuildMerkleTree() const
893 {
894 vMerkleTree.clear();
223b6f1b 895 BOOST_FOREACH(const CTransaction& tx, vtx)
0a61b0df 896 vMerkleTree.push_back(tx.GetHash());
897 int j = 0;
898 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
899 {
900 for (int i = 0; i < nSize; i += 2)
901 {
223b6f1b 902 int i2 = std::min(i+1, nSize-1);
0a61b0df 903 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]),
904 BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
905 }
906 j += nSize;
907 }
908 return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
909 }
910
223b6f1b 911 std::vector<uint256> GetMerkleBranch(int nIndex) const
0a61b0df 912 {
913 if (vMerkleTree.empty())
914 BuildMerkleTree();
223b6f1b 915 std::vector<uint256> vMerkleBranch;
0a61b0df 916 int j = 0;
917 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
918 {
223b6f1b 919 int i = std::min(nIndex^1, nSize-1);
0a61b0df 920 vMerkleBranch.push_back(vMerkleTree[j+i]);
921 nIndex >>= 1;
922 j += nSize;
923 }
924 return vMerkleBranch;
925 }
926
223b6f1b 927 static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
0a61b0df 928 {
929 if (nIndex == -1)
930 return 0;
223b6f1b 931 BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
0a61b0df 932 {
933 if (nIndex & 1)
934 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
935 else
936 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
937 nIndex >>= 1;
938 }
939 return hash;
940 }
941
942
f03304a9 943 bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
0a61b0df 944 {
945 // Open history file to append
946 CAutoFile fileout = AppendBlockFile(nFileRet);
947 if (!fileout)
948 return error("CBlock::WriteToDisk() : AppendBlockFile failed");
0a61b0df 949
950 // Write index header
951 unsigned int nSize = fileout.GetSerializeSize(*this);
952 fileout << FLATDATA(pchMessageStart) << nSize;
953
954 // Write block
955 nBlockPosRet = ftell(fileout);
956 if (nBlockPosRet == -1)
957 return error("CBlock::WriteToDisk() : ftell failed");
958 fileout << *this;
959
960 // Flush stdio buffers and commit to disk before returning
961 fflush(fileout);
962 if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
963 {
6853e627 964#ifdef WIN32
0a61b0df 965 _commit(_fileno(fileout));
966#else
967 fsync(fileno(fileout));
968#endif
969 }
970
971 return true;
972 }
973
974 bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
975 {
976 SetNull();
977
978 // Open history file to read
979 CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
980 if (!filein)
981 return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
982 if (!fReadTransactions)
983 filein.nType |= SER_BLOCKHEADERONLY;
984
985 // Read block
986 filein >> *this;
987
988 // Check the header
989 if (!CheckProofOfWork(GetHash(), nBits))
990 return error("CBlock::ReadFromDisk() : errors in block header");
991
992 return true;
993 }
994
995
996
997 void print() const
998 {
999 printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
1000 GetHash().ToString().substr(0,20).c_str(),
1001 nVersion,
1002 hashPrevBlock.ToString().substr(0,20).c_str(),
b22c8842 1003 hashMerkleRoot.ToString().substr(0,10).c_str(),
0a61b0df 1004 nTime, nBits, nNonce,
1005 vtx.size());
c376ac35 1006 for (unsigned int i = 0; i < vtx.size(); i++)
0a61b0df 1007 {
1008 printf(" ");
1009 vtx[i].print();
1010 }
1011 printf(" vMerkleTree: ");
c376ac35 1012 for (unsigned int i = 0; i < vMerkleTree.size(); i++)
b22c8842 1013 printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
0a61b0df 1014 printf("\n");
1015 }
1016
1017
0a61b0df 1018 bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1019 bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1020 bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
1021 bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
1022 bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
1023 bool CheckBlock() const;
1024 bool AcceptBlock();
d68dcf74
PW
1025
1026private:
1027 bool SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew);
0a61b0df 1028};
1029
1030
1031
1032
1033
1034
6b8de05d
PW
1035/** The block chain is a tree shaped structure starting with the
1036 * genesis block at the root, with each block potentially having multiple
1037 * candidates to be the next block. pprev and pnext link a path through the
1038 * main/longest chain. A blockindex may have multiple pprev pointing back
1039 * to it, but pnext will only point forward to the longest branch, or will
1040 * be null if the block is not part of the longest chain.
1041 */
0a61b0df 1042class CBlockIndex
1043{
1044public:
1045 const uint256* phashBlock;
1046 CBlockIndex* pprev;
1047 CBlockIndex* pnext;
1048 unsigned int nFile;
1049 unsigned int nBlockPos;
1050 int nHeight;
1051 CBigNum bnChainWork;
1052
1053 // block header
1054 int nVersion;
1055 uint256 hashMerkleRoot;
1056 unsigned int nTime;
1057 unsigned int nBits;
1058 unsigned int nNonce;
1059
1060
1061 CBlockIndex()
1062 {
1063 phashBlock = NULL;
1064 pprev = NULL;
1065 pnext = NULL;
1066 nFile = 0;
1067 nBlockPos = 0;
1068 nHeight = 0;
1069 bnChainWork = 0;
1070
1071 nVersion = 0;
1072 hashMerkleRoot = 0;
1073 nTime = 0;
1074 nBits = 0;
1075 nNonce = 0;
1076 }
1077
1078 CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
1079 {
1080 phashBlock = NULL;
1081 pprev = NULL;
1082 pnext = NULL;
1083 nFile = nFileIn;
1084 nBlockPos = nBlockPosIn;
1085 nHeight = 0;
1086 bnChainWork = 0;
1087
1088 nVersion = block.nVersion;
1089 hashMerkleRoot = block.hashMerkleRoot;
1090 nTime = block.nTime;
1091 nBits = block.nBits;
1092 nNonce = block.nNonce;
1093 }
1094
f03304a9 1095 CBlock GetBlockHeader() const
1096 {
1097 CBlock block;
1098 block.nVersion = nVersion;
1099 if (pprev)
1100 block.hashPrevBlock = pprev->GetBlockHash();
1101 block.hashMerkleRoot = hashMerkleRoot;
1102 block.nTime = nTime;
1103 block.nBits = nBits;
1104 block.nNonce = nNonce;
1105 return block;
1106 }
1107
0a61b0df 1108 uint256 GetBlockHash() const
1109 {
1110 return *phashBlock;
1111 }
1112
bde280b9 1113 int64 GetBlockTime() const
0a61b0df 1114 {
bde280b9 1115 return (int64)nTime;
0a61b0df 1116 }
1117
1118 CBigNum GetBlockWork() const
1119 {
9b8eb4d6 1120 CBigNum bnTarget;
1121 bnTarget.SetCompact(nBits);
1122 if (bnTarget <= 0)
0a61b0df 1123 return 0;
9b8eb4d6 1124 return (CBigNum(1)<<256) / (bnTarget+1);
0a61b0df 1125 }
1126
1127 bool IsInMainChain() const
1128 {
1129 return (pnext || this == pindexBest);
1130 }
1131
1132 bool CheckIndex() const
1133 {
1134 return CheckProofOfWork(GetBlockHash(), nBits);
1135 }
1136
1137 bool EraseBlockFromDisk()
1138 {
1139 // Open history file
1140 CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
1141 if (!fileout)
1142 return false;
1143
1144 // Overwrite with empty null block
1145 CBlock block;
1146 block.SetNull();
1147 fileout << block;
1148
1149 return true;
1150 }
1151
1152 enum { nMedianTimeSpan=11 };
1153
bde280b9 1154 int64 GetMedianTimePast() const
0a61b0df 1155 {
bde280b9
WL
1156 int64 pmedian[nMedianTimeSpan];
1157 int64* pbegin = &pmedian[nMedianTimeSpan];
1158 int64* pend = &pmedian[nMedianTimeSpan];
0a61b0df 1159
1160 const CBlockIndex* pindex = this;
1161 for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
1162 *(--pbegin) = pindex->GetBlockTime();
1163
223b6f1b 1164 std::sort(pbegin, pend);
0a61b0df 1165 return pbegin[(pend - pbegin)/2];
1166 }
1167
bde280b9 1168 int64 GetMedianTime() const
0a61b0df 1169 {
1170 const CBlockIndex* pindex = this;
1171 for (int i = 0; i < nMedianTimeSpan/2; i++)
1172 {
1173 if (!pindex->pnext)
1174 return GetBlockTime();
1175 pindex = pindex->pnext;
1176 }
1177 return pindex->GetMedianTimePast();
1178 }
1179
1180
1181
223b6f1b 1182 std::string ToString() const
0a61b0df 1183 {
1184 return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
1185 pprev, pnext, nFile, nBlockPos, nHeight,
b22c8842 1186 hashMerkleRoot.ToString().substr(0,10).c_str(),
0a61b0df 1187 GetBlockHash().ToString().substr(0,20).c_str());
1188 }
1189
1190 void print() const
1191 {
1192 printf("%s\n", ToString().c_str());
1193 }
1194};
1195
1196
1197
6b8de05d 1198/** Used to marshal pointers into hashes for db storage. */
0a61b0df 1199class CDiskBlockIndex : public CBlockIndex
1200{
1201public:
1202 uint256 hashPrev;
1203 uint256 hashNext;
1204
1205 CDiskBlockIndex()
1206 {
1207 hashPrev = 0;
1208 hashNext = 0;
1209 }
1210
1211 explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
1212 {
1213 hashPrev = (pprev ? pprev->GetBlockHash() : 0);
1214 hashNext = (pnext ? pnext->GetBlockHash() : 0);
1215 }
1216
1217 IMPLEMENT_SERIALIZE
1218 (
1219 if (!(nType & SER_GETHASH))
1220 READWRITE(nVersion);
1221
1222 READWRITE(hashNext);
1223 READWRITE(nFile);
1224 READWRITE(nBlockPos);
1225 READWRITE(nHeight);
1226
1227 // block header
1228 READWRITE(this->nVersion);
1229 READWRITE(hashPrev);
1230 READWRITE(hashMerkleRoot);
1231 READWRITE(nTime);
1232 READWRITE(nBits);
1233 READWRITE(nNonce);
1234 )
1235
1236 uint256 GetBlockHash() const
1237 {
1238 CBlock block;
1239 block.nVersion = nVersion;
1240 block.hashPrevBlock = hashPrev;
1241 block.hashMerkleRoot = hashMerkleRoot;
1242 block.nTime = nTime;
1243 block.nBits = nBits;
1244 block.nNonce = nNonce;
1245 return block.GetHash();
1246 }
1247
1248
223b6f1b 1249 std::string ToString() const
0a61b0df 1250 {
223b6f1b 1251 std::string str = "CDiskBlockIndex(";
0a61b0df 1252 str += CBlockIndex::ToString();
1253 str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)",
1254 GetBlockHash().ToString().c_str(),
1255 hashPrev.ToString().substr(0,20).c_str(),
1256 hashNext.ToString().substr(0,20).c_str());
1257 return str;
1258 }
1259
1260 void print() const
1261 {
1262 printf("%s\n", ToString().c_str());
1263 }
1264};
1265
1266
1267
1268
1269
1270
1271
1272
6b8de05d
PW
1273/** Describes a place in the block chain to another node such that if the
1274 * other node doesn't have the same branch, it can find a recent common trunk.
1275 * The further back it is, the further before the fork it may be.
1276 */
0a61b0df 1277class CBlockLocator
1278{
1279protected:
223b6f1b 1280 std::vector<uint256> vHave;
0a61b0df 1281public:
1282
1283 CBlockLocator()
1284 {
1285 }
1286
1287 explicit CBlockLocator(const CBlockIndex* pindex)
1288 {
1289 Set(pindex);
1290 }
1291
1292 explicit CBlockLocator(uint256 hashBlock)
1293 {
223b6f1b 1294 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
0a61b0df 1295 if (mi != mapBlockIndex.end())
1296 Set((*mi).second);
1297 }
1298
30ab2c9c
PW
1299 CBlockLocator(const std::vector<uint256>& vHaveIn)
1300 {
1301 vHave = vHaveIn;
1302 }
1303
0a61b0df 1304 IMPLEMENT_SERIALIZE
1305 (
1306 if (!(nType & SER_GETHASH))
1307 READWRITE(nVersion);
1308 READWRITE(vHave);
1309 )
1310
f03304a9 1311 void SetNull()
1312 {
1313 vHave.clear();
1314 }
1315
1316 bool IsNull()
1317 {
1318 return vHave.empty();
1319 }
1320
0a61b0df 1321 void Set(const CBlockIndex* pindex)
1322 {
1323 vHave.clear();
1324 int nStep = 1;
1325 while (pindex)
1326 {
1327 vHave.push_back(pindex->GetBlockHash());
1328
1329 // Exponentially larger steps back
1330 for (int i = 0; pindex && i < nStep; i++)
1331 pindex = pindex->pprev;
1332 if (vHave.size() > 10)
1333 nStep *= 2;
1334 }
1335 vHave.push_back(hashGenesisBlock);
1336 }
1337
1338 int GetDistanceBack()
1339 {
1340 // Retrace how far back it was in the sender's branch
1341 int nDistance = 0;
1342 int nStep = 1;
223b6f1b 1343 BOOST_FOREACH(const uint256& hash, vHave)
0a61b0df 1344 {
223b6f1b 1345 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
0a61b0df 1346 if (mi != mapBlockIndex.end())
1347 {
1348 CBlockIndex* pindex = (*mi).second;
1349 if (pindex->IsInMainChain())
1350 return nDistance;
1351 }
1352 nDistance += nStep;
1353 if (nDistance > 10)
1354 nStep *= 2;
1355 }
1356 return nDistance;
1357 }
1358
1359 CBlockIndex* GetBlockIndex()
1360 {
1361 // Find the first block the caller has in the main chain
223b6f1b 1362 BOOST_FOREACH(const uint256& hash, vHave)
0a61b0df 1363 {
223b6f1b 1364 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
0a61b0df 1365 if (mi != mapBlockIndex.end())
1366 {
1367 CBlockIndex* pindex = (*mi).second;
1368 if (pindex->IsInMainChain())
1369 return pindex;
1370 }
1371 }
1372 return pindexGenesisBlock;
1373 }
1374
1375 uint256 GetBlockHash()
1376 {
1377 // Find the first block the caller has in the main chain
223b6f1b 1378 BOOST_FOREACH(const uint256& hash, vHave)
0a61b0df 1379 {
223b6f1b 1380 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
0a61b0df 1381 if (mi != mapBlockIndex.end())
1382 {
1383 CBlockIndex* pindex = (*mi).second;
1384 if (pindex->IsInMainChain())
1385 return hash;
1386 }
1387 }
1388 return hashGenesisBlock;
1389 }
1390
1391 int GetHeight()
1392 {
1393 CBlockIndex* pindex = GetBlockIndex();
1394 if (!pindex)
1395 return 0;
1396 return pindex->nHeight;
1397 }
1398};
1399
1400
1401
1402
1403
1404
e4ff4e68 1405
1406
1407
6b8de05d
PW
1408/** Alerts are for notifying old versions if they become too obsolete and
1409 * need to upgrade. The message is displayed in the status bar.
1410 * Alert messages are broadcast as a vector of signed data. Unserializing may
1411 * not read the entire buffer if the alert is for a newer version, but older
1412 * versions can still relay the original data.
1413 */
0a61b0df 1414class CUnsignedAlert
1415{
1416public:
1417 int nVersion;
bde280b9
WL
1418 int64 nRelayUntil; // when newer nodes stop relaying to newer nodes
1419 int64 nExpiration;
0a61b0df 1420 int nID;
1421 int nCancel;
223b6f1b 1422 std::set<int> setCancel;
0a61b0df 1423 int nMinVer; // lowest version inclusive
1424 int nMaxVer; // highest version inclusive
223b6f1b 1425 std::set<std::string> setSubVer; // empty matches all
0a61b0df 1426 int nPriority;
1427
1428 // Actions
223b6f1b
WL
1429 std::string strComment;
1430 std::string strStatusBar;
1431 std::string strReserved;
0a61b0df 1432
1433 IMPLEMENT_SERIALIZE
1434 (
1435 READWRITE(this->nVersion);
1436 nVersion = this->nVersion;
1437 READWRITE(nRelayUntil);
1438 READWRITE(nExpiration);
1439 READWRITE(nID);
1440 READWRITE(nCancel);
1441 READWRITE(setCancel);
1442 READWRITE(nMinVer);
1443 READWRITE(nMaxVer);
1444 READWRITE(setSubVer);
1445 READWRITE(nPriority);
1446
1447 READWRITE(strComment);
1448 READWRITE(strStatusBar);
986b5e25 1449 READWRITE(strReserved);
0a61b0df 1450 )
1451
1452 void SetNull()
1453 {
1454 nVersion = 1;
1455 nRelayUntil = 0;
1456 nExpiration = 0;
1457 nID = 0;
1458 nCancel = 0;
1459 setCancel.clear();
1460 nMinVer = 0;
1461 nMaxVer = 0;
1462 setSubVer.clear();
1463 nPriority = 0;
1464
1465 strComment.clear();
1466 strStatusBar.clear();
986b5e25 1467 strReserved.clear();
0a61b0df 1468 }
1469
223b6f1b 1470 std::string ToString() const
0a61b0df 1471 {
223b6f1b
WL
1472 std::string strSetCancel;
1473 BOOST_FOREACH(int n, setCancel)
0a61b0df 1474 strSetCancel += strprintf("%d ", n);
223b6f1b
WL
1475 std::string strSetSubVer;
1476 BOOST_FOREACH(std::string str, setSubVer)
0a61b0df 1477 strSetSubVer += "\"" + str + "\" ";
1478 return strprintf(
1479 "CAlert(\n"
1480 " nVersion = %d\n"
1481 " nRelayUntil = %"PRI64d"\n"
1482 " nExpiration = %"PRI64d"\n"
1483 " nID = %d\n"
1484 " nCancel = %d\n"
1485 " setCancel = %s\n"
1486 " nMinVer = %d\n"
1487 " nMaxVer = %d\n"
1488 " setSubVer = %s\n"
1489 " nPriority = %d\n"
1490 " strComment = \"%s\"\n"
1491 " strStatusBar = \"%s\"\n"
0a61b0df 1492 ")\n",
1493 nVersion,
1494 nRelayUntil,
1495 nExpiration,
1496 nID,
1497 nCancel,
1498 strSetCancel.c_str(),
1499 nMinVer,
1500 nMaxVer,
1501 strSetSubVer.c_str(),
1502 nPriority,
1503 strComment.c_str(),
986b5e25 1504 strStatusBar.c_str());
0a61b0df 1505 }
1506
1507 void print() const
1508 {
1509 printf("%s", ToString().c_str());
1510 }
1511};
1512
6b8de05d 1513/** An alert is a combination of a serialized CUnsignedAlert and a signature. */
0a61b0df 1514class CAlert : public CUnsignedAlert
1515{
1516public:
223b6f1b
WL
1517 std::vector<unsigned char> vchMsg;
1518 std::vector<unsigned char> vchSig;
0a61b0df 1519
1520 CAlert()
1521 {
1522 SetNull();
1523 }
1524
1525 IMPLEMENT_SERIALIZE
1526 (
1527 READWRITE(vchMsg);
1528 READWRITE(vchSig);
1529 )
1530
1531 void SetNull()
1532 {
1533 CUnsignedAlert::SetNull();
1534 vchMsg.clear();
1535 vchSig.clear();
1536 }
1537
1538 bool IsNull() const
1539 {
1540 return (nExpiration == 0);
1541 }
1542
1543 uint256 GetHash() const
1544 {
1545 return SerializeHash(*this);
1546 }
1547
1548 bool IsInEffect() const
1549 {
1550 return (GetAdjustedTime() < nExpiration);
1551 }
1552
1553 bool Cancels(const CAlert& alert) const
1554 {
1555 if (!IsInEffect())
461764cb 1556 return false; // this was a no-op before 31403
0a61b0df 1557 return (alert.nID <= nCancel || setCancel.count(alert.nID));
1558 }
1559
223b6f1b 1560 bool AppliesTo(int nVersion, std::string strSubVerIn) const
0a61b0df 1561 {
f8ded588 1562 // TODO: rework for client-version-embedded-in-strSubVer ?
0a61b0df 1563 return (IsInEffect() &&
1564 nMinVer <= nVersion && nVersion <= nMaxVer &&
1565 (setSubVer.empty() || setSubVer.count(strSubVerIn)));
1566 }
1567
1568 bool AppliesToMe() const
1569 {
f8ded588 1570 return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<std::string>()));
0a61b0df 1571 }
1572
1573 bool RelayTo(CNode* pnode) const
1574 {
1575 if (!IsInEffect())
1576 return false;
1577 // returns true if wasn't already contained in the set
1578 if (pnode->setKnown.insert(GetHash()).second)
1579 {
1580 if (AppliesTo(pnode->nVersion, pnode->strSubVer) ||
1581 AppliesToMe() ||
1582 GetAdjustedTime() < nRelayUntil)
1583 {
1584 pnode->PushMessage("alert", *this);
1585 return true;
1586 }
1587 }
1588 return false;
1589 }
1590
1591 bool CheckSignature()
1592 {
1593 CKey key;
1594 if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284")))
1595 return error("CAlert::CheckSignature() : SetPubKey failed");
1596 if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
1597 return error("CAlert::CheckSignature() : verify signature failed");
1598
1599 // Now unserialize the data
1600 CDataStream sMsg(vchMsg);
1601 sMsg >> *(CUnsignedAlert*)this;
1602 return true;
1603 }
1604
1605 bool ProcessAlert();
1606};
1607
223b6f1b 1608#endif
This page took 0.293296 seconds and 4 git commands to generate.