Auto merge of #3857 - LarryRuane:3708-timestampindex, r=bitcartel
add TimestampIndex changes needed for bitcore block explorer Addresses #3708, follow-on to #3849, no tests yet. This is the third of 3 indices that we're adding.
This commit is contained in:
commit
244922d527
|
@ -199,6 +199,7 @@ BITCOIN_CORE_H = \
|
|||
sync.h \
|
||||
threadsafety.h \
|
||||
timedata.h \
|
||||
timestampindex.h \
|
||||
tinyformat.h \
|
||||
torcontrol.h \
|
||||
transaction_builder.h \
|
||||
|
|
26
src/main.cpp
26
src/main.cpp
|
@ -70,6 +70,7 @@ bool fTxIndex = false;
|
|||
bool fInsightExplorer = false; // insightexplorer
|
||||
bool fAddressIndex = false; // insightexplorer
|
||||
bool fSpentIndex = false; // insightexplorer
|
||||
bool fTimestampIndex = false; // insightexplorer
|
||||
bool fHavePruned = false;
|
||||
bool fPruneMode = false;
|
||||
bool fIsBareMultisigStd = true;
|
||||
|
@ -2801,7 +2802,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||
if (!pblocktree->WriteTxIndex(vPos))
|
||||
return AbortNode(state, "Failed to write transaction index");
|
||||
|
||||
// insightexplorer
|
||||
// START insightexplorer
|
||||
if (fAddressIndex) {
|
||||
if (!pblocktree->WriteAddressIndex(addressIndex)) {
|
||||
return AbortNode(state, "Failed to write address index");
|
||||
|
@ -2810,12 +2811,32 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||
return AbortNode(state, "Failed to write address unspent index");
|
||||
}
|
||||
}
|
||||
// insightexplorer
|
||||
if (fSpentIndex) {
|
||||
if (!pblocktree->UpdateSpentIndex(spentIndex)) {
|
||||
return AbortNode(state, "Failed to write spent index");
|
||||
}
|
||||
}
|
||||
if (fTimestampIndex) {
|
||||
unsigned int logicalTS = pindex->nTime;
|
||||
unsigned int prevLogicalTS = 0;
|
||||
|
||||
// retrieve logical timestamp of the previous block
|
||||
if (pindex->pprev)
|
||||
if (!pblocktree->ReadTimestampBlockIndex(pindex->pprev->GetBlockHash(), prevLogicalTS))
|
||||
LogPrintf("%s: Failed to read previous block's logical timestamp\n", __func__);
|
||||
|
||||
if (logicalTS <= prevLogicalTS) {
|
||||
logicalTS = prevLogicalTS + 1;
|
||||
LogPrintf("%s: Previous logical timestamp is newer Actual[%d] prevLogical[%d] Logical[%d]\n", __func__, pindex->nTime, prevLogicalTS, logicalTS);
|
||||
}
|
||||
|
||||
if (!pblocktree->WriteTimestampIndex(CTimestampIndexKey(logicalTS, pindex->GetBlockHash())))
|
||||
return AbortNode(state, "Failed to write timestamp index");
|
||||
|
||||
if (!pblocktree->WriteTimestampBlockIndex(CTimestampBlockIndexKey(pindex->GetBlockHash()), CTimestampBlockIndexValue(logicalTS)))
|
||||
return AbortNode(state, "Failed to write blockhash index");
|
||||
}
|
||||
// END insightexplorer
|
||||
|
||||
// add this block to the view's block chain
|
||||
view.SetBestBlock(pindex->GetBlockHash());
|
||||
|
@ -4715,6 +4736,7 @@ bool InitBlockIndex() {
|
|||
pblocktree->WriteFlag("insightexplorer", fInsightExplorer);
|
||||
fAddressIndex = fInsightExplorer;
|
||||
fSpentIndex = fInsightExplorer;
|
||||
fTimestampIndex = fInsightExplorer;
|
||||
|
||||
LogPrintf("Initializing databases...\n");
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "uint256.h"
|
||||
#include "addressindex.h"
|
||||
#include "spentindex.h"
|
||||
#include "timestampindex.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_TIMESTAMPINDEX_H
|
||||
#define BITCOIN_TIMESTAMPINDEX_H
|
||||
|
||||
#include "uint256.h"
|
||||
|
||||
struct CTimestampIndexIteratorKey {
|
||||
unsigned int timestamp;
|
||||
|
||||
size_t GetSerializeSize(int nType, int nVersion) const {
|
||||
return 4;
|
||||
}
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s) const {
|
||||
ser_writedata32be(s, timestamp);
|
||||
}
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s) {
|
||||
timestamp = ser_readdata32be(s);
|
||||
}
|
||||
|
||||
CTimestampIndexIteratorKey(unsigned int time) {
|
||||
timestamp = time;
|
||||
}
|
||||
|
||||
CTimestampIndexIteratorKey() {
|
||||
SetNull();
|
||||
}
|
||||
|
||||
void SetNull() {
|
||||
timestamp = 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct CTimestampIndexKey {
|
||||
unsigned int timestamp;
|
||||
uint256 blockHash;
|
||||
|
||||
size_t GetSerializeSize(int nType, int nVersion) const {
|
||||
return 36;
|
||||
}
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s) const {
|
||||
ser_writedata32be(s, timestamp);
|
||||
blockHash.Serialize(s);
|
||||
}
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s) {
|
||||
timestamp = ser_readdata32be(s);
|
||||
blockHash.Unserialize(s);
|
||||
}
|
||||
|
||||
CTimestampIndexKey(unsigned int time, uint256 hash) {
|
||||
timestamp = time;
|
||||
blockHash = hash;
|
||||
}
|
||||
|
||||
CTimestampIndexKey() {
|
||||
SetNull();
|
||||
}
|
||||
|
||||
void SetNull() {
|
||||
timestamp = 0;
|
||||
blockHash.SetNull();
|
||||
}
|
||||
};
|
||||
|
||||
struct CTimestampBlockIndexKey {
|
||||
uint256 blockHash;
|
||||
|
||||
size_t GetSerializeSize(int nType, int nVersion) const {
|
||||
return 32;
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s) const {
|
||||
blockHash.Serialize(s);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s) {
|
||||
blockHash.Unserialize(s);
|
||||
}
|
||||
|
||||
CTimestampBlockIndexKey(uint256 hash) {
|
||||
blockHash = hash;
|
||||
}
|
||||
|
||||
CTimestampBlockIndexKey() {
|
||||
SetNull();
|
||||
}
|
||||
|
||||
void SetNull() {
|
||||
blockHash.SetNull();
|
||||
}
|
||||
};
|
||||
|
||||
struct CTimestampBlockIndexValue {
|
||||
unsigned int ltimestamp;
|
||||
size_t GetSerializeSize(int nType, int nVersion) const {
|
||||
return 4;
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s) const {
|
||||
ser_writedata32be(s, ltimestamp);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s) {
|
||||
ltimestamp = ser_readdata32be(s);
|
||||
}
|
||||
|
||||
CTimestampBlockIndexValue (unsigned int time) {
|
||||
ltimestamp = time;
|
||||
}
|
||||
|
||||
CTimestampBlockIndexValue() {
|
||||
SetNull();
|
||||
}
|
||||
|
||||
void SetNull() {
|
||||
ltimestamp = 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BITCOIN_TIMESTAMPINDEX_H
|
52
src/txdb.cpp
52
src/txdb.cpp
|
@ -39,6 +39,8 @@ static const char DB_LAST_BLOCK = 'l';
|
|||
static const char DB_ADDRESSINDEX = 'd';
|
||||
static const char DB_ADDRESSUNSPENTINDEX = 'u';
|
||||
static const char DB_SPENTINDEX = 'p';
|
||||
static const char DB_TIMESTAMPINDEX = 'T';
|
||||
static const char DB_BLOCKHASHINDEX = 'h';
|
||||
|
||||
CCoinsViewDB::CCoinsViewDB(std::string dbName, size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / dbName, nCacheSize, fMemory, fWipe) {
|
||||
}
|
||||
|
@ -390,6 +392,56 @@ bool CBlockTreeDB::UpdateSpentIndex(const std::vector<CSpentIndexDbEntry> &vect)
|
|||
}
|
||||
return WriteBatch(batch);
|
||||
}
|
||||
|
||||
bool CBlockTreeDB::WriteTimestampIndex(const CTimestampIndexKey ×tampIndex) {
|
||||
CDBBatch batch(*this);
|
||||
batch.Write(make_pair(DB_TIMESTAMPINDEX, timestampIndex), 0);
|
||||
return WriteBatch(batch);
|
||||
}
|
||||
|
||||
bool CBlockTreeDB::ReadTimestampIndex(const unsigned int &high, const unsigned int &low,
|
||||
const bool fActiveOnly, std::vector<std::pair<uint256, unsigned int> > &hashes)
|
||||
{
|
||||
boost::scoped_ptr<CDBIterator> pcursor(NewIterator());
|
||||
|
||||
pcursor->Seek(make_pair(DB_TIMESTAMPINDEX, CTimestampIndexIteratorKey(low)));
|
||||
|
||||
while (pcursor->Valid()) {
|
||||
boost::this_thread::interruption_point();
|
||||
std::pair<char, CTimestampIndexKey> key;
|
||||
if (!(pcursor->GetKey(key) && key.first == DB_TIMESTAMPINDEX && key.second.timestamp < high)) {
|
||||
break;
|
||||
}
|
||||
if (fActiveOnly) {
|
||||
CBlockIndex* pblockindex = mapBlockIndex[key.second.blockHash];
|
||||
if (chainActive.Contains(pblockindex)) {
|
||||
hashes.push_back(std::make_pair(key.second.blockHash, key.second.timestamp));
|
||||
}
|
||||
} else {
|
||||
hashes.push_back(std::make_pair(key.second.blockHash, key.second.timestamp));
|
||||
}
|
||||
pcursor->Next();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBlockTreeDB::WriteTimestampBlockIndex(const CTimestampBlockIndexKey &blockhashIndex,
|
||||
const CTimestampBlockIndexValue &logicalts)
|
||||
{
|
||||
CDBBatch batch(*this);
|
||||
batch.Write(make_pair(DB_BLOCKHASHINDEX, blockhashIndex), logicalts);
|
||||
return WriteBatch(batch);
|
||||
}
|
||||
|
||||
bool CBlockTreeDB::ReadTimestampBlockIndex(const uint256 &hash, unsigned int <imestamp)
|
||||
{
|
||||
CTimestampBlockIndexValue(lts);
|
||||
if (!Read(std::make_pair(DB_BLOCKHASHINDEX, hash), lts))
|
||||
return false;
|
||||
|
||||
ltimestamp = lts.ltimestamp;
|
||||
return true;
|
||||
}
|
||||
// END insightexplorer
|
||||
|
||||
bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) {
|
||||
|
|
10
src/txdb.h
10
src/txdb.h
|
@ -26,6 +26,10 @@ struct CAddressIndexIteratorKey;
|
|||
struct CAddressIndexIteratorHeightKey;
|
||||
struct CSpentIndexKey;
|
||||
struct CSpentIndexValue;
|
||||
struct CTimestampIndexKey;
|
||||
struct CTimestampIndexIteratorKey;
|
||||
struct CTimestampBlockIndexKey;
|
||||
struct CTimestampBlockIndexValue;
|
||||
|
||||
typedef std::pair<CAddressUnspentKey, CAddressUnspentValue> CAddressUnspentDbEntry;
|
||||
typedef std::pair<CAddressIndexKey, CAmount> CAddressIndexDbEntry;
|
||||
|
@ -94,6 +98,12 @@ public:
|
|||
bool ReadAddressIndex(uint160 addressHash, int type, std::vector<CAddressIndexDbEntry> &addressIndex, int start = 0, int end = 0);
|
||||
bool ReadSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value);
|
||||
bool UpdateSpentIndex(const std::vector<CSpentIndexDbEntry> &vect);
|
||||
bool WriteTimestampIndex(const CTimestampIndexKey ×tampIndex);
|
||||
bool ReadTimestampIndex(const unsigned int &high, const unsigned int &low,
|
||||
const bool fActiveOnly, std::vector<std::pair<uint256, unsigned int> > &vect);
|
||||
bool WriteTimestampBlockIndex(const CTimestampBlockIndexKey &blockhashIndex,
|
||||
const CTimestampBlockIndexValue &logicalts);
|
||||
bool ReadTimestampBlockIndex(const uint256 &hash, unsigned int &logicalTS);
|
||||
// END insightexplorer
|
||||
|
||||
bool WriteFlag(const std::string &name, bool fValue);
|
||||
|
|
Loading…
Reference in New Issue