diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/bloom.h | 2 | ||||
-rw-r--r-- | src/chainparams.cpp | 3 | ||||
-rw-r--r-- | src/chainparamsbase.cpp | 3 | ||||
-rw-r--r-- | src/db.cpp | 2 | ||||
-rw-r--r-- | src/init.cpp | 12 | ||||
-rw-r--r-- | src/key.h | 2 | ||||
-rw-r--r-- | src/main.cpp | 112 | ||||
-rw-r--r-- | src/main.h | 64 | ||||
-rw-r--r-- | src/qt/clientmodel.cpp | 8 | ||||
-rw-r--r-- | src/qt/splashscreen.cpp | 1 | ||||
-rw-r--r-- | src/rpcblockchain.cpp | 10 | ||||
-rw-r--r-- | src/test/multisig_tests.cpp | 4 | ||||
-rw-r--r-- | src/txmempool.cpp | 7 | ||||
-rw-r--r-- | src/ui_interface.h | 6 | ||||
-rw-r--r-- | src/wallet.cpp | 99 | ||||
-rw-r--r-- | src/wallet.h | 58 |
18 files changed, 202 insertions, 195 deletions
@@ -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)) @@ -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 |