Initial merge

This commit is contained in:
jl777
2017-03-30 04:35:16 +03:00
633 changed files with 11230 additions and 184263 deletions

View File

@@ -57,6 +57,7 @@ int64_t nTimeBestReceived = 0;
CWaitableCriticalSection csBestBlock;
CConditionVariable cvBlockChange;
int nScriptCheckThreads = 0;
bool fExperimentalMode = false;
bool fImporting = false;
bool fReindex = false;
bool fTxIndex = false;
@@ -79,9 +80,9 @@ struct COrphanTx {
CTransaction tx;
NodeId fromPeer;
};
map<uint256, COrphanTx> mapOrphanTransactions;
map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
void EraseOrphansFor(NodeId peer);
map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main);;
map<uint256, set<uint256> > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);;
void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/**
* Returns true if there are nRequired or more blocks of minVersion or above
@@ -573,7 +574,7 @@ CBlockTreeDB *pblocktree = NULL;
// mapOrphanTransactions
//
bool AddOrphanTx(const CTransaction& tx, NodeId peer)
bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
uint256 hash = tx.GetHash();
if (mapOrphanTransactions.count(hash))
@@ -603,7 +604,7 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer)
return true;
}
void static EraseOrphanTx(uint256 hash)
void static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
if (it == mapOrphanTransactions.end())
@@ -637,7 +638,7 @@ void EraseOrphansFor(NodeId peer)
}
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
unsigned int nEvicted = 0;
while (mapOrphanTransactions.size() > nMaxOrphans)
@@ -776,7 +777,7 @@ bool CheckFinalTx(const CTransaction &tx, int flags)
/**
* Check transaction inputs to mitigate two
* potential denial-of-service attacks:
*
*
* 1. scriptSigs with extra data stuffed into them,
* not consumed by scriptPubKey (or P2SH script)
* 2. P2SH scripts with a crazy number of expensive
@@ -1753,13 +1754,16 @@ bool CScriptCheck::operator()() {
return true;
}
bool NonContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams, std::vector<CScriptCheck> *pvChecks)
int GetSpendHeight(const CCoinsViewCache& inputs)
{
if (!tx.IsCoinBase())
{
if (pvChecks)
pvChecks->reserve(tx.vin.size());
LOCK(cs_main);
CBlockIndex* pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
return pindexPrev->nHeight + 1;
}
namespace Consensus {
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, const Consensus::Params& consensusParams)
{
// This doesn't trigger the DoS code on purpose; if it did, it would make it easier
// for an attacker to attempt to split the network.
if (!inputs.HaveInputs(tx))
@@ -1778,6 +1782,13 @@ bool NonContextualCheckInputs(const CTransaction& tx, CValidationState &state, c
assert(coins);
if (coins->IsCoinBase()) {
// Ensure that coinbases are matured
if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
return state.Invalid(
error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
}
// Ensure that coinbases cannot be spent to transparent outputs
// Disabled on regtest
if (fCoinbaseEnforcedProtectionEnabled &&
@@ -1830,7 +1841,20 @@ bool NonContextualCheckInputs(const CTransaction& tx, CValidationState &state, c
if (!MoneyRange(nFees))
return state.DoS(100, error("CheckInputs(): nFees out of range"),
REJECT_INVALID, "bad-txns-fee-outofrange");
//fprintf(stderr,"nFees %.8f\n",(double)nFees/COIN);
return true;
}
}// namespace Consensus
bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams, std::vector<CScriptCheck> *pvChecks)
{
if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs), consensusParams))
return false;
if (!tx.IsCoinBase())
{
if (pvChecks)
pvChecks->reserve(tx.vin.size());
// The first loop above does all the inexpensive checks.
// Only if ALL inputs pass do we perform expensive ECDSA signature checks.
// Helps prevent CPU exhaustion attacks.
@@ -1879,6 +1903,8 @@ bool NonContextualCheckInputs(const CTransaction& tx, CValidationState &state, c
}
bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams, std::vector<CScriptCheck> *pvChecks)
/*bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams, std::vector<CScriptCheck> *pvChecks)
{
if (!NonContextualCheckInputs(tx, state, inputs, fScriptChecks, flags, cacheStore, consensusParams, pvChecks)) {
fprintf(stderr,"ContextualCheckInputs failure.0\n");
@@ -1914,7 +1940,7 @@ bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, cons
}
return true;
}
}*/
namespace {
@@ -2207,8 +2233,20 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
{
const CChainParams& chainparams = Params();
AssertLockHeld(cs_main);
/*<<<<<<< HEA
// Check it again in case a previous version let a bad block in
bool fExpensiveChecks = (!fCheckpointsEnabled || pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));
=======
*/
bool fExpensiveChecks = true;
if (fCheckpointsEnabled) {
CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
if (pindexLastCheckpoint && pindexLastCheckpoint->GetAncestor(pindex->nHeight) == pindex) {
// This block is an ancestor of a checkpoint: disable script checks
fExpensiveChecks = false;
}
}
//>>>>>>> zcash/master
auto verifier = libzcash::ProofVerifier::Strict();
auto disabledVerifier = libzcash::ProofVerifier::Disabled();
@@ -2228,6 +2266,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
// Before the genesis block, there was an empty tree
ZCIncrementalMerkleTree tree;
pindex->hashAnchor = tree.root();
// The genesis block contained no JoinSplits
pindex->hashAnchorEnd = pindex->hashAnchor;
}
return true;
}
@@ -2345,6 +2385,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
}
view.PushAnchor(tree);
if (!fJustCheck) {
pindex->hashAnchorEnd = tree.root();
}
blockundo.old_tree_root = old_tree_root;
int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
@@ -2560,7 +2603,7 @@ void static UpdateTip(CBlockIndex *pindexNew) {
LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)CBlock::CURRENT_VERSION);
if (nUpgraded > 100/2)
{
// strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user:
// strMiscWarning is read by GetWarnings(), called by the JSON-RPC code to warn the user:
strMiscWarning = _("Warning: This version is obsolete; upgrade required!");
CAlert::Notify(strMiscWarning, true);
fWarned = true;
@@ -2627,7 +2670,7 @@ static int64_t nTimeFlush = 0;
static int64_t nTimeChainState = 0;
static int64_t nTimePostConnect = 0;
/**
/**
* Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
* corresponding to pindexNew, to bypass loading it again from disk.
*/
@@ -2652,7 +2695,6 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
{
CCoinsViewCache view(pcoinsTip);
CInv inv(MSG_BLOCK, pindexNew->GetBlockHash());
bool rv = ConnectBlock(*pblock, state, pindexNew, view);
GetMainSignals().BlockChecked(*pblock, state);
if (!rv) {
@@ -2660,7 +2702,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
InvalidBlockFound(pindexNew, state);
return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
}
mapBlockSource.erase(inv.hash);
mapBlockSource.erase(pindexNew->GetBlockHash());
nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
assert(view.Flush());
@@ -2893,6 +2935,7 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
}
// Notify external listeners about the new tip.
GetMainSignals().UpdatedBlockTip(pindexNewTip);
uiInterface.NotifyBlockTip(hashNewTip);
} //else fprintf(stderr,"initial download skips propagation\n");
} while(pindexMostWork != chainActive.Tip());
@@ -3275,7 +3318,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
return state.Invalid(error("%s: block's timestamp is too early", __func__),
REJECT_INVALID, "time-too-old");
if(fCheckpointsEnabled)
if (fCheckpointsEnabled)
{
// Check that the block chain matches the known block chain up to a checkpoint
if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
@@ -3794,11 +3837,27 @@ bool static LoadBlockIndexDB()
pblocktree->ReadFlag("txindex", fTxIndex);
LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
// Fill in-memory data
BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
{
CBlockIndex* pindex = item.second;
// - This relationship will always be true even if pprev has multiple
// children, because hashAnchor is technically a property of pprev,
// not its children.
// - This will miss chain tips; we handle the best tip below, and other
// tips will be handled by ConnectTip during a re-org.
if (pindex->pprev) {
pindex->pprev->hashAnchorEnd = pindex->hashAnchor;
}
}
// Load pointer to end of best chain
BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
if (it == mapBlockIndex.end())
return true;
chainActive.SetTip(it->second);
// Set hashAnchorEnd for the end of best chain
it->second->hashAnchorEnd = pcoinsTip->GetBestAnchor();
PruneBlockIndexCandidates();
@@ -4285,7 +4344,7 @@ void static CheckBlockIndex()
// CAlert
//
string GetWarnings(string strFor)
std::string GetWarnings(const std::string& strFor)
{
int nPriority = 0;
string strStatusBar;
@@ -4353,7 +4412,7 @@ string GetWarnings(string strFor)
//
bool static AlreadyHave(const CInv& inv)
bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
switch (inv.type)
{
@@ -4522,7 +4581,6 @@ void static ProcessGetData(CNode* pfrom)
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
{
const CChainParams& chainparams = Params();
RandAddSeedPerfmon();
LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
{
@@ -4608,9 +4666,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CAddress addr = GetLocalAddress(&pfrom->addr);
if (addr.IsRoutable())
{
LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
pfrom->PushAddress(addr);
} else if (IsPeerAddrLocalGood(pfrom)) {
addr.SetIP(pfrom->addrLocal);
LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
pfrom->PushAddress(addr);
}
}