Add withdraw-locks-creation tracking in txdb

This commit is contained in:
Matt Corallo 2016-03-13 16:31:58 -04:00 committed by Gregory Sanders
parent 9bfc2c813d
commit 3914ec30cf
3 changed files with 50 additions and 0 deletions

View file

@ -2405,6 +2405,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
assert(block.vtx.size() == 1);
std::vector<std::pair<uint256, CDiskTxPos> > vPos;
std::multimap<uint256, std::pair<COutPoint, CAmount> > 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<std::pair<uint256, CDiskTxPos> > vPos;
vPos.reserve(block.vtx.size());
std::multimap<uint256, std::pair<COutPoint, CAmount> > mLocksCreated;
blockundo.vtxundo.reserve(block.vtx.size() - 1);
std::vector<PrecomputedTransactionData> 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());

View file

@ -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<std::pair<uint256, CDiskTxPos>
return WriteBatch(batch);
}
bool CBlockTreeDB::WriteLocksCreated(const std::multimap<uint256, std::pair<COutPoint, CAmount> > &map) {
if (map.size() == 0)
return true;
uint256 prevGenesis;
CDBBatch batch(*this);
std::vector<std::pair<COutPoint, CAmount> > vLocks;
for (std::multimap<uint256, std::pair<COutPoint, CAmount> >::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<std::pair<COutPoint, CAmount> > &vLocks) {
return Read(make_pair(DB_LOCKS, genesisHash), vLocks);
}
bool CBlockTreeDB::ReWriteLocksCreated(const uint256 &genesisHash, const std::vector<std::pair<COutPoint, CAmount> > &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');
}

View file

@ -116,6 +116,9 @@ public:
bool ReadReindexing(bool &fReindex);
bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos);
bool WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> > &list);
bool WriteLocksCreated(const std::multimap<uint256, std::pair<COutPoint, CAmount> > &list);
bool ReadLocksCreated(const uint256 &genesisHash, std::vector<std::pair<COutPoint, CAmount> > &vLocks);
bool ReWriteLocksCreated(const uint256 &genesisHash, const std::vector<std::pair<COutPoint, CAmount> > &vLocks);
bool WriteFlag(const std::string &name, bool fValue);
bool ReadFlag(const std::string &name, bool &fValue);
bool LoadBlockIndexGuts(boost::function<CBlockIndex*(const uint256&)> insertBlockIndex);