aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--configure.ac2
-rw-r--r--src/bloom.h2
-rw-r--r--src/chainparams.cpp3
-rw-r--r--src/chainparamsbase.cpp3
-rw-r--r--src/db.cpp2
-rw-r--r--src/init.cpp12
-rw-r--r--src/key.h2
-rw-r--r--src/main.cpp112
-rw-r--r--src/main.h64
-rw-r--r--src/qt/clientmodel.cpp8
-rw-r--r--src/qt/splashscreen.cpp1
-rw-r--r--src/rpcblockchain.cpp10
-rw-r--r--src/test/multisig_tests.cpp4
-rw-r--r--src/txmempool.cpp7
-rw-r--r--src/ui_interface.h6
-rw-r--r--src/wallet.cpp99
-rw-r--r--src/wallet.h58
18 files changed, 202 insertions, 195 deletions
diff --git a/README.md b/README.md
index 081af80dcf..43be738c62 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
Bitcoin Core integration/staging tree
=====================================
+[![Build Status](https://travis-ci.org/bitcoin/bitcoin.svg?branch=master)](https://travis-ci.org/bitcoin/bitcoin)
+
https://www.bitcoin.org
Copyright (c) 2009-2014 Bitcoin Core Developers
diff --git a/configure.ac b/configure.ac
index 700f4ab709..5a2d7e8e41 100644
--- a/configure.ac
+++ b/configure.ac
@@ -577,7 +577,7 @@ CPPFLAGS="$TEMP_CPPFLAGS"
fi
if test x$boost_sleep != xyes; then
- AC_MSG_ERROR(No working boost sleep implementation found. If on ubuntu 13.10 with libboost1.54-all-dev remove libboost.1.54-all-dev and use libboost1.53-all-dev)
+ AC_MSG_ERROR(No working boost sleep implementation found.)
fi
AC_ARG_WITH([utils],
diff --git a/src/bloom.h b/src/bloom.h
index d0caf9e9fa..54d16d7126 100644
--- a/src/bloom.h
+++ b/src/bloom.h
@@ -60,7 +60,7 @@ public:
// It should generally always be a random value (and is largely only exposed for unit testing)
// nFlags should be one of the BLOOM_UPDATE_* enums (not _MASK)
CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweak, unsigned char nFlagsIn);
- CBloomFilter() : isFull(true) {}
+ CBloomFilter() : isFull(true), isEmpty(false), nHashFuncs(0), nTweak(0), nFlags(0) {}
IMPLEMENT_SERIALIZE
(
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index f32d4ed235..ce99f268f3 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -5,10 +5,11 @@
#include "chainparams.h"
-#include "assert.h"
#include "random.h"
#include "util.h"
+#include <assert.h>
+
#include <boost/assign/list_of.hpp>
using namespace std;
diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp
index 720e24c4a8..d1e19871c3 100644
--- a/src/chainparamsbase.cpp
+++ b/src/chainparamsbase.cpp
@@ -5,9 +5,10 @@
#include "chainparamsbase.h"
-#include "assert.h"
#include "util.h"
+#include <assert.h>
+
#include <boost/assign/list_of.hpp>
using namespace boost::assign;
diff --git a/src/db.cpp b/src/db.cpp
index 8c139843a1..23d2cc988d 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -227,10 +227,10 @@ CDB::CDB(const char *pszFile, const char* pszMode) :
pdb(NULL), activeTxn(NULL)
{
int ret;
+ fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
if (pszFile == NULL)
return;
- fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
bool fCreate = strchr(pszMode, 'c');
unsigned int nFlags = DB_THREAD;
if (fCreate)
diff --git a/src/init.cpp b/src/init.cpp
index e972413c4b..50ad2785dd 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -35,6 +35,7 @@
#include "compat/sanity.h"
#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/replace.hpp>
#include <boost/filesystem.hpp>
#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/thread.hpp>
@@ -369,6 +370,14 @@ std::string LicenseInfo()
"\n";
}
+static void BlockNotifyCallback(const uint256& hashNewTip)
+{
+ std::string strCmd = GetArg("-blocknotify", "");
+
+ boost::replace_all(strCmd, "%s", hashNewTip.GetHex());
+ boost::thread t(runCommand, strCmd); // thread runs free
+}
+
struct CImportingNow
{
CImportingNow() {
@@ -1185,6 +1194,9 @@ bool AppInit2(boost::thread_group& threadGroup)
#endif // !ENABLE_WALLET
// ********************************************************* Step 9: import blocks
+ if (mapArgs.count("-blocknotify"))
+ uiInterface.NotifyBlockTip.connect(BlockNotifyCallback);
+
// scan for better chains in the block chain database, that are not yet connected in the active best chain
CValidationState state;
if (!ActivateBestChain(state))
diff --git a/src/key.h b/src/key.h
index 11dc65de8c..1de83cc738 100644
--- a/src/key.h
+++ b/src/key.h
@@ -189,7 +189,7 @@ private:
public:
// Construct an invalid private key.
- CKey() : fValid(false) {
+ CKey() : fValid(false), fCompressed(false) {
LockObject(vch);
}
diff --git a/src/main.cpp b/src/main.cpp
index ddc37ea534..da00b4b531 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -732,53 +732,6 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in
return nSigOps;
}
-int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
-{
- AssertLockHeld(cs_main);
- CBlock blockTmp;
-
- if (pblock == NULL) {
- CCoins coins;
- if (pcoinsTip->GetCoins(GetHash(), coins)) {
- CBlockIndex *pindex = chainActive[coins.nHeight];
- if (pindex) {
- if (!ReadBlockFromDisk(blockTmp, pindex))
- return 0;
- pblock = &blockTmp;
- }
- }
- }
-
- if (pblock) {
- // Update the tx's hashBlock
- hashBlock = pblock->GetHash();
-
- // Locate the transaction
- for (nIndex = 0; nIndex < (int)pblock->vtx.size(); nIndex++)
- if (pblock->vtx[nIndex] == *(CTransaction*)this)
- break;
- if (nIndex == (int)pblock->vtx.size())
- {
- vMerkleBranch.clear();
- nIndex = -1;
- LogPrintf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");
- return 0;
- }
-
- // Fill in merkle branch
- vMerkleBranch = pblock->GetMerkleBranch(nIndex);
- }
-
- // Is the tx in a block that's in the main chain
- map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
- if (mi == mapBlockIndex.end())
- return 0;
- CBlockIndex* pindex = (*mi).second;
- if (!pindex || !chainActive.Contains(pindex))
- return 0;
-
- return chainActive.Height() - pindex->nHeight + 1;
-}
@@ -1028,58 +981,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
return true;
}
-
-int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const
-{
- if (hashBlock == 0 || nIndex == -1)
- return 0;
- AssertLockHeld(cs_main);
-
- // Find the block it claims to be in
- map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
- if (mi == mapBlockIndex.end())
- return 0;
- CBlockIndex* pindex = (*mi).second;
- if (!pindex || !chainActive.Contains(pindex))
- return 0;
-
- // Make sure the merkle branch connects to this block
- if (!fMerkleVerified)
- {
- if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
- return 0;
- fMerkleVerified = true;
- }
-
- pindexRet = pindex;
- return chainActive.Height() - pindex->nHeight + 1;
-}
-
-int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const
-{
- AssertLockHeld(cs_main);
- int nResult = GetDepthInMainChainINTERNAL(pindexRet);
- if (nResult == 0 && !mempool.exists(GetHash()))
- return -1; // Not in chain, not in mempool
-
- return nResult;
-}
-
-int CMerkleTx::GetBlocksToMaturity() const
-{
- if (!IsCoinBase())
- return 0;
- return max(0, (COINBASE_MATURITY+1) - GetDepthInMainChain());
-}
-
-
-bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectInsaneFee)
-{
- CValidationState state;
- return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectInsaneFee);
-}
-
-
// Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
{
@@ -1387,10 +1288,8 @@ void Misbehaving(NodeId pnode, int howmuch)
void static InvalidChainFound(CBlockIndex* pindexNew)
{
if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
- {
pindexBestInvalid = pindexNew;
- uiInterface.NotifyBlocksChanged();
- }
+
LogPrintf("InvalidChainFound: invalid block=%s height=%d log2_work=%.8g date=%s\n",
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
@@ -2151,18 +2050,15 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
uint256 hashNewTip = pindexNewTip->GetBlockHash();
// Relay inventory, but don't relay old inventory during initial block download.
int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
+ {
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
-
- std::string strCmd = GetArg("-blocknotify", "");
- if (!strCmd.empty()) {
- boost::replace_all(strCmd, "%s", hashNewTip.GetHex());
- boost::thread t(runCommand, strCmd); // thread runs free
}
+
+ uiInterface.NotifyBlockTip(hashNewTip);
}
- uiInterface.NotifyBlocksChanged();
} while(pindexMostWork != chainActive.Tip());
return true;
diff --git a/src/main.h b/src/main.h
index 0a1ff45460..9fe15d3aa3 100644
--- a/src/main.h
+++ b/src/main.h
@@ -328,7 +328,7 @@ private:
int nHashType;
public:
- CScriptCheck() {}
+ CScriptCheck(): ptxTo(0), nIn(0), nFlags(0), nHashType(0) {}
CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, int nHashTypeIn) :
scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey),
ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), nHashType(nHashTypeIn) { }
@@ -344,66 +344,6 @@ public:
}
};
-/** A transaction with a merkle branch linking it to the block chain. */
-class CMerkleTx : public CTransaction
-{
-private:
- int GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const;
-
-public:
- uint256 hashBlock;
- std::vector<uint256> vMerkleBranch;
- int nIndex;
-
- // memory only
- mutable bool fMerkleVerified;
-
-
- CMerkleTx()
- {
- Init();
- }
-
- CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
- {
- Init();
- }
-
- void Init()
- {
- hashBlock = 0;
- nIndex = -1;
- fMerkleVerified = false;
- }
-
-
- IMPLEMENT_SERIALIZE
- (
- nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
- nVersion = this->nVersion;
- READWRITE(hashBlock);
- READWRITE(vMerkleBranch);
- READWRITE(nIndex);
- )
-
-
- int SetMerkleBranch(const CBlock* pblock=NULL);
-
- // Return depth of transaction in blockchain:
- // -1 : not in blockchain, and not in memory pool (conflicted transaction)
- // 0 : in memory pool, waiting to be included in a block
- // >=1 : this many blocks deep in the main chain
- int GetDepthInMainChain(CBlockIndex* &pindexRet) const;
- int GetDepthInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
- bool IsInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; }
- int GetBlocksToMaturity() const;
- bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectInsaneFee=true);
-};
-
-
-
-
-
/** Data structure that represents a partial merkle tree.
*
* It respresents a subset of the txid's of a known block, in a way that
@@ -876,7 +816,7 @@ private:
unsigned char chRejectCode;
bool corruptionPossible;
public:
- CValidationState() : mode(MODE_VALID), nDoS(0), corruptionPossible(false) {}
+ CValidationState() : mode(MODE_VALID), nDoS(0), chRejectCode(0), corruptionPossible(false) {}
bool DoS(int level, bool ret = false,
unsigned char chRejectCodeIn=0, std::string strRejectReasonIn="",
bool corruptionIn=false) {
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 9c9ff5b3a1..738fb48ef8 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -209,12 +209,6 @@ static void ShowProgress(ClientModel *clientmodel, const std::string &title, int
Q_ARG(int, nProgress));
}
-static void NotifyBlocksChanged(ClientModel *clientmodel)
-{
- // This notification is too frequent. Don't trigger a signal.
- // Don't remove it, though, as it might be useful later.
-}
-
static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
{
// Too noisy: qDebug() << "NotifyNumConnectionsChanged : " + QString::number(newNumConnections);
@@ -234,7 +228,6 @@ void ClientModel::subscribeToCoreSignals()
{
// Connect signals to client
uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
- uiInterface.NotifyBlocksChanged.connect(boost::bind(NotifyBlocksChanged, this));
uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2));
}
@@ -243,7 +236,6 @@ void ClientModel::unsubscribeFromCoreSignals()
{
// Disconnect signals from client
uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
- uiInterface.NotifyBlocksChanged.disconnect(boost::bind(NotifyBlocksChanged, this));
uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2));
}
diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp
index 1162e2d87f..5dd110b36a 100644
--- a/src/qt/splashscreen.cpp
+++ b/src/qt/splashscreen.cpp
@@ -4,6 +4,7 @@
#include "splashscreen.h"
+#include "version.h"
#include "clientversion.h"
#include "init.h"
#include "ui_interface.h"
diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp
index 58cab14045..8a4b25cc54 100644
--- a/src/rpcblockchain.cpp
+++ b/src/rpcblockchain.cpp
@@ -54,9 +54,11 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex)
{
Object result;
result.push_back(Pair("hash", block.GetHash().GetHex()));
- CMerkleTx txGen(block.vtx[0]);
- txGen.SetMerkleBranch(&block);
- result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain()));
+ int confirmations = -1;
+ // Only report confirmations if the block is on the main chain
+ if (chainActive.Contains(blockindex))
+ confirmations = chainActive.Height() - blockindex->nHeight + 1;
+ result.push_back(Pair("confirmations", confirmations));
result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
result.push_back(Pair("height", blockindex->nHeight));
result.push_back(Pair("version", block.nVersion));
@@ -242,7 +244,7 @@ Value getblock(const Array& params, bool fHelp)
"\nResult (for verbose = true):\n"
"{\n"
" \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
- " \"confirmations\" : n, (numeric) The number of confirmations\n"
+ " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
" \"size\" : n, (numeric) The block size\n"
" \"height\" : n, (numeric) The block height or index\n"
" \"version\" : n, (numeric) The block version\n"
diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp
index 2a0466e928..02c6d095f2 100644
--- a/src/test/multisig_tests.cpp
+++ b/src/test/multisig_tests.cpp
@@ -164,9 +164,9 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
// Tests Solver() that returns lists of keys that are
// required to satisfy a ScriptPubKey
//
- // Also tests IsMine() and ExtractAddress()
+ // Also tests IsMine() and ExtractDestination()
//
- // Note: ExtractAddress for the multisignature transactions
+ // Note: ExtractDestination for the multisignature transactions
// always returns false for this release, even if you have
// one key that would satisfy an (a|b) or 2-of-3 keys needed
// to spend an escrow transaction.
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 8af1f1c91b..238d5bab16 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -11,7 +11,8 @@
using namespace std;
-CTxMemPoolEntry::CTxMemPoolEntry()
+CTxMemPoolEntry::CTxMemPoolEntry():
+ nFee(0), nTxSize(0), nTime(0), dPriority(0.0)
{
nHeight = MEMPOOL_HEIGHT;
}
@@ -345,7 +346,9 @@ public:
};
-CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) : minRelayFee(_minRelayFee)
+CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) :
+ nTransactionsUpdated(0),
+ minRelayFee(_minRelayFee)
{
// Sanity checks off by default for performance, because otherwise
// accepting transactions becomes O(N^2) where N is the number
diff --git a/src/ui_interface.h b/src/ui_interface.h
index b3df2b5a85..bbc8a203c9 100644
--- a/src/ui_interface.h
+++ b/src/ui_interface.h
@@ -78,9 +78,6 @@ public:
/** Translate a message to the native language of the user. */
boost::signals2::signal<std::string (const char* psz)> Translate;
- /** Block chain changed. */
- boost::signals2::signal<void ()> NotifyBlocksChanged;
-
/** Number of network connections changed. */
boost::signals2::signal<void (int newNumConnections)> NotifyNumConnectionsChanged;
@@ -95,6 +92,9 @@ public:
/** Show progress e.g. for verifychain */
boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;
+
+ /** New block has been accepted */
+ boost::signals2::signal<void (const uint256& hash)> NotifyBlockTip;
};
extern CClientUIInterface uiInterface;
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 786b2f6a92..18a5b3971c 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -2194,3 +2194,102 @@ CWalletKey::CWalletKey(int64_t nExpires)
nTimeCreated = (nExpires ? GetTime() : 0);
nTimeExpires = nExpires;
}
+
+int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
+{
+ AssertLockHeld(cs_main);
+ CBlock blockTmp;
+
+ if (pblock == NULL) {
+ CCoins coins;
+ if (pcoinsTip->GetCoins(GetHash(), coins)) {
+ CBlockIndex *pindex = chainActive[coins.nHeight];
+ if (pindex) {
+ if (!ReadBlockFromDisk(blockTmp, pindex))
+ return 0;
+ pblock = &blockTmp;
+ }
+ }
+ }
+
+ if (pblock) {
+ // Update the tx's hashBlock
+ hashBlock = pblock->GetHash();
+
+ // Locate the transaction
+ for (nIndex = 0; nIndex < (int)pblock->vtx.size(); nIndex++)
+ if (pblock->vtx[nIndex] == *(CTransaction*)this)
+ break;
+ if (nIndex == (int)pblock->vtx.size())
+ {
+ vMerkleBranch.clear();
+ nIndex = -1;
+ LogPrintf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");
+ return 0;
+ }
+
+ // Fill in merkle branch
+ vMerkleBranch = pblock->GetMerkleBranch(nIndex);
+ }
+
+ // Is the tx in a block that's in the main chain
+ map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
+ if (mi == mapBlockIndex.end())
+ return 0;
+ CBlockIndex* pindex = (*mi).second;
+ if (!pindex || !chainActive.Contains(pindex))
+ return 0;
+
+ return chainActive.Height() - pindex->nHeight + 1;
+}
+
+int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const
+{
+ if (hashBlock == 0 || nIndex == -1)
+ return 0;
+ AssertLockHeld(cs_main);
+
+ // Find the block it claims to be in
+ map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
+ if (mi == mapBlockIndex.end())
+ return 0;
+ CBlockIndex* pindex = (*mi).second;
+ if (!pindex || !chainActive.Contains(pindex))
+ return 0;
+
+ // Make sure the merkle branch connects to this block
+ if (!fMerkleVerified)
+ {
+ if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
+ return 0;
+ fMerkleVerified = true;
+ }
+
+ pindexRet = pindex;
+ return chainActive.Height() - pindex->nHeight + 1;
+}
+
+int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const
+{
+ AssertLockHeld(cs_main);
+ int nResult = GetDepthInMainChainINTERNAL(pindexRet);
+ if (nResult == 0 && !mempool.exists(GetHash()))
+ return -1; // Not in chain, not in mempool
+
+ return nResult;
+}
+
+int CMerkleTx::GetBlocksToMaturity() const
+{
+ if (!IsCoinBase())
+ return 0;
+ return max(0, (COINBASE_MATURITY+1) - GetDepthInMainChain());
+}
+
+
+bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectInsaneFee)
+{
+ CValidationState state;
+ return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectInsaneFee);
+}
+
diff --git a/src/wallet.h b/src/wallet.h
index 052da24609..544b4f5bfb 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -457,6 +457,63 @@ struct COutputEntry
int vout;
};
+/** A transaction with a merkle branch linking it to the block chain. */
+class CMerkleTx : public CTransaction
+{
+private:
+ int GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const;
+
+public:
+ uint256 hashBlock;
+ std::vector<uint256> vMerkleBranch;
+ int nIndex;
+
+ // memory only
+ mutable bool fMerkleVerified;
+
+
+ CMerkleTx()
+ {
+ Init();
+ }
+
+ CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
+ {
+ Init();
+ }
+
+ void Init()
+ {
+ hashBlock = 0;
+ nIndex = -1;
+ fMerkleVerified = false;
+ }
+
+
+ IMPLEMENT_SERIALIZE
+ (
+ nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
+ nVersion = this->nVersion;
+ READWRITE(hashBlock);
+ READWRITE(vMerkleBranch);
+ READWRITE(nIndex);
+ )
+
+
+ int SetMerkleBranch(const CBlock* pblock=NULL);
+
+ // Return depth of transaction in blockchain:
+ // -1 : not in blockchain, and not in memory pool (conflicted transaction)
+ // 0 : in memory pool, waiting to be included in a block
+ // >=1 : this many blocks deep in the main chain
+ int GetDepthInMainChain(CBlockIndex* &pindexRet) const;
+ int GetDepthInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
+ bool IsInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; }
+ int GetBlocksToMaturity() const;
+ bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectInsaneFee=true);
+};
+
+
/** A transaction with a bunch of additional info that only the owner cares about.
* It includes any unrecorded transactions needed to link it back to the block chain.
*/
@@ -905,6 +962,7 @@ public:
strOtherAccount.clear();
strComment.clear();
nOrderPos = -1;
+ nEntryNo = 0;
}
IMPLEMENT_SERIALIZE