diff --git a/src/main.cpp b/src/main.cpp index bd77e00d6e..786310e723 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2405,6 +2405,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin assert(block.vtx.size() == 1); std::vector > vPos; + std::multimap > mLocksCreated; const CTransaction& tx = block.vtx[0]; CTxUndo undoDummy; @@ -2412,10 +2413,16 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size())); vPos.push_back(std::make_pair(tx.GetHash(), pos)); + for (unsigned int i = 0; i < tx.vout.size(); i++) { + CTxOut txout= tx.vout[i]; + if (txout.scriptPubKey.IsWithdrawLock() && txout.nValue.IsAmount()) + mLocksCreated.insert(std::make_pair(txout.scriptPubKey.GetWithdrawLockGenesisHash(), std::make_pair(COutPoint(tx.GetHash(), i), txout.nValue.GetAmount()))); + } if (fTxIndex) if (!pblocktree->WriteTxIndex(vPos)) return AbortNode(state, "Failed to write transaction index"); + pblocktree->WriteLocksCreated(mLocksCreated); view.SetBestBlock(pindex->GetBlockHash()); } @@ -2515,6 +2522,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size())); std::vector > vPos; vPos.reserve(block.vtx.size()); + std::multimap > mLocksCreated; blockundo.vtxundo.reserve(block.vtx.size() - 1); std::vector txdata; txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated @@ -2590,6 +2598,12 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin vPos.push_back(std::make_pair(tx.GetHash(), pos)); pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); + + for (unsigned int j = 0; j < tx.vout.size(); j++) { + CTxOut txout = tx.vout[j]; + if (txout.scriptPubKey.IsWithdrawLock() && txout.nValue.IsAmount()) + mLocksCreated.insert(std::make_pair(txout.scriptPubKey.GetWithdrawLockGenesisHash(), std::make_pair(COutPoint(tx.GetHash(), j), txout.nValue.GetAmount()))); + } } int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2; LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime3 - nTime2), 0.001 * (nTime3 - nTime2) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime3 - nTime2) / (nInputs-1), nTimeConnect * 0.000001); @@ -2634,6 +2648,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (!pblocktree->WriteTxIndex(vPos)) return AbortNode(state, "Failed to write transaction index"); + pblocktree->WriteLocksCreated(mLocksCreated); + // add this block to the view's block chain view.SetBestBlock(pindex->GetBlockHash()); diff --git a/src/txdb.cpp b/src/txdb.cpp index f9ca63083e..ba2fad086e 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -19,6 +19,7 @@ using namespace std; static const char DB_COINS = 'c'; static const char DB_BLOCK_FILES = 'f'; static const char DB_TXINDEX = 't'; +static const char DB_LOCKS = 'k'; static const char DB_BLOCK_INDEX = 'b'; static const char DB_WITHDRAW_FLAG = 'w'; @@ -171,6 +172,36 @@ bool CBlockTreeDB::WriteTxIndex(const std::vector return WriteBatch(batch); } +bool CBlockTreeDB::WriteLocksCreated(const std::multimap > &map) { + if (map.size() == 0) + return true; + + uint256 prevGenesis; + CDBBatch batch(*this); + std::vector > vLocks; + for (std::multimap >::const_iterator it=map.begin(); it!=map.end(); it++) { + if (prevGenesis != it->first || it == map.begin()) { + if (it != map.begin()) + batch.Write(make_pair(DB_LOCKS, prevGenesis), vLocks); + prevGenesis = it->first; + if (!Read(make_pair(DB_LOCKS, it->first), vLocks)) + vLocks.clear(); + } + vLocks.push_back(it->second); + } + batch.Write(make_pair(DB_LOCKS, prevGenesis), vLocks); + return WriteBatch(batch); +} + + +bool CBlockTreeDB::ReadLocksCreated(const uint256 &genesisHash, std::vector > &vLocks) { + return Read(make_pair(DB_LOCKS, genesisHash), vLocks); +} + +bool CBlockTreeDB::ReWriteLocksCreated(const uint256 &genesisHash, const std::vector > &vLocks) { + return Write(make_pair(DB_LOCKS, genesisHash), vLocks); +} + bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) { return Write(std::make_pair(DB_FLAG, name), fValue ? '1' : '0'); } diff --git a/src/txdb.h b/src/txdb.h index 3af4d0736d..32c52f3ad8 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -116,6 +116,9 @@ public: bool ReadReindexing(bool &fReindex); bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos); bool WriteTxIndex(const std::vector > &list); + bool WriteLocksCreated(const std::multimap > &list); + bool ReadLocksCreated(const uint256 &genesisHash, std::vector > &vLocks); + bool ReWriteLocksCreated(const uint256 &genesisHash, const std::vector > &vLocks); bool WriteFlag(const std::string &name, bool fValue); bool ReadFlag(const std::string &name, bool &fValue); bool LoadBlockIndexGuts(boost::function insertBlockIndex);