aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp83
1 files changed, 67 insertions, 16 deletions
diff --git a/src/main.cpp b/src/main.cpp
index b2873f2a10..2d8ac0c9bc 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2013 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -17,7 +17,6 @@
#include "ui_interface.h"
#include "util.h"
-#include <inttypes.h>
#include <sstream>
#include <boost/algorithm/string/replace.hpp>
@@ -53,7 +52,7 @@ unsigned int nCoinCacheSize = 5000;
/** Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) */
int64_t CTransaction::nMinTxFee = 10000; // Override with -mintxfee
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying) */
-int64_t CTransaction::nMinRelayTxFee = 10000;
+int64_t CTransaction::nMinRelayTxFee = 1000;
static CMedianFilter<int> cPeerBlockCounts(8, 0); // Amount of blocks that other nodes claim to have
@@ -525,6 +524,10 @@ bool IsStandardTx(const CTransaction& tx, string& reason)
reason = "scriptsig-not-pushonly";
return false;
}
+ if (!txin.scriptSig.HasCanonicalPushes()) {
+ reason = "scriptsig-non-canonical-push";
+ return false;
+ }
}
unsigned int nDataOut = 0;
@@ -902,7 +905,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Don't accept it if it can't get into a block
int64_t txMinFee = GetMinFee(tx, nSize, true, GMF_RELAY);
if (fLimitFree && nFees < txMinFee)
- return state.DoS(0, error("AcceptToMemoryPool : not enough fees %s, %"PRId64" < %"PRId64,
+ return state.DoS(0, error("AcceptToMemoryPool : not enough fees %s, %d < %d",
hash.ToString(), nFees, txMinFee),
REJECT_INSUFFICIENTFEE, "insufficient fee");
@@ -931,7 +934,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
}
if (fRejectInsaneFee && nFees > CTransaction::nMinRelayTxFee * 10000)
- return error("AcceptToMemoryPool: : insane fees %s, %"PRId64" > %"PRId64,
+ return error("AcceptToMemoryPool: : insane fees %s, %d > %d",
hash.ToString(),
nFees, CTransaction::nMinRelayTxFee * 10000);
@@ -951,7 +954,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
}
-int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const
+int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const
{
if (hashBlock == 0 || nIndex == -1)
return 0;
@@ -976,6 +979,14 @@ int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const
return chainActive.Height() - pindex->nHeight + 1;
}
+int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const
+{
+ int nResult = GetDepthInMainChainINTERNAL(pindexRet);
+ if (nResult == 0 && !mempool.exists(GetHash()))
+ return -1; // Not in chain, not in mempool
+
+ return nResult;
+}
int CMerkleTx::GetBlocksToMaturity() const
{
@@ -1240,7 +1251,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
// Limit adjustment step
int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
- LogPrintf(" nActualTimespan = %"PRId64" before bounds\n", nActualTimespan);
+ LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
if (nActualTimespan < nTargetTimespan/4)
nActualTimespan = nTargetTimespan/4;
if (nActualTimespan > nTargetTimespan*4)
@@ -1257,7 +1268,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
/// debug print
LogPrintf("GetNextWorkRequired RETARGET\n");
- LogPrintf("nTargetTimespan = %"PRId64" nActualTimespan = %"PRId64"\n", nTargetTimespan, nActualTimespan);
+ LogPrintf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
LogPrintf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString());
LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString());
@@ -1810,7 +1821,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
if (block.vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees))
return state.DoS(100,
- error("ConnectBlock() : coinbase pays too much (actual=%"PRId64" vs limit=%"PRId64")",
+ error("ConnectBlock() : coinbase pays too much (actual=%d vs limit=%d)",
block.vtx[0].GetValueOut(), GetBlockValue(pindex->nHeight, nFees)),
REJECT_INVALID, "bad-cb-amount");
@@ -1939,17 +1950,23 @@ bool static DisconnectTip(CValidationState &state) {
// Write the chain state to disk, if necessary.
if (!WriteChainState(state))
return false;
- // Ressurect mempool transactions from the disconnected block.
+ // Resurrect mempool transactions from the disconnected block.
BOOST_FOREACH(const CTransaction &tx, block.vtx) {
// ignore validation errors in resurrected transactions
+ list<CTransaction> removed;
CValidationState stateDummy;
if (!tx.IsCoinBase())
if (!AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
- mempool.remove(tx, true);
+ mempool.remove(tx, removed, true);
}
mempool.check(pcoinsTip);
// Update chainActive and related variables.
UpdateTip(pindexDelete->pprev);
+ // Let wallets know transactions went from 1-confirmed to
+ // 0-confirmed or conflicted:
+ BOOST_FOREACH(const CTransaction &tx, block.vtx) {
+ SyncWithWallets(tx.GetHash(), tx, NULL);
+ }
return true;
}
@@ -1980,13 +1997,24 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew) {
if (!WriteChainState(state))
return false;
// Remove conflicting transactions from the mempool.
+ list<CTransaction> txConflicted;
BOOST_FOREACH(const CTransaction &tx, block.vtx) {
- mempool.remove(tx);
- mempool.removeConflicts(tx);
+ list<CTransaction> unused;
+ mempool.remove(tx, unused);
+ mempool.removeConflicts(tx, txConflicted);
}
mempool.check(pcoinsTip);
// Update chainActive & related variables.
UpdateTip(pindexNew);
+ // Tell wallet about transactions that went from mempool
+ // to conflicted:
+ BOOST_FOREACH(const CTransaction &tx, txConflicted) {
+ SyncWithWallets(tx.GetHash(), tx, NULL);
+ }
+ // ... and about transactions that got confirmed:
+ BOOST_FOREACH(const CTransaction &tx, block.vtx) {
+ SyncWithWallets(tx.GetHash(), tx, &block);
+ }
return true;
}
@@ -2347,6 +2375,11 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CDiskBlockPos* dbp)
return state.DoS(100, error("AcceptBlock() : rejected by checkpoint lock-in at %d", nHeight),
REJECT_CHECKPOINT, "checkpoint mismatch");
+ // Don't accept any forks from the main chain prior to last checkpoint
+ CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
+ if (pcheckpoint && nHeight < pcheckpoint->nHeight)
+ return state.DoS(100, error("AcceptBlock() : forked chain older than last checkpoint (height %d)", nHeight));
+
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
if (block.nVersion < 2)
{
@@ -3078,7 +3111,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
AbortNode(_("Error: system error: ") + e.what());
}
if (nLoaded > 0)
- LogPrintf("Loaded %i blocks from external file in %"PRId64"ms\n", nLoaded, GetTimeMillis() - nStart);
+ LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
return nLoaded > 0;
}
@@ -3201,10 +3234,28 @@ void static ProcessGetData(CNode* pfrom)
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
{
- // Send block from disk
+ bool send = false;
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash);
if (mi != mapBlockIndex.end())
{
+ // If the requested block is at a height below our last
+ // checkpoint, only serve it if it's in the checkpointed chain
+ int nHeight = mi->second->nHeight;
+ CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
+ if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
+ if (!chainActive.Contains(mi->second))
+ {
+ LogPrintf("ProcessGetData(): ignoring request for old block that isn't in the main chain\n");
+ } else {
+ send = true;
+ }
+ } else {
+ send = true;
+ }
+ }
+ if (send)
+ {
+ // Send block from disk
CBlock block;
ReadBlockFromDisk(block, (*mi).second);
if (inv.type == MSG_BLOCK)
@@ -3839,7 +3890,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
}
if (!(sProblem.empty())) {
- LogPrint("net", "pong %s %s: %s, %"PRIx64" expected, %"PRIx64" received, %"PRIszu" bytes\n",
+ LogPrint("net", "pong %s %s: %s, %x expected, %x received, %"PRIszu" bytes\n",
pfrom->addr.ToString(),
pfrom->cleanSubVer,
sProblem,