23 #include <boost/algorithm/string/replace.hpp>
24 #include <boost/filesystem.hpp>
25 #include <boost/filesystem/fstream.hpp>
28 using namespace boost;
31 # error "Anoncoin cannot be compiled without assertions."
81 struct CBlockIndexWorkComparator
94 if (pa < pb)
return false;
95 if (pa > pb)
return true;
104 set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexValid;
108 int nLastBlockFile = 0;
114 uint32_t nBlockSequenceId = 1;
118 map<uint256, NodeId> mapBlockSource;
128 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
129 map<uint256, pair<NodeId, list<uint256>::iterator> > mapBlocksToDownload;
140 struct CMainSignals {
142 boost::signals2::signal<void (const uint256 &, const CTransaction &, const CBlock *)> SyncTransaction;
144 boost::signals2::signal<void (const uint256 &)> EraseTransaction;
146 boost::signals2::signal<void (const uint256 &)> UpdatedTransaction;
148 boost::signals2::signal<void (const CBlockLocator &)> SetBestChain;
150 boost::signals2::signal<void (const uint256 &)> Inventory;
152 boost::signals2::signal<void ()> Broadcast;
175 g_signals.Broadcast.disconnect_all_slots();
176 g_signals.Inventory.disconnect_all_slots();
177 g_signals.SetBestChain.disconnect_all_slots();
178 g_signals.UpdatedTransaction.disconnect_all_slots();
179 g_signals.EraseTransaction.disconnect_all_slots();
180 g_signals.SyncTransaction.disconnect_all_slots();
184 g_signals.SyncTransaction(hash, tx, pblock);
194 struct CBlockReject {
195 unsigned char chRejectCode;
196 string strRejectReason;
212 std::vector<CBlockReject> rejects;
222 int64_t nStallingSince;
223 list<QueuedBlock> vBlocksInFlight;
226 bool fPreferredDownload;
229 list<uint256> vBlocksToDownload;
230 int nBlocksToDownload;
231 int64_t nLastBlockReceive;
232 int64_t nLastBlockProcess;
237 pindexBestKnownBlock = NULL;
238 hashLastUnknownBlock =
uint256(0);
239 pindexLastCommonBlock = NULL;
240 fSyncStarted =
false;
243 fPreferredDownload =
false;
245 nBlocksToDownload = 0;
246 nLastBlockReceive = 0;
247 nLastBlockProcess = 0;
252 map<NodeId, CNodeState> mapNodeState;
255 CNodeState *State(
NodeId pnode) {
256 map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
257 if (it == mapNodeState.end())
265 return chainActive.
Height();
268 void InitializeNode(
NodeId nodeid,
const CNode *pnode) {
270 CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
274 void FinalizeNode(
NodeId nodeid) {
276 CNodeState *state = State(nodeid);
278 BOOST_FOREACH(
const QueuedBlock& entry, state->vBlocksInFlight)
279 mapBlocksInFlight.erase(entry.hash);
280 BOOST_FOREACH(const
uint256& hash, state->vBlocksToDownload)
281 mapBlocksToDownload.erase(hash);
284 mapNodeState.erase(nodeid);
288 void MarkBlockAsReceived(const
uint256 &hash,
NodeId nodeFrom = -1) {
289 map<uint256, pair<NodeId, list<uint256>::iterator> >::iterator itToDownload = mapBlocksToDownload.find(hash);
290 if (itToDownload != mapBlocksToDownload.end()) {
291 CNodeState *state = State(itToDownload->second.first);
292 state->vBlocksToDownload.erase(itToDownload->second.second);
293 state->nBlocksToDownload--;
294 mapBlocksToDownload.erase(itToDownload);
297 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
298 if (itInFlight != mapBlocksInFlight.end()) {
299 CNodeState *state = State(itInFlight->second.first);
300 state->vBlocksInFlight.erase(itInFlight->second.second);
301 state->nBlocksInFlight--;
302 if (itInFlight->second.first == nodeFrom)
304 mapBlocksInFlight.erase(itInFlight);
311 if (mapBlocksToDownload.count(hash) || mapBlocksInFlight.count(hash))
314 CNodeState *state = State(nodeid);
318 list<uint256>::iterator it = state->vBlocksToDownload.insert(state->vBlocksToDownload.end(), hash);
319 state->nBlocksToDownload++;
320 if (state->nBlocksToDownload > 5000)
322 mapBlocksToDownload[hash] = std::make_pair(nodeid, it);
327 void MarkBlockAsInFlight(
NodeId nodeid,
const uint256 &hash) {
328 CNodeState *state = State(nodeid);
329 assert(state != NULL);
332 MarkBlockAsReceived(hash);
334 QueuedBlock newentry = {hash, NULL,
GetTimeMicros(), state->nBlocksInFlight};
335 if (state->nBlocksInFlight == 0)
336 state->nLastBlockReceive = newentry.nTime;
337 list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
338 state->nBlocksInFlight++;
339 mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
346 CNodeState *state = State(nodeid);
350 stats.
nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
351 stats.
nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
352 BOOST_FOREACH(
const QueuedBlock& queue, state->vBlocksInFlight) {
361 nodeSignals.
GetHeight.connect(&GetHeight);
370 nodeSignals.
GetHeight.disconnect(&GetHeight);
383 if (pindex == NULL) {
387 vChain.resize(pindex->
nHeight + 1);
388 while (pindex && vChain[pindex->
nHeight] != pindex) {
389 vChain[pindex->
nHeight] = pindex;
390 pindex = pindex->
pprev;
397 std::vector<uint256> vHave;
408 int nHeight = std::max(pindex->
nHeight - nStep, 0);
410 while (pindex->
nHeight > nHeight && !Contains(pindex))
411 pindex = pindex->
pprev;
414 pindex = (*this)[nHeight];
415 if (vHave.size() > 10)
425 std::map<uint256, CBlockIndex*>::iterator mi =
mapBlockIndex.find(hash);
429 if (Contains(pindex))
460 LogPrint(
"mempool",
"ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.
ToString());
466 BOOST_FOREACH(
const CTxIn& txin, tx.
vin)
469 LogPrint(
"mempool",
"stored orphan tx %s (mapsz %u prevsz %u)\n", hash.
ToString(),
474 void static EraseOrphanTx(
uint256 hash)
479 BOOST_FOREACH(
const CTxIn& txin, it->second.tx.vin)
484 itPrev->second.erase(hash);
485 if (itPrev->second.empty())
497 map<uint256, COrphanTx>::iterator maybeErase = iter++;
498 if (maybeErase->second.fromPeer == peer)
500 EraseOrphanTx(maybeErase->second.tx.GetHash());
504 if (nErased > 0) LogPrint(
"mempool",
"Erased %d orphan tx from peer %d\n", nErased, peer);
510 unsigned int nEvicted = 0;
518 EraseOrphanTx(it->first);
556 reason =
"non-final";
565 if (sz >= MAX_STANDARD_TX_SIZE) {
570 BOOST_FOREACH(
const CTxIn& txin, tx.
vin)
580 reason =
"scriptsig-size";
584 reason =
"scriptsig-not-pushonly";
588 reason =
"scriptsig-non-canonical-push";
593 unsigned int nDataOut = 0;
597 reason =
"scriptpubkey";
610 reason =
"multi-op-return";
623 if (nBlockHeight == 0)
624 nBlockHeight = chainActive.
Height();
627 if ((int64_t)tx.
nLockTime < ((int64_t)tx.
nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
629 BOOST_FOREACH(
const CTxIn& txin, tx.
vin)
651 for (
unsigned int i = 0; i < tx.
vin.size(); i++)
655 vector<vector<unsigned char> > vSolutions;
659 if (!
Solver(prevScript, whichType, vSolutions))
662 if (nArgsExpected < 0)
670 vector<vector<unsigned char> > stack;
671 if (!
EvalScript(stack, tx.
vin[i].scriptSig, tx, i,
false, 0))
678 CScript subscript(stack.back().begin(), stack.back().end());
679 vector<vector<unsigned char> > vSolutions2;
681 if (!
Solver(subscript, whichType2, vSolutions2))
690 nArgsExpected += tmpExpected;
693 if (stack.size() != (
unsigned int)nArgsExpected)
702 unsigned int nSigOps = 0;
703 BOOST_FOREACH(
const CTxIn& txin, tx.
vin)
719 unsigned int nSigOps = 0;
720 for (
unsigned int i = 0; i < tx.
vin.size(); i++)
729 int CMerkleTx::SetMerkleBranch(
const CBlock* pblock)
734 if (pblock == NULL) {
736 if (pcoinsTip->
GetCoins(GetHash(), coins)) {
751 for (nIndex = 0; nIndex < (int)pblock->
vtx.size(); nIndex++)
754 if (nIndex == (
int)pblock->
vtx.size())
756 vMerkleBranch.clear();
758 LogPrintf(
"ERROR: SetMerkleBranch() : couldn't find tx in block\n");
767 map<uint256, CBlockIndex*>::iterator mi =
mapBlockIndex.find(hashBlock);
771 if (!pindex || !chainActive.
Contains(pindex))
787 return state.
DoS(10, error(
"CheckTransaction() : vin empty"),
788 REJECT_INVALID,
"bad-txns-vin-empty");
790 return state.
DoS(10, error(
"CheckTransaction() : vout empty"),
791 REJECT_INVALID,
"bad-txns-vout-empty");
794 return state.
DoS(100, error(
"CheckTransaction() : size limits failed"),
795 REJECT_INVALID,
"bad-txns-oversize");
798 int64_t nValueOut = 0;
802 return state.
DoS(100, error(
"CheckTransaction() : txout.nValue negative"),
803 REJECT_INVALID,
"bad-txns-vout-negative");
804 if (txout.
nValue > MAX_MONEY)
805 return state.
DoS(100, error(
"CheckTransaction() : txout.nValue too high"),
806 REJECT_INVALID,
"bad-txns-vout-toolarge");
807 nValueOut += txout.
nValue;
809 return state.
DoS(100, error(
"CheckTransaction() : txout total out of range"),
810 REJECT_INVALID,
"bad-txns-txouttotal-toolarge");
814 set<COutPoint> vInOutPoints;
815 BOOST_FOREACH(
const CTxIn& txin, tx.
vin)
817 if (vInOutPoints.count(txin.
prevout))
818 return state.
DoS(100, error(
"CheckTransaction() : duplicate inputs"),
819 REJECT_INVALID,
"bad-txns-inputs-duplicate");
820 vInOutPoints.insert(txin.
prevout);
832 if (tx.
vin[0].scriptSig.size() < 2 || tx.
vin[0].scriptSig.size() > 120)
833 return state.
DoS(100, error(
"CheckTransaction() : coinbase script size"),
834 REJECT_INVALID,
"bad-cb-length");
838 BOOST_FOREACH(
const CTxIn& txin, tx.
vin)
840 return state.
DoS(10, error(
"CheckTransaction() : prevout is null"),
841 REJECT_INVALID,
"bad-txns-prevout-null");
852 int64_t nMinFee = (1 + (int64_t)nBytes / 1000) * nBaseFee;
862 if (nBytes < (mode ==
GMF_SEND ? 5000 : (DEFAULT_BLOCK_PRIORITY_SIZE - 1000)))
869 if (txout.
nValue < DUST_SOFT_LIMIT)
879 bool* pfMissingInputs,
bool fRejectInsaneFee)
883 *pfMissingInputs =
false;
886 return error(
"AcceptToMemoryPool: : CheckTransaction failed");
890 return state.
DoS(100, error(
"AcceptToMemoryPool: : coinbase as individual tx"),
891 REJECT_INVALID,
"coinbase");
897 error(
"AcceptToMemoryPool : nonstandard transaction: %s", reason),
898 REJECT_NONSTANDARD, reason);
908 for (
unsigned int i = 0; i < tx.
vin.size(); i++)
935 BOOST_FOREACH(
const CTxIn txin, tx.
vin) {
938 *pfMissingInputs =
true;
945 return state.
Invalid(error(
"AcceptToMemoryPool : inputs already spent"),
946 REJECT_DUPLICATE,
"bad-txns-inputs-spent");
957 return error(
"AcceptToMemoryPool: : nonstandard transaction input");
965 int64_t nFees = nValueIn-nValueOut;
969 unsigned int nSize = entry.GetTxSize();
973 if (fLimitFree && nFees < txMinFee)
974 return state.
DoS(0, error(
"AcceptToMemoryPool : not enough fees %s, %d < %d",
976 REJECT_INSUFFICIENTFEE,
"insufficient fee");
984 static double dFreeCount;
985 static int64_t nLastTime;
991 dFreeCount *= pow(1.0 - 1.0/600.0, (
double)(nNow - nLastTime));
995 if (dFreeCount >=
GetArg(
"-limitfreerelay", 15)*10*1000)
996 return state.
DoS(0, error(
"AcceptToMemoryPool : free transaction rejected by rate limiter"),
997 REJECT_INSUFFICIENTFEE,
"insufficient priority");
998 LogPrint(
"mempool",
"Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
1003 return error(
"AcceptToMemoryPool: : insane fees %s, %d > %d",
1011 return error(
"AcceptToMemoryPool: : ConnectInputs failed %s", hash.
ToString());
1017 g_signals.SyncTransaction(hash, tx, NULL);
1025 if (hashBlock == 0 || nIndex == -1)
1030 map<uint256, CBlockIndex*>::iterator mi =
mapBlockIndex.find(hashBlock);
1034 if (!pindex || !chainActive.
Contains(pindex))
1038 if (!fMerkleVerified)
1042 fMerkleVerified =
true;
1052 int nResult = GetDepthInMainChainINTERNAL(pindexRet);
1053 if (nResult == 0 && !mempool.
exists(GetHash()))
1063 return max(0, (COINBASE_MATURITY+1) - GetDepthInMainChain());
1081 if (mempool.
lookup(hash, txOut))
1096 }
catch (std::exception &e) {
1097 return error(
"%s : Deserialize or I/O error - %s", __func__, e.what());
1101 return error(
"%s : txid mismatch", __func__);
1115 pindexSlow = chainActive[nHeight];
1150 return error(
"WriteBlockToDisk : OpenBlockFile failed");
1157 long fileOutPos = ftell(fileout);
1159 return error(
"WriteBlockToDisk : ftell failed");
1160 pos.
nPos = (
unsigned int)fileOutPos;
1178 return error(
"ReadBlockFromDisk : OpenBlockFile failed");
1184 catch (std::exception &e) {
1185 return error(
"%s : Deserialize or I/O error - %s", __func__, e.what());
1190 return error(
"ReadBlockFromDisk : Errors in block header");
1200 return error(
"ReadBlockFromDisk(CBlock&, CBlockIndex*) : GetHash() doesn't match index");
1206 map<uint256, COrphanBlock*>::iterator it =
mapOrphanBlocks.find(hash);
1212 map<uint256, COrphanBlock*>::iterator it2 =
mapOrphanBlocks.find(it->second->hashPrev);
1220 void static PruneOrphanBlocks()
1232 std::multimap<uint256, COrphanBlock*>::iterator it2 =
mapOrphanBlocksByPrev.find(it->second->hashBlock);
1238 uint256 hash = it->second->hashBlock;
1251 static int64_t nLastUpdate;
1253 if (chainActive.
Tip() != pindexLastBest)
1255 pindexLastBest = chainActive.
Tip();
1258 return (
GetTime() - nLastUpdate < 10 &&
1276 if (pindexBestForkTip && chainActive.
Height() - pindexBestForkTip->
nHeight >= 72)
1277 pindexBestForkTip = NULL;
1279 if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.
Tip()->
nChainWork + (chainActive.
Tip()->
GetBlockWork() * 6).getuint256()))
1281 if (!fLargeWorkForkFound)
1283 std::string strCmd =
GetArg(
"-alertnotify",
"");
1284 if (!strCmd.empty())
1286 std::string warning = std::string(
"'Warning: Large-work fork detected, forking after block ") +
1287 pindexBestForkBase->phashBlock->ToString() + std::string(
"'");
1288 boost::replace_all(strCmd,
"%s", warning);
1292 if (pindexBestForkTip)
1294 LogPrintf(
"CheckForkWarningConditions: Warning: Large valid fork found\n forking the chain at height %d (%s)\n lasting to height %d (%s).\nChain state database corruption likely.\n",
1295 pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(),
1297 fLargeWorkForkFound =
true;
1301 LogPrintf(
"CheckForkWarningConditions: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n");
1302 fLargeWorkInvalidChainFound =
true;
1307 fLargeWorkForkFound =
false;
1308 fLargeWorkInvalidChainFound =
false;
1318 while (pfork && pfork != plonger)
1321 plonger = plonger->
pprev;
1322 if (pfork == plonger)
1324 pfork = pfork->
pprev;
1334 if (pfork && (!pindexBestForkTip || (pindexBestForkTip && pindexNewForkTip->
nHeight > pindexBestForkTip->
nHeight)) &&
1338 pindexBestForkTip = pindexNewForkTip;
1339 pindexBestForkBase = pfork;
1351 CNodeState *state = State(pnode);
1355 state->nMisbehavior += howmuch;
1356 if (state->nMisbehavior >=
GetArg(
"-banscore", 100))
1358 LogPrintf(
"Misbehaving: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
1359 state->fShouldBan =
true;
1361 LogPrintf(
"Misbehaving: %s (%d -> %d)\n", state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
1364 void static InvalidChainFound(
CBlockIndex* pindexNew)
1366 if (!pindexBestInvalid || pindexNew->
nChainWork > pindexBestInvalid->nChainWork)
1368 pindexBestInvalid = pindexNew;
1375 LogPrintf(
"InvalidChainFound: invalid block=%s height=%d log2_work=%.8g date=%s\n",
1379 LogPrintf(
"InvalidChainFound: current best=%s height=%d log2_work=%.8g date=%s\n",
1388 std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->
GetBlockHash());
1389 if (it != mapBlockSource.end() && State(it->second)) {
1391 State(it->second)->rejects.push_back(reject);
1399 setBlockIndexValid.erase(pindex);
1400 InvalidChainFound(pindex);
1428 BOOST_FOREACH(
const CTxIn &txin, tx.
vin) {
1443 const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
1444 if (!
VerifyScript(scriptSig, scriptPubKey, *ptxTo, nIn, nFlags, nHashType))
1445 return error(
"CScriptCheck() : %s VerifySignature failed", ptxTo->GetHash().ToString());
1451 return CScriptCheck(txFrom, txTo, nIn, flags, nHashType)();
1459 pvChecks->reserve(tx.
vin.size());
1469 int nSpendHeight = pindexPrev->
nHeight + 1;
1470 int64_t nValueIn = 0;
1472 for (
unsigned int i = 0; i < tx.
vin.size(); i++)
1479 if (nSpendHeight - coins.
nHeight < COINBASE_MATURITY)
1481 error(
"CheckInputs() : tried to spend coinbase at depth %d", nSpendHeight - coins.
nHeight),
1482 REJECT_INVALID,
"bad-txns-premature-spend-of-coinbase");
1486 nValueIn += coins.
vout[prevout.
n].nValue;
1488 return state.
DoS(100, error(
"CheckInputs() : txin values out of range"),
1489 REJECT_INVALID,
"bad-txns-inputvalues-outofrange");
1494 return state.
DoS(100, error(
"CheckInputs() : %s value in < value out", tx.
GetHash().
ToString()),
1495 REJECT_INVALID,
"bad-txns-in-belowout");
1500 return state.
DoS(100, error(
"CheckInputs() : %s nTxFee < 0", tx.
GetHash().
ToString()),
1501 REJECT_INVALID,
"bad-txns-fee-negative");
1504 return state.
DoS(100, error(
"CheckInputs() : nFees out of range"),
1505 REJECT_INVALID,
"bad-txns-fee-outofrange");
1514 if (fScriptChecks) {
1515 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
1523 check.
swap(pvChecks->back());
1524 }
else if (!check()) {
1528 CScriptCheck check(coins, tx, i, flags & (~SCRIPT_VERIFY_STRICTENC), 0);
1530 return state.
Invalid(
false, REJECT_NONSTANDARD,
"non-canonical");
1532 return state.
DoS(100,
false, REJECT_NONSTANDARD,
"non-canonical");
1555 return error(
"DisconnectBlock() : no undo data available");
1557 return error(
"DisconnectBlock() : failure reading undo data");
1559 if (blockUndo.
vtxundo.size() + 1 != block.
vtx.size())
1560 return error(
"DisconnectBlock() : block and undo data inconsistent");
1563 for (
int i = block.
vtx.size() - 1; i >= 0; i--) {
1569 fClean = fClean && error(
"DisconnectBlock() : outputs still spent? database corrupted");
1587 if (outs != outsBlock)
1588 fClean = fClean && error(
"DisconnectBlock() : added transaction mismatch? database corrupted");
1597 return error(
"DisconnectBlock() : transaction and undo data inconsistent");
1598 for (
unsigned int j = tx.
vin.size(); j-- > 0;) {
1606 fClean = fClean && error(
"DisconnectBlock() : undo data overwriting existing transaction");
1613 fClean = fClean && error(
"DisconnectBlock() : undo data adding output to missing transaction");
1616 fClean = fClean && error(
"DisconnectBlock() : undo data overwriting existing output");
1617 if (coins.
vout.size() < out.
n+1)
1618 coins.
vout.resize(out.
n+1);
1621 return error(
"DisconnectBlock() : cannot restore coin inputs");
1637 void static FlushBlockFile(
bool fFinalize =
false)
1639 LOCK(cs_LastBlockFile);
1666 scriptcheckqueue.Thread();
1673 if (!
CheckBlock(block, state, !fJustCheck, !fJustCheck))
1700 bool fEnforceBIP30 =
true;
1701 if (fEnforceBIP30) {
1702 for (
unsigned int i = 0; i < block.
vtx.size(); i++) {
1705 return state.
DoS(100, error(
"ConnectBlock() : tried to overwrite transaction"),
1706 REJECT_INVALID,
"bad-txns-BIP30");
1711 int64_t nBIP16SwitchTime = 1349049600;
1712 bool fStrictPayToScriptHash = (pindex->
nTime >= nBIP16SwitchTime);
1724 unsigned int nSigOps = 0;
1726 std::vector<std::pair<uint256, CDiskTxPos> > vPos;
1727 vPos.reserve(block.
vtx.size());
1728 for (
unsigned int i = 0; i < block.
vtx.size(); i++)
1732 nInputs += tx.
vin.size();
1734 if (nSigOps > MAX_BLOCK_SIGOPS)
1735 return state.
DoS(100, error(
"ConnectBlock() : too many sigops"),
1736 REJECT_INVALID,
"bad-blk-sigops");
1741 return state.
DoS(100, error(
"ConnectBlock() : inputs missing/spent"),
1742 REJECT_INVALID,
"bad-txns-inputs-missingorspent");
1744 if (fStrictPayToScriptHash)
1750 if (nSigOps > MAX_BLOCK_SIGOPS)
1751 return state.
DoS(100, error(
"ConnectBlock() : too many sigops"),
1752 REJECT_INVALID,
"bad-blk-sigops");
1757 std::vector<CScriptCheck> vChecks;
1760 control.
Add(vChecks);
1766 blockundo.
vtxundo.push_back(txundo);
1768 vPos.push_back(std::make_pair(block.
GetTxHash(i), pos));
1773 LogPrintf(
"- Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin)\n", (
unsigned)block.
vtx.size(), 0.001 * nTime, 0.001 * nTime / block.
vtx.size(), nInputs <= 1 ? 0 : 0.001 * nTime / (nInputs-1));
1776 return state.
DoS(100,
1777 error(
"ConnectBlock() : coinbase pays too much (actual=%d vs limit=%d)",
1779 REJECT_INVALID,
"bad-cb-amount");
1781 if (!control.
Wait())
1782 return state.
DoS(100,
false);
1785 LogPrintf(
"- Verify %u txins: %.2fms (%.3fms/txin)\n", nInputs - 1, 0.001 * nTime2, nInputs <= 1 ? 0 : 0.001 * nTime2 / (nInputs-1));
1796 return error(
"ConnectBlock() : FindUndoPos failed");
1798 return state.
Abort(
_(
"Failed to write undo data"));
1809 return state.
Abort(
_(
"Failed to write block index"));
1814 return state.
Abort(
_(
"Failed to write transaction index"));
1822 for (
unsigned int i = 0; i < block.
vtx.size(); i++)
1823 g_signals.SyncTransaction(block.
GetTxHash(i), block.
vtx[i], &block);
1830 static int64_t nLastWrite = 0;
1838 return state.
Error(
"out of disk space");
1841 if (!pcoinsTip->
Flush())
1842 return state.
Abort(
_(
"Failed to write to coin database"));
1850 chainActive.
SetTip(pindexNew);
1854 if ((chainActive.
Height() % 20160) == 0 || (!fIsInitialDownload && (chainActive.
Height() % 144) == 0))
1855 g_signals.SetBestChain(chainActive.
GetLocator());
1860 LogPrintf(
"UpdateTip: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f\n",
1866 if (!fIsInitialDownload)
1870 for (
int i = 0; i < 100 && pindex != NULL; i++)
1874 pindex = pindex->
pprev;
1878 if (nUpgraded > 100/2)
1880 strMiscWarning =
_(
"Warning: This version is obsolete, upgrade required!");
1887 assert(pindexDelete);
1888 mempool.
check(pcoinsTip);
1892 return state.
Abort(
_(
"Failed to read block"));
1898 return error(
"DisconnectTip() : DisconnectBlock %s failed", pindexDelete->
GetBlockHash().
ToString());
1899 assert(view.Flush());
1904 if (!WriteChainState(state))
1909 list<CTransaction> removed;
1913 mempool.
remove(tx, removed,
true);
1915 mempool.
check(pcoinsTip);
1917 UpdateTip(pindexDelete->
pprev);
1928 assert(pindexNew->
pprev == chainActive.
Tip());
1929 mempool.
check(pcoinsTip);
1933 return state.
Abort(
_(
"Failed to read block"));
1941 InvalidBlockFound(pindexNew, state);
1944 mapBlockSource.erase(inv.hash);
1945 assert(view.Flush());
1950 if (!WriteChainState(state))
1953 list<CTransaction> txConflicted;
1955 list<CTransaction> unused;
1956 mempool.
remove(tx, unused);
1959 mempool.
check(pcoinsTip);
1961 UpdateTip(pindexNew);
1976 void static FindMostWorkChain() {
1981 setBlockIndexValid.erase(chainMostWork.
Tip());
1988 std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexValid.rbegin();
1989 if (it == setBlockIndexValid.rend())
1997 bool fInvalidAncestor =
false;
1998 while (pindexTest && !chainActive.
Contains(pindexTest)) {
2001 if (pindexBestInvalid == NULL || pindexNew->
nChainWork > pindexBestInvalid->nChainWork)
2002 pindexBestInvalid = pindexNew;
CBlockIndex *pindexFailed = pindexNew;
2003 while (pindexTest != pindexFailed) {
2005 setBlockIndexValid.erase(pindexFailed);
2006 pindexFailed = pindexFailed->
pprev;
2008 fInvalidAncestor =
true;
2011 pindexTest = pindexTest->
pprev;
2013 if (fInvalidAncestor)
2020 if (chainMostWork.
Tip() && !CBlockIndexWorkComparator()(chainMostWork.
Tip(), pindexNew))
2024 chainMostWork.
SetTip(pindexNew);
2031 bool fComplete =
false;
2032 while (!fComplete) {
2033 FindMostWorkChain();
2037 if (chainMostWork.
Tip() == NULL)
break;
2040 while (chainActive.
Tip() && !chainMostWork.
Contains(chainActive.
Tip())) {
2041 if (!DisconnectTip(state))
2046 while (!chainActive.
Contains(chainMostWork.
Tip())) {
2048 if (!ConnectTip(state, pindexConnect)) {
2052 InvalidChainFound(chainMostWork.
Tip());
2064 if (chainActive.
Tip() != pindexOldTip) {
2065 std::string strCmd =
GetArg(
"-blocknotify",
"");
2081 return state.
Invalid(error(
"AddToBlockIndex() : %s already exists", hash.
ToString()), 0,
"duplicate");
2087 LOCK(cs_nBlockSequenceId);
2090 map<uint256, CBlockIndex*>::iterator mi =
mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
2095 pindexNew->
pprev = (*miPrev).second;
2098 pindexNew->
nTx = block.
vtx.size();
2105 setBlockIndexValid.insert(pindexNew);
2108 return state.
Abort(
_(
"Failed to write block index"));
2115 if (pindexNew == chainActive.
Tip())
2120 static uint256 hashPrevBestCoinBase;
2121 g_signals.UpdatedTransaction(hashPrevBestCoinBase);
2122 hashPrevBestCoinBase = block.
GetTxHash(0);
2126 if (!pblocktree->
Flush())
2127 return state.
Abort(
_(
"Failed to sync block index"));
2136 bool fUpdatedLast =
false;
2138 LOCK(cs_LastBlockFile);
2141 if (nLastBlockFile != pos.
nFile) {
2142 nLastBlockFile = pos.
nFile;
2143 infoLastBlockFile.SetNull();
2145 fUpdatedLast =
true;
2148 while (infoLastBlockFile.nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
2149 LogPrintf(
"Leaving block file %i: %s\n", nLastBlockFile, infoLastBlockFile.ToString());
2150 FlushBlockFile(
true);
2152 infoLastBlockFile.SetNull();
2154 fUpdatedLast =
true;
2156 pos.
nFile = nLastBlockFile;
2157 pos.
nPos = infoLastBlockFile.nSize;
2160 infoLastBlockFile.nSize += nAddSize;
2161 infoLastBlockFile.AddBlock(nHeight, nTime);
2164 unsigned int nOldChunks = (pos.
nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
2165 unsigned int nNewChunks = (infoLastBlockFile.nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
2166 if (nNewChunks > nOldChunks) {
2170 LogPrintf(
"Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.
nFile);
2176 return state.
Error(
"out of disk space");
2181 return state.
Abort(
_(
"Failed to write file info"));
2192 LOCK(cs_LastBlockFile);
2194 unsigned int nNewSize;
2195 if (nFile == nLastBlockFile) {
2196 pos.
nPos = infoLastBlockFile.nUndoSize;
2197 nNewSize = (infoLastBlockFile.nUndoSize += nAddSize);
2199 return state.
Abort(
_(
"Failed to write block info"));
2203 return state.
Abort(
_(
"Failed to read block info"));
2205 nNewSize = (info.
nUndoSize += nAddSize);
2207 return state.
Abort(
_(
"Failed to write block info"));
2210 unsigned int nOldChunks = (pos.
nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
2211 unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
2212 if (nNewChunks > nOldChunks) {
2216 LogPrintf(
"Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.
nFile);
2222 return state.
Error(
"out of disk space");
2236 return state.
DoS(100, error(
"CheckBlock() : size limits failed"),
2237 REJECT_INVALID,
"bad-blk-length");
2241 return state.
DoS(50, error(
"CheckBlock() : proof of work failed"),
2242 REJECT_INVALID,
"high-hash");
2246 return state.
Invalid(error(
"CheckBlock() : block timestamp too far in the future"),
2247 REJECT_INVALID,
"time-too-new");
2250 if (block.
vtx.empty() || !block.
vtx[0].IsCoinBase())
2251 return state.
DoS(100, error(
"CheckBlock() : first tx is not coinbase"),
2252 REJECT_INVALID,
"bad-cb-missing");
2253 for (
unsigned int i = 1; i < block.
vtx.size(); i++)
2254 if (block.
vtx[i].IsCoinBase())
2255 return state.
DoS(100, error(
"CheckBlock() : more than one coinbase"),
2256 REJECT_INVALID,
"bad-cb-multiple");
2261 return error(
"CheckBlock() : CheckTransaction failed");
2270 set<uint256> uniqueTx;
2271 for (
unsigned int i = 0; i < block.
vtx.size(); i++) {
2274 if (uniqueTx.size() != block.
vtx.size())
2275 return state.
DoS(100, error(
"CheckBlock() : duplicate transaction"),
2276 REJECT_INVALID,
"bad-txns-duplicate",
true);
2278 unsigned int nSigOps = 0;
2283 if (nSigOps > MAX_BLOCK_SIGOPS)
2284 return state.
DoS(100, error(
"CheckBlock() : out-of-bounds SigOpCount"),
2285 REJECT_INVALID,
"bad-blk-sigops",
true);
2289 return state.
DoS(100, error(
"CheckBlock() : hashMerkleRoot mismatch"),
2290 REJECT_INVALID,
"bad-txnmrklroot",
true);
2301 return state.
Invalid(error(
"AcceptBlock() : block already in mapBlockIndex"), 0,
"duplicate");
2306 if (hash !=
Params().HashGenesisBlock()) {
2309 return state.
DoS(10, error(
"AcceptBlock() : prev block not found"), 0,
"bad-prevblk");
2310 pindexPrev = (*mi).second;
2311 nHeight = pindexPrev->
nHeight+1;
2315 return state.
DoS(100, error(
"AcceptBlock() : incorrect proof of work"),
2316 REJECT_INVALID,
"bad-diffbits");
2320 return state.
Invalid(error(
"AcceptBlock() : block's timestamp is too early"),
2321 REJECT_INVALID,
"time-too-old");
2326 return state.
DoS(10, error(
"AcceptBlock() : contains a non-final transaction"),
2327 REJECT_INVALID,
"bad-txns-nonfinal");
2331 return state.
DoS(100, error(
"AcceptBlock() : rejected by checkpoint lock-in at %d", nHeight),
2332 REJECT_CHECKPOINT,
"checkpoint mismatch");
2336 if (pcheckpoint && nHeight < pcheckpoint->nHeight)
2337 return state.
DoS(100, error(
"AcceptBlock() : forked chain older than last checkpoint (height %d)", nHeight));
2342 if ((!
TestNet() && nHeight >= 710000) ||
2343 (
TestNet() && nHeight >= 400000))
2345 return state.
Invalid(error(
"AcceptBlock() : rejected nVersion=1 block"),
2346 REJECT_OBSOLETE,
"bad-version");
2352 if ((!
TestNet() && nHeight >= 710000) ||
2353 (
TestNet() && nHeight >= 400000))
2356 if (block.
vtx[0].vin[0].scriptSig.size() < expect.size() ||
2357 !std::equal(expect.begin(), expect.end(), block.
vtx[0].vin[0].scriptSig.begin()))
2358 return state.
DoS(100, error(
"AcceptBlock() : block height mismatch in coinbase"),
2359 REJECT_INVALID,
"bad-cb-height");
2370 if (!
FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.
nTime, dbp != NULL))
2371 return error(
"AcceptBlock() : FindBlockPos failed");
2374 return state.
Abort(
_(
"Failed to write block"));
2376 return error(
"AcceptBlock() : AddToBlockIndex failed");
2377 }
catch(std::runtime_error &e) {
2378 return state.
Abort(
_(
"System error: ") + e.what());
2396 unsigned int nFound = 0;
2397 for (
unsigned int i = 0; i < nToCheck && nFound < nRequired && pstart != NULL; i++)
2399 if (pstart->
nVersion >= minVersion)
2401 pstart = pstart->
pprev;
2403 return (nFound >= nRequired);
2410 for (
int i = 0; i < nMedianTimeSpan/2; i++)
2412 if (!chainActive.
Next(pindex))
2413 return GetBlockTime();
2414 pindex = chainActive.
Next(pindex);
2438 return state.
Invalid(error(
"ProcessBlock() : already have block %d %s",
mapBlockIndex[hash]->nHeight, hash.
ToString()), 0,
"duplicate");
2440 return state.
Invalid(error(
"ProcessBlock() : already have block (orphan) %s", hash.
ToString()), 0,
"duplicate");
2444 return error(
"ProcessBlock() : CheckBlock FAILED");
2453 return state.
DoS(100, error(
"ProcessBlock() : block with timestamp before last checkpoint"),
2454 REJECT_CHECKPOINT,
"time-too-old");
2460 if (bnNewBlock > bnRequired)
2462 return state.
DoS(100, error(
"ProcessBlock() : block with too little proof-of-work"),
2463 REJECT_INVALID,
"bad-diffbits");
2475 PruneOrphanBlocks();
2495 return error(
"ProcessBlock() : AcceptBlock FAILED");
2498 vector<uint256> vWorkQueue;
2499 vWorkQueue.push_back(hash);
2500 for (
unsigned int i = 0; i < vWorkQueue.size(); i++)
2502 uint256 hashPrev = vWorkQueue[i];
2516 vWorkQueue.push_back(mi->second->hashBlock);
2538 vector<bool> vMatch;
2539 vector<uint256> vHashes;
2541 vMatch.reserve(block.
vtx.size());
2542 vHashes.reserve(block.
vtx.size());
2544 for (
unsigned int i = 0; i < block.
vtx.size(); i++)
2549 vMatch.push_back(
true);
2550 vMatchedTxn.push_back(make_pair(i, hash));
2553 vMatch.push_back(
false);
2554 vHashes.push_back(hash);
2573 uint256 left = CalcHash(height-1, pos*2, vTxid), right;
2575 if (pos*2+1 < CalcTreeWidth(height-1))
2576 right = CalcHash(height-1, pos*2+1, vTxid);
2586 bool fParentOfMatch =
false;
2587 for (
unsigned int p = pos << height; p < (pos+1) << height && p < nTransactions; p++)
2588 fParentOfMatch |= vMatch[p];
2590 vBits.push_back(fParentOfMatch);
2591 if (height==0 || !fParentOfMatch) {
2593 vHash.push_back(CalcHash(height, pos, vTxid));
2596 TraverseAndBuild(height-1, pos*2, vTxid, vMatch);
2597 if (pos*2+1 < CalcTreeWidth(height-1))
2598 TraverseAndBuild(height-1, pos*2+1, vTxid, vMatch);
2603 if (nBitsUsed >= vBits.size()) {
2608 bool fParentOfMatch = vBits[nBitsUsed++];
2609 if (height==0 || !fParentOfMatch) {
2611 if (nHashUsed >= vHash.size()) {
2616 const uint256 &hash = vHash[nHashUsed++];
2617 if (height==0 && fParentOfMatch)
2618 vMatch.push_back(hash);
2622 uint256 left = TraverseAndExtract(height-1, pos*2, nBitsUsed, nHashUsed, vMatch), right;
2623 if (pos*2+1 < CalcTreeWidth(height-1))
2624 right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch);
2632 CPartialMerkleTree::CPartialMerkleTree(
const std::vector<uint256> &vTxid,
const std::vector<bool> &vMatch) : nTransactions(vTxid.size()), fBad(false) {
2646 CPartialMerkleTree::CPartialMerkleTree() : nTransactions(0), fBad(true) {}
2667 unsigned int nBitsUsed = 0, nHashUsed = 0;
2673 if ((nBitsUsed+7)/8 != (
vBits.size()+7)/8)
2676 if (nHashUsed !=
vHash.size())
2678 return hashMerkleRoot;
2697 uint64_t nFreeBytesAvailable = filesystem::space(
GetDataDir()).available;
2700 if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
2701 return AbortNode(
_(
"Error: Disk space is low!"));
2711 boost::filesystem::create_directories(path.parent_path());
2712 FILE* file = fopen(path.string().c_str(),
"rb+");
2713 if (!file && !fReadOnly)
2714 file = fopen(path.string().c_str(),
"wb+");
2716 LogPrintf(
"Unable to open file %s\n", path.string());
2720 if (fseek(file, pos.
nPos, SEEK_SET)) {
2721 LogPrintf(
"Unable to seek to position %u of %s\n", pos.
nPos, path.string());
2743 map<uint256, CBlockIndex*>::iterator mi =
mapBlockIndex.find(hash);
2745 return (*mi).second;
2750 throw runtime_error(
"LoadBlockIndex() : new CBlockIndex failed");
2751 mi =
mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
2757 bool static LoadBlockIndexDB()
2762 boost::this_thread::interruption_point();
2765 vector<pair<int, CBlockIndex*> > vSortedByHeight;
2770 vSortedByHeight.push_back(make_pair(pindex->
nHeight, pindex));
2772 sort(vSortedByHeight.begin(), vSortedByHeight.end());
2779 setBlockIndexValid.insert(pindex);
2781 pindexBestInvalid = pindex;
2786 LogPrintf(
"LoadBlockIndexDB(): last block file = %i\n", nLastBlockFile);
2788 LogPrintf(
"LoadBlockIndexDB(): last block file info: %s\n", infoLastBlockFile.ToString());
2791 bool fReindexing =
false;
2797 LogPrintf(
"LoadBlockIndexDB(): transaction index %s\n",
fTxIndex ?
"enabled" :
"disabled");
2803 chainActive.
SetTip(it->second);
2804 LogPrintf(
"LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s progress=%f\n",
2815 if (chainActive.
Tip() == NULL || chainActive.
Tip()->
pprev == NULL)
2819 if (nCheckDepth <= 0)
2820 nCheckDepth = 1000000000;
2821 if (nCheckDepth > chainActive.
Height())
2822 nCheckDepth = chainActive.
Height();
2823 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
2824 LogPrintf(
"Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
2828 int nGoodTransactions = 0;
2832 boost::this_thread::interruption_point();
2840 if (nCheckLevel >= 1 && !
CheckBlock(block, state))
2843 if (nCheckLevel >= 2 && pindex) {
2855 return error(
"VerifyDB() : *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->
nHeight, pindex->
GetBlockHash().
ToString());
2856 pindexState = pindex->
pprev;
2858 nGoodTransactions = 0;
2859 pindexFailure = pindex;
2861 nGoodTransactions += block.
vtx.size();
2865 return error(
"VerifyDB() : *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.
Height() - pindexFailure->
nHeight + 1, nGoodTransactions);
2868 if (nCheckLevel >= 4) {
2870 while (pindex != chainActive.
Tip()) {
2871 boost::this_thread::interruption_point();
2872 pindex = chainActive.
Next(pindex);
2881 LogPrintf(
"No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.
Height() - pindexState->
nHeight, nGoodTransactions);
2889 setBlockIndexValid.clear();
2890 chainActive.
SetTip(NULL);
2891 pindexBestInvalid = NULL;
2897 if (!
fReindex && !LoadBlockIndexDB())
2906 if (chainActive.
Genesis() != NULL)
2912 LogPrintf(
"Initializing databases...\n");
2923 return error(
"LoadBlockIndex() : FindBlockPos failed");
2925 return error(
"LoadBlockIndex() : writing genesis block to disk failed");
2927 return error(
"LoadBlockIndex() : genesis block not accepted");
2928 }
catch(std::runtime_error &e) {
2929 return error(
"LoadBlockIndex() : failed to initialize block database: %s", e.what());
2942 map<CBlockIndex*, vector<CBlockIndex*> > mapNext;
2946 mapNext[pindex->
pprev].push_back(pindex);
2952 vector<pair<int, CBlockIndex*> > vStack;
2953 vStack.push_back(make_pair(0, chainActive.
Genesis()));
2956 while (!vStack.empty())
2958 int nCol = vStack.back().first;
2963 if (nCol > nPrevCol)
2965 for (
int i = 0; i < nCol-1; i++)
2969 else if (nCol < nPrevCol)
2971 for (
int i = 0; i < nCol; i++)
2978 for (
int i = 0; i < nCol; i++)
2984 LogPrintf(
"%d (blk%05u.dat:0x%x) %s tx %u\n",
2991 vector<CBlockIndex*>& vNext = mapNext[pindex];
2992 for (
unsigned int i = 0; i < vNext.size(); i++)
2994 if (chainActive.
Next(vNext[i]))
2996 swap(vNext[0], vNext[i]);
3002 for (
unsigned int i = 0; i < vNext.size(); i++)
3003 vStack.push_back(make_pair(nCol+i, vNext[i]));
3014 uint64_t nStartByte = 0;
3019 nStartByte = info.
nSize;
3023 uint64_t nRewind = blkdat.
GetPos();
3024 while (blkdat.
good() && !blkdat.
eof()) {
3025 boost::this_thread::interruption_point();
3030 unsigned int nSize = 0;
3035 nRewind = blkdat.
GetPos()+1;
3041 if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
3043 }
catch (std::exception &e) {
3049 uint64_t nBlockPos = blkdat.
GetPos();
3050 blkdat.
SetLimit(nBlockPos + nSize);
3053 nRewind = blkdat.
GetPos();
3056 if (nBlockPos >= nStartByte) {
3059 dbp->
nPos = nBlockPos;
3066 }
catch (std::exception &e) {
3067 LogPrintf(
"%s : Deserialize or I/O error - %s", __func__, e.what());
3071 }
catch(std::runtime_error &e) {
3072 AbortNode(
_(
"Error: system error: ") + e.what());
3096 string strStatusBar;
3103 strStatusBar =
_(
"This is a pre-release test build - use at your own risk - do not use for mining or merchant applications");
3112 if (fLargeWorkForkFound)
3115 strStatusBar = strRPC =
_(
"Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.");
3117 else if (fLargeWorkInvalidChainFound)
3120 strStatusBar = strRPC =
_(
"Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.");
3128 const CAlert& alert = item.second;
3137 if (strFor ==
"statusbar")
3138 return strStatusBar;
3139 else if (strFor ==
"rpc")
3141 assert(!
"GetWarnings() : invalid parameter");
3145 void static RelayAlerts(
CNode* pfrom)
3149 item.second.RelayTo(pfrom);
3164 bool static AlreadyHave(const
CInv& inv)
3170 bool txInMap =
false;
3171 txInMap = mempool.
exists(inv.hash);
3184 void static ProcessGetData(
CNode* pfrom)
3186 std::deque<CInv>::iterator it = pfrom->
vRecvGetData.begin();
3188 vector<CInv> vNotFound;
3197 const CInv &inv = *it;
3199 boost::this_thread::interruption_point();
3210 int nHeight = mi->second->nHeight;
3212 if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
3213 if (!chainActive.
Contains(mi->second))
3215 LogPrintf(
"ProcessGetData(): ignoring request for old block that isn't in the main chain\n");
3243 typedef std::pair<unsigned int, uint256> PairType;
3244 BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
3245 if (!pfrom->setInventoryKnown.count(
CInv(
MSG_TX, pair.second)))
3246 pfrom->PushMessage("tx", block.vtx[pair.first]);
3253 if (inv.hash == pfrom->hashContinue)
3268 bool pushed =
false;
3271 map<CInv, CDataStream>::iterator mi =
mapRelay.find(inv);
3277 if (!pushed && inv.
type == MSG_TX) {
3288 vNotFound.push_back(inv);
3293 g_signals.Inventory(inv.
hash);
3302 if (!vNotFound.empty()) {
3314 bool static ProcessMessage(
CNode* pfrom,
string strCommand,
CDataStream& vRecv)
3317 LogPrint(
"net",
"received: %s (%u bytes)\n", strCommand, vRecv.
size());
3320 LogPrintf(
"dropmessagestest DROPPING RECV MESSAGE\n");
3331 if (strCommand ==
"version")
3336 pfrom->
PushMessage(
"reject", strCommand, REJECT_DUPLICATE,
string(
"Duplicate version message"));
3344 uint64_t nNonce = 1;
3346 if (pfrom->
nVersion < MIN_PEER_PROTO_VERSION)
3352 pfrom->
PushMessage(
"reject", strCommand, REJECT_OBSOLETE,
3353 strprintf(
"Version must be %d or greater", MIN_PEER_PROTO_VERSION));
3361 vRecv >> addrFrom >> nNonce;
3362 if (!vRecv.
empty()) {
3368 const char *badSubVers[] = {
"/potcoinseeder",
"/reddcoinseeder",
"/worldcoinseeder" };
3369 for (
int x = 0; x < 3; x++)
3371 if (pfrom->
cleanSubVer.find(badSubVers[x], 0) == 0)
3374 pfrom->
PushMessage(
"reject", strCommand, REJECT_INVALID,
string(
"invalid client subver"));
3387 if (pfrom->
fInbound && addrMe.IsRoutable())
3412 #ifdef ENABLE_I2PSAM
3413 pfrom->SetSendStreamType(pfrom->GetSendStreamType() & ( (pfrom->
nServices & NODE_I2P) ? ~SER_IPADDRONLY : SER_IPADDRONLY));
3445 LogPrintf(
"receive version message: %s: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", pfrom->
cleanSubVer, pfrom->
nVersion, pfrom->
nStartingHeight, addrMe.ToString(), addrFrom.
ToString(), pfrom->
addr.
ToString());
3459 else if (strCommand ==
"verack")
3462 #ifdef ENABLE_I2PSAM
3463 pfrom->SetRecvStreamType( pfrom->GetRecvStreamType() & ( (pfrom->
nServices & NODE_I2P) ? ~SER_IPADDRONLY : SER_IPADDRONLY) );
3468 else if (strCommand ==
"addr")
3470 vector<CAddress> vAddr;
3476 if (vAddr.size() > 1000)
3479 return error(
"message addr size() = %u", vAddr.size());
3483 vector<CAddress> vAddrOk;
3485 int64_t nSince = nNow - 10 * 60;
3486 BOOST_FOREACH(
CAddress& addr, vAddr)
3488 boost::this_thread::interruption_point();
3490 if (addr.
nTime <= 100000000 || addr.
nTime > nNow + 10 * 60)
3491 addr.
nTime = nNow - 5 * 24 * 60 * 60;
3504 uint64_t hashAddr = addr.
GetHash();
3505 uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((
GetTime()+hashAddr)/(24*60*60));
3507 multimap<uint256, CNode*> mapMix;
3510 if (pnode->
nVersion < CADDR_TIME_VERSION)
3512 unsigned int nPointer;
3513 memcpy(&nPointer, &pnode,
sizeof(nPointer));
3514 uint256 hashKey = hashRand ^ nPointer;
3516 mapMix.insert(make_pair(hashKey, pnode));
3518 int nRelayNodes = fReachable ? 2 : 1;
3519 for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
3520 ((*mi).second)->PushAddress(addr);
3525 #ifdef ENABLE_I2PSAM
3530 if( !IsI2PEnabled() || addr.IsNativeI2P() )
3531 vAddrOk.push_back(addr);
3533 #else // Original Code
3534 vAddrOk.push_back(addr);
3539 if (vAddr.size() < 1000)
3546 else if (strCommand ==
"inv")
3550 if (vInv.size() > MAX_INV_SZ)
3553 return error(
"message inv size() = %u", vInv.size());
3558 for (
unsigned int nInv = 0; nInv < vInv.size(); nInv++)
3560 const CInv &inv = vInv[nInv];
3562 boost::this_thread::interruption_point();
3565 bool fAlreadyHave = AlreadyHave(inv);
3566 LogPrint(
"net",
" got inventory: %s %s\n", inv.
ToString(), fAlreadyHave ?
"have" :
"new");
3568 if (!fAlreadyHave) {
3571 AddBlockToQueue(pfrom->
GetId(), inv.
hash);
3580 g_signals.Inventory(inv.
hash);
3584 return error(
"send buffer size() = %u", pfrom->
nSendSize);
3590 else if (strCommand ==
"getdata")
3594 if (vInv.size() > MAX_INV_SZ)
3597 return error(
"message getdata size() = %u", vInv.size());
3600 if (
fDebug || (vInv.size() != 1))
3601 LogPrint(
"net",
"received getdata (%u invsz)\n", vInv.size());
3603 if ((
fDebug && vInv.size() > 0) || (vInv.size() == 1))
3604 LogPrint(
"net",
"received getdata for: %s\n", vInv[0].ToString());
3607 ProcessGetData(pfrom);
3611 else if (strCommand ==
"getblocks")
3615 vRecv >> locator >> hashStop;
3624 pindex = chainActive.
Next(pindex);
3626 LogPrint(
"net",
"getblocks %d to %s limit %d\n", (pindex ? pindex->
nHeight : -1), hashStop.ToString(), nLimit);
3627 for (; pindex; pindex = chainActive.
Next(pindex))
3647 else if (strCommand ==
"getheaders")
3651 vRecv >> locator >> hashStop;
3659 map<uint256, CBlockIndex*>::iterator mi =
mapBlockIndex.find(hashStop);
3662 pindex = (*mi).second;
3667 pindex = chainActive.
FindFork(locator);
3669 pindex = chainActive.
Next(pindex);
3673 vector<CBlock> vHeaders;
3675 LogPrint(
"net",
"getheaders %d to %s\n", (pindex ? pindex->
nHeight : -1), hashStop.ToString());
3676 for (; pindex; pindex = chainActive.
Next(pindex))
3679 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
3686 else if (strCommand ==
"tx")
3688 vector<uint256> vWorkQueue;
3689 vector<uint256> vEraseQueue;
3693 CInv inv(MSG_TX, tx.GetHash());
3698 bool fMissingInputs =
false;
3702 mempool.
check(pcoinsTip);
3705 vWorkQueue.push_back(inv.
hash);
3706 vEraseQueue.push_back(inv.
hash);
3709 LogPrint(
"mempool",
"AcceptToMemoryPool: %s %s : accepted %s (poolsz %u)\n",
3711 tx.GetHash().ToString(),
3712 mempool.
mapTx.size());
3715 set<NodeId> setMisbehaving;
3716 for (
unsigned int i = 0; i < vWorkQueue.size(); i++)
3721 for (set<uint256>::iterator mi = itByPrev->second.begin();
3722 mi != itByPrev->second.end();
3725 const uint256& orphanHash = *mi;
3728 bool fMissingInputs2 =
false;
3734 vEraseQueue.push_back(orphanHash);
3736 if (setMisbehaving.count(fromPeer))
3740 LogPrint(
"mempool",
" accepted orphan tx %s\n", orphanHash.
ToString());
3743 vWorkQueue.push_back(orphanHash);
3745 else if (!fMissingInputs2)
3748 if (stateDummy.
IsInvalid(nDos) && nDos > 0)
3752 setMisbehaving.insert(fromPeer);
3753 LogPrint(
"mempool",
" invalid orphan tx %s\n", orphanHash.
ToString());
3756 LogPrint(
"mempool",
" removed orphan tx %s\n", orphanHash.
ToString());
3758 mempool.
check(pcoinsTip);
3762 BOOST_FOREACH(
uint256 hash, vEraseQueue)
3763 EraseOrphanTx(hash);
3765 else if (fMissingInputs)
3770 unsigned int nMaxOrphanTx = (
unsigned int)std::max((int64_t)0,
GetArg(
"-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
3773 LogPrint(
"mempool",
"mapOrphan overflow, removed %u tx\n", nEvicted);
3778 LogPrint(
"mempool",
"%s from %s %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
3794 LogPrint(
"net",
"received block %s\n", block.GetHash().ToString());
3802 mapBlockSource[inv.
hash] = pfrom->
GetId();
3803 MarkBlockAsReceived(inv.
hash, pfrom->
GetId());
3810 else if (strCommand ==
"getaddr")
3814 BOOST_FOREACH(
const CAddress &addr, vAddr)
3815 pfrom->PushAddress(addr);
3819 else if (strCommand == "mempool")
3823 std::vector<uint256> vtxid;
3824 mempool.queryHashes(vtxid);
3826 BOOST_FOREACH(
uint256& hash, vtxid) {
3827 CInv inv(MSG_TX, hash);
3829 bool fInMemPool = mempool.lookup(hash, tx);
3830 if (!fInMemPool)
continue;
3833 vInv.push_back(inv);
3834 if (vInv.size() == MAX_INV_SZ) {
3839 if (vInv.size() > 0)
3844 else if (strCommand ==
"ping")
3846 if (pfrom->
nVersion > BIP0031_VERSION)
3866 else if (strCommand ==
"pong")
3871 bool bPingFinished =
false;
3872 std::string sProblem;
3874 if (nAvail >=
sizeof(nonce)) {
3881 bPingFinished =
true;
3883 if (pingUsecTime > 0) {
3888 sProblem =
"Timing mishap";
3892 sProblem =
"Nonce mismatch";
3895 bPingFinished =
true;
3896 sProblem =
"Nonce zero";
3900 sProblem =
"Unsolicited pong without ping";
3904 bPingFinished =
true;
3905 sProblem =
"Short payload";
3908 if (!(sProblem.empty())) {
3909 LogPrint(
"net",
"pong %s %s: %s, %x expected, %x received, %u bytes\n",
3917 if (bPingFinished) {
3923 else if (strCommand ==
"alert")
3928 uint256 alertHash = alert.GetHash();
3929 if (pfrom->
setKnown.count(alertHash) == 0)
3931 if (alert.ProcessAlert())
3938 alert.RelayTo(pnode);
3954 else if (strCommand ==
"filterload")
3959 if (!filter.IsWithinSizeConstraints())
3973 else if (strCommand ==
"filteradd")
3975 vector<unsigned char> vData;
3980 if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
3993 else if (strCommand ==
"filterclear")
4002 else if (strCommand ==
"reject")
4006 string strMsg;
unsigned char ccode;
string strReason;
4010 ss << strMsg <<
" code " <<
itostr(ccode) <<
": " << strReason;
4012 if (strMsg ==
"block" || strMsg ==
"tx")
4016 ss <<
": hash " << hash.
ToString();
4019 }
catch (std::ios_base::failure& e) {
4021 LogPrint(
"net",
"Unparseable reject message received\n");
4034 if (strCommand ==
"version" || strCommand ==
"addr" || strCommand ==
"inv" || strCommand ==
"getdata" || strCommand ==
"ping")
4058 ProcessGetData(pfrom);
4063 std::deque<CNetMessage>::iterator it = pfrom->
vRecvMsg.begin();
4086 LogPrintf(
"\n\nPROCESSMESSAGE: INVALID MESSAGESTART\n\n");
4106 unsigned int nChecksum = 0;
4107 memcpy(&nChecksum, &hash,
sizeof(nChecksum));
4110 LogPrintf(
"ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
4111 strCommand, nMessageSize, nChecksum, hdr.
nChecksum);
4119 fRet = ProcessMessage(pfrom, strCommand, vRecv);
4120 boost::this_thread::interruption_point();
4122 catch (std::ios_base::failure& e)
4124 pfrom->
PushMessage(
"reject", strCommand, REJECT_MALFORMED,
string(
"error parsing message"));
4125 if (strstr(e.what(),
"end of data"))
4128 LogPrintf(
"ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand, nMessageSize, e.what());
4130 else if (strstr(e.what(),
"size too large"))
4133 LogPrintf(
"ProcessMessages(%s, %u bytes) : Exception '%s' caught\n", strCommand, nMessageSize, e.what());
4140 catch (boost::thread_interrupted) {
4143 catch (std::exception& e) {
4150 LogPrintf(
"ProcessMessage(%s, %u bytes) FAILED\n", strCommand, nMessageSize);
4173 bool pingSend =
false;
4184 while (nonce == 0) {
4185 RAND_bytes((
unsigned char*)&nonce,
sizeof(nonce));
4189 if (pto->
nVersion > BIP0031_VERSION) {
4204 static int64_t nLastRebroadcast;
4212 if (nLastRebroadcast)
4232 vector<CAddress> vAddr;
4239 vAddr.push_back(addr);
4241 if (vAddr.size() >= 1000)
4253 CNodeState &state = *State(pto->
GetId());
4254 if (state.fShouldBan) {
4261 state.fShouldBan =
false;
4264 BOOST_FOREACH(
const CBlockReject& reject, state.rejects)
4265 pto->
PushMessage(
"reject", (
string)
"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
4266 state.rejects.clear();
4279 g_signals.Broadcast();
4286 vector<CInv> vInvWait;
4297 if (inv.
type == MSG_TX && !fSendTrickle)
4305 bool fTrickleWait = ((hashRand & 3) != 0);
4309 vInvWait.push_back(inv);
4317 vInv.push_back(inv);
4318 if (vInv.size() >= 1000)
4337 state.nLastBlockReceive < state.nLastBlockProcess - BLOCK_DOWNLOAD_TIMEOUT*1000000 &&
4338 state.vBlocksInFlight.front().nTime < state.nLastBlockProcess - 2*BLOCK_DOWNLOAD_TIMEOUT*1000000) {
4339 LogPrintf(
"Peer %s is stalling block download, disconnecting\n", state.name.c_str());
4346 vector<CInv> vGetData;
4347 while (!pto->
fDisconnect && state.nBlocksToDownload && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
4348 uint256 hash = state.vBlocksToDownload.front();
4350 MarkBlockAsInFlight(pto->
GetId(), hash);
4351 LogPrint(
"net",
"Requesting block %s from %s\n", hash.
ToString().c_str(), state.name.c_str());
4352 if (vGetData.size() >= 1000)
4365 if (!AlreadyHave(inv))
4368 LogPrint(
"net",
"sending getdata: %s\n", inv.
ToString());
4369 vGetData.push_back(inv);
4370 if (vGetData.size() >= 1000)
4378 if (!vGetData.empty())
4396 std::map<uint256, CBlockIndex*>::iterator it1 =
mapBlockIndex.begin();
4398 delete (*it1).second;
4402 std::map<uint256, COrphanBlock*>::iterator it2 =
mapOrphanBlocks.begin();
4404 delete (*it2).second;
const boost::filesystem::path & GetDataDir(bool fNetSpecific)
CClientUIInterface uiInterface
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
void PushMessage(const char *pszCommand)
uint64_t GetRand(uint64_t nMax)
bool IsDust(int64_t nMinRelayTxFee) const
bool CheckProofOfWork(uint256 hash, unsigned int nBits)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
int64_t GetValueOut() const
void check(CCoinsViewCache *pcoins) const
CDiskBlockPos GetBlockPos() const
CBigNum GetBlockWork() const
void TraverseAndBuild(int height, unsigned int pos, const std::vector< uint256 > &vTxid, const std::vector< bool > &vMatch)
bool fLargeWorkInvalidChainFound
CCriticalSection cs_filter
bool AreInputsStandard(const CTransaction &tx, CCoinsViewCache &mapInputs)
Check for standard transaction types.
void Add(std::vector< T > &vChecks)
bool AddOrphanTx(const CTransaction &tx, NodeId peer)
FILE * OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly)
Open a block file (blk?????.dat)
const_iterator begin() const
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
bool lookup(uint256 hash, CTransaction &result) const
virtual void SetBestChain(const CBlockLocator &locator)=0
int64_t GetBlockValue(int nHeight, int64_t nFees)
const char * GetCommand() const
#define TRY_LOCK(cs, name)
void SetBackend(CCoinsView &viewIn)
void FileCommit(FILE *fileout)
void swap(CScriptCheck &check)
std::vector< CTxOut > vout
unsigned int nTransactions
uint256 getuint256() const
bool ReadReindexing(bool &fReindex)
An in-memory indexed chain of blocks.
unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime)
Calculate the minimum amount of work a received block needs, without knowing its direct parent...
bool IsPayToScriptHash() const
bool ReadLastBlockFile(int &nFile)
int GetDepthInMainChainINTERNAL(CBlockIndex *&pindexRet) const
std::map< COutPoint, CInPoint > mapNextTx
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CTransaction &txTo, unsigned int nIn, unsigned int flags, int nHashType)
std::pair< iterator, bool > insert(const key_type &x)
void AskFor(const CInv &inv)
virtual void Inventory(const uint256 &hash)=0
bool CorruptionPossible() const
void CheckForkWarningConditionsOnNewFork(CBlockIndex *pindexNewForkTip)
BloomFilter is a probabilistic filter which SPV clients provide so that we can filter the transaction...
void ThreadScriptCheck()
Run an instance of the script checking thread.
unsigned int GetSizeOfCompactSize(uint64_t nSize)
bool VerifyDB(int nCheckLevel, int nCheckDepth)
Verify consistency of the block and coin databases.
string GetWarnings(string strFor)
uint256 hashLastGetBlocksEnd
CBlockIndex * GetLastCheckpoint(const std::map< uint256, CBlockIndex * > &mapBlockIndex)
limitedmap< CInv, int64_t > mapAlreadyAskedFor(MAX_INV_SZ)
int64_t GetMinFee(const CTransaction &tx, unsigned int nBytes, bool fAllowFree, enum GetMinFee_mode mode)
bool AddToBlockIndex(CBlock &block, CValidationState &state, const CDiskBlockPos &pos)
bool WriteBlockIndex(const CDiskBlockIndex &blockindex)
bool MoneyRange(int64_t nValue)
Double ended buffer combining vector and stream-like interfaces.
Data structure that represents a partial merkle tree.
CCriticalSection cs_inventory
RAII-style controller object for a CCheckQueue that guarantees the passed queue is finished before co...
bool SeenLocal(const CService &addr)
vote for a local address
std::vector< CAddress > vAddrToSend
pruned version of CTransaction: only retains metadata and unspent transaction outputs ...
unsigned int GetSerializeSize(const T &obj)
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
void AddAddressKnown(const CAddress &addr)
void CheckForkWarningConditions()
bool LoadBlockIndexGuts()
std::string DateTimeStrFormat(const char *pszFormat, int64_t nTime)
void RandAddSeedPerfmon()
static int64_t nMinTxFee
Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) ...
virtual void SyncTransaction(const uint256 &hash, const CTransaction &tx, const CBlock *pblock)=0
void SetRecvVersion(int nVersionIn)
void RenameThread(const char *name)
const string strMessageMagic
CChain chainActive
The currently-connected chain of blocks.
Undo information for a CTxIn.
size_type count(const key_type &k) const
void PushInventory(const CInv &inv)
bool GetCoins(const uint256 &txid, CCoins &coins)
void PrintBlockTree()
Print the loaded block tree.
void insert(const uint256 &hash)
bool IsAvailable(unsigned int nPos) const
std::deque< CInv > vRecvGetData
int ScriptSigArgsExpected(txnouttype t, const std::vector< std::vector< unsigned char > > &vSolutions)
bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
bool Invalid(bool ret=false, unsigned char _chRejectCode=0, std::string _strRejectReason="")
std::set< uint256 > setKnown
uint256 BuildMerkleTree() const
int GetDepthInMainChain() const
FILE * OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
void UpdateTime(CBlockHeader &block, const CBlockIndex *pindexPrev)
bool VerifySignature(const CCoins &txFrom, const CTransaction &txTo, unsigned int nIn, unsigned int flags, int nHashType)
Verify a signature.
CBlockLocator GetLocator(const CBlockIndex *pindex=NULL) const
Return a CBlockLocator that refers to a block in this chain (by default the tip). ...
#define CLIENT_VERSION_IS_RELEASE
bool AcceptToMemoryPool(CTxMemPool &pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool *pfMissingInputs, bool fRejectInsaneFee)
(try to) add transaction to memory pool
#define AssertLockHeld(cs)
std::vector< CAddress > GetAddr()
bool SetLimit(uint64_t nPos=(uint64_t)(-1))
class CMainCleanup instance_of_cmaincleanup
int GetBlocksToMaturity() const
std::vector< uint256 > GetMerkleBranch(int nIndex) const
CBigNum & SetCompact(unsigned int nCompact)
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or NULL if none.
std::deque< CNetMessage > vRecvMsg
std::vector< uint256 > vHash
int Height() const
Return the maximal height in the chain.
Used to relay blocks as header + vector to filtered nodes.
CBlockTreeDB * pblocktree
Global variable that points to the active block tree (protected by cs_main)
unsigned int CalcTreeWidth(int height)
bool TruncateFile(FILE *file, unsigned int length)
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
int64_t GetAdjustedTime()
CBlockIndex * Next(const CBlockIndex *pindex) const
Find the successor of a block in this chain, or NULL if the given index is not found or is the tip...
void AddTimeData(const CNetAddr &ip, int64_t nTime)
void EraseOrphansFor(NodeId peer)
Access to the block database (blocks/index/)
CBlockHeader GetBlockHeader() const
string SanitizeString(const string &str)
unsigned int GetSerializeSize(char a, int, int=0)
Abstract view on the open txout dataset.
void PushGetBlocks(CNode *pnode, CBlockIndex *pindexBegin, uint256 hashEnd)
bool HaveCoins(const uint256 &txid)
bool IsInitialBlockDownload()
Check whether we are doing an initial block download (synchronizing from disk or network) ...
An input of a transaction.
An alert is a combination of a serialized CUnsignedAlert and a signature.
std::string itostr(int n)
void AddressCurrentlyConnected(const CService &addr)
mruset< CAddress > setAddrKnown
#define MESSAGE_START_SIZE
unsigned int GetSigOpCount(bool fAccurate) const
bool HaveInputs(const CTransaction &tx)
bool AcceptBlock(CBlock &block, CValidationState &state, CDiskBlockPos *dbp)
std::vector< CTxOut > vout
void UnloadBlockIndex()
Unload database information.
void RegisterNodeSignals(CNodeSignals &nodeSignals)
Register with a network node to receive its signals.
bool SendMessages(CNode *pto, bool fSendTrickle)
Send queued protocol messages to be sent to a give node.
CBlockHeader GetBlockHeader() const
CBlockIndex * pindexLastGetBlocksBegin
bool ActivateBestChain(CValidationState &state)
Find the best known block, and make it the tip of the block chain.
bool DoS(int level, bool ret=false, unsigned char chRejectCodeIn=0, std::string strRejectReasonIn="", bool corruptionIn=false)
int64_t GetMedianTime() const
C++ wrapper for BIGNUM (OpenSSL bignum)
mruset< CInv > setInventoryKnown
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length)
A CService with information about it as peer.
unsigned int SendBufferSize()
bool LoadBlockIndex()
Load the block tree and coins database from disk.
bool AcceptToMemoryPool(bool fLimitFree=true)
const CTxOut & GetOutputFor(const CTxIn &input)
void RelayTransaction(const CTransaction &tx, const uint256 &hash)
bool Solver(const CScript &scriptPubKey, txnouttype &typeRet, vector< vector< unsigned char > > &vSolutionsRet)
bool fSuccessfullyConnected
map< uint256, CAlert > mapAlerts
std::map< uint256, CTxMemPoolEntry > mapTx
bool WriteBlockFileInfo(int nFile, const CBlockFileInfo &fileinfo)
bool Error(std::string strRejectReasonIn="")
std::string ToString() const
void UpdateCoins(const CTransaction &tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight, const uint256 &txhash)
std::vector< uint256 > vMerkleTree
CCriticalSection cs_mapAlerts
uint256 TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector< uint256 > &vMatch)
int GetTotalBlocksEstimate()
void PrintExceptionContinue(std::exception *pex, const char *pszThread)
uint256 Hash(const T1 pbegin, const T1 pend)
An output of a transaction.
Used to marshal pointers into hashes for db storage.
bool WriteBlockToDisk(CBlock &block, CDiskBlockPos &pos)
Functions for disk access for blocks.
std::vector< uint256 > vHave
bool ConnectBlock(CBlock &block, CValidationState &state, CBlockIndex *pindex, CCoinsViewCache &view, bool fJustCheck)
bool EvalScript(vector< vector< unsigned char > > &stack, const CScript &script, const CTransaction &txTo, unsigned int nIn, unsigned int flags, int nHashType)
bool CheckBlock(int nHeight, const uint256 &hash)
bool WriteLastBlockFile(int nFile)
bool SetPos(uint64_t nPos)
Queue for verifications that have to be performed.
An outpoint - a combination of a transaction hash and an index n into its vout.
CCoinsViewCache * pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
void AddTransactionsUpdated(unsigned int n)
std::vector< CTxInUndo > vprevout
bool Abort(const std::string &msg)
std::string GetHex() const
boost::signals2::signal< bool(CNode *, bool)> SendMessages
double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks)
void RegisterWallet(CWalletInterface *pwalletIn)
Register a wallet to receive updates from core.
bool DisconnectBlock(CBlock &block, CValidationState &state, CBlockIndex *pindex, CCoinsViewCache &view, bool *pfClean)
Functions for validating blocks and updating the block tree.
map< uint256, COrphanTx > mapOrphanTransactions
bool ProcessMessages(CNode *pfrom)
Process protocol messages received from a given node.
void remove(const CTransaction &tx, std::list< CTransaction > &removed, bool fRecursive=false)
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats)
Get statistics from node state.
bool ReadFlag(const std::string &name, bool &fValue)
virtual const CBlock & GenesisBlock() const =0
boost::signals2::signal< bool(CNode *)> ProcessMessages
bool ReadBlockFileInfo(int nFile, CBlockFileInfo &fileinfo)
CBlockIndex * InsertBlockIndex(uint256 hash)
Create a new block index entry for a given block hash.
bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos)
Closure representing one script verification Note that this stores references to the spending transac...
void removeConflicts(const CTransaction &tx, std::list< CTransaction > &removed)
std::vector< bool > vBits
const uint256 & GetTxHash(unsigned int nIndex) const
std::string GetRejectReason() const
unsigned char GetRejectCode() const
bool IsStandardTx(const CTransaction &tx, string &reason)
CChain chainMostWork
The currently best known chain of headers (some of which may be invalid).
boost::signals2::signal< int()> GetHeight
unsigned int GetP2SHSigOpCount(const CTransaction &tx, CCoinsViewCache &inputs)
Count ECDSA signature operations in pay-to-script-hash inputs.
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or NULL if none.
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
Capture information about block/transaction validation.
void AddInventoryKnown(const CInv &inv)
bool CheckBlock(const CBlock &block, CValidationState &state, bool fCheckPOW, bool fCheckMerkleRoot)
bool IsReachable(enum Network net)
check whether a given network is one we can probably connect to
uint256 ExtractMatches(std::vector< uint256 > &vMatch)
void SyncWithWallets(const uint256 &hash, const CTransaction &tx, const CBlock *pblock)
Push an updated transaction to all registered wallets.
int64_t nTimeBestReceived
CCriticalSection cs_mapRelay
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos)
bool Spend(const COutPoint &out, CTxInUndo &undo)
CBlockIndex * pindexBestForkBase
double GetPriority(const CTransaction &tx, int nHeight)
bool IsRelevantAndUpdate(const CTransaction &tx, const uint256 &hash)
bool ProcessBlock(CValidationState &state, CNode *pfrom, CBlock *pblock, CDiskBlockPos *dbp)
Process an incoming block.
unsigned int GetLegacySigOpCount(const CTransaction &tx)
Count ECDSA signature operations the old-fashioned (pre-0.6) way.
The block chain is a tree shaped structure starting with the genesis block at the root...
const CChainParams & Params()
Return the currently selected parameters.
bool CheckInputs(const CTransaction &tx, CValidationState &state, CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, std::vector< CScriptCheck > *pvChecks)
Undo information for a CBlock.
Serialized script, used inside transaction inputs and outputs.
std::vector< CInv > vInventoryToSend
bool addUnchecked(const uint256 &hash, const CTxMemPoolEntry &entry)
Undo information for a CTransaction.
void * memcpy(void *a, const void *b, size_t c)
unsigned int nCoinCacheSize
std::string ToString() const
CBlockIndex * FindFork(const CBlockLocator &locator) const
Find the last common block between this chain and a locator.
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
void Misbehaving(NodeId pnode, int howmuch)
Increase a node's misbehavior score.
boost::signals2::signal< void()> NotifyBlocksChanged
Block chain changed.
bool exists(uint256 hash)
bool AbortNode(const std::string &strMessage)
Abort with a message.
#define LIMITED_STRING(obj, n)
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
static uint256 CheckMerkleBranch(uint256 hash, const std::vector< uint256 > &vMerkleBranch, int nIndex)
CBlockIndex * SetTip(CBlockIndex *pindex)
Set/initialize a chain with a given tip.
void UnregisterAllWallets()
Unregister all wallets from core.
bool WriteTxIndex(const std::vector< std::pair< uint256, CDiskTxPos > > &list)
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
Retrieve a transaction (from memory pool, or from disk, if possible)
CMerkleBlock(const CBlock &block, CBloomFilter &filter)
CAddress GetLocalAddress(const CNetAddr *paddrPeer)
static bool Ban(const CNetAddr &ip)
bool IsStandard(const CScript &scriptPubKey, txnouttype &whichType)
int64_t GetValueIn(const CTransaction &tx)
Amount of anoncoins coming in to a transaction Note that lightweight clients may not know anything be...
boost::signals2::signal< bool(const std::string &message, const std::string &caption, unsigned int style), boost::signals2::last_value< bool > > ThreadSafeMessageBox
Show message box.
static int64_t nMinRelayTxFee
Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) ...
virtual void UpdatedTransaction(const uint256 &hash)=0
virtual void EraseFromWallet(const uint256 &hash)=0
bool WriteFlag(const std::string &name, bool fValue)
void UnregisterWallet(CWalletInterface *pwalletIn)
Unregister a wallet from core.
bool SetCoins(const uint256 &txid, const CCoins &coins)
CBlockIndex * pindexBestForkTip
std::vector< CTransaction > vtx
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
bool SetBestBlock(const uint256 &hashBlock)
unsigned int GetCacheSize()
std::string ToString() const
CDiskBlockPos GetUndoPos() const
vector< unsigned char > vchBlock
The basic transaction that is broadcasted on the network and contained in blocks. ...
bool LoadExternalBlockFile(FILE *fileIn, CDiskBlockPos *dbp)
Import blocks from an external file.
Information about a peer.
static const int CURRENT_VERSION
std::vector< int > vHeightInFlight
bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown=false)
FILE * OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly)
Open an undo file (rev?????.dat)
boost::signals2::signal< void(NodeId)> FinalizeNode
CCoinsView that adds a memory cache for transactions to another CCoinsView.
bool CheckDiskSpace(uint64_t nAdditionalBytes)
Check whether enough disk space is available for an incoming block.
virtual void ResendWalletTransactions()=0
std::string ToString() const
Wrapper around a FILE* that implements a ring buffer to deserialize from.
int64_t GetBlockTime() const
bool InitBlockIndex()
Initialize a new block tree database + block data on disk.
std::vector< CTxUndo > vtxundo
multimap< uint256, COrphanBlock * > mapOrphanBlocksByPrev
map< uint256, COrphanBlock * > mapOrphanBlocks
bool HasCanonicalPushes() const
boost::signals2::signal< void(NodeId, const CNode *)> InitializeNode
int64_t GetMedianTimePast() const
CCoinsView that brings transactions from a memorypool into view.
map< uint256, CBlockIndex * > mapBlockIndex
std::multimap< int64_t, CInv > mapAskFor
unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock)
CCriticalSection cs_vNodes
map< uint256, set< uint256 > > mapOrphanTransactionsByPrev
bool CheckTransaction(const CTransaction &tx, CValidationState &state)
const uint256 & HashGenesisBlock() const
map< string, string > mapArgs
map< CInv, CDataStream > mapRelay
int atoi(const std::string &str)
uint256 GetBlockHash() const
const_iterator end() const
void runCommand(std::string strCommand)
void UnregisterNodeSignals(CNodeSignals &nodeSignals)
Unregister a network node.
uint256 CalcHash(int height, unsigned int pos, const std::vector< uint256 > &vTxid)
static bool IsSuperMajority(int minVersion, const CBlockIndex *pstart, unsigned int nRequired, unsigned int nToCheck)
Returns true if there are nRequired or more blocks of minVersion or above in the last nToCheck blocks...
void PushAddress(const CAddress &addr)
void Good(const CService &addr, int64_t nTime=GetAdjustedTime())
bool WriteBestInvalidWork(const CBigNum &bnBestInvalidWork)
const uint256 * phashBlock