revise leveldb parser. add chainstate parser.
This commit is contained in:
parent
b740185c69
commit
6970f8a593
|
@ -607,6 +607,11 @@ read_addr(const std::string addr, const int64_t blockheight, const int64_t block
|
||||||
static bool
|
static bool
|
||||||
get_block_by_tx(const std::string itxhash, CBlock& rcblock, CBlockIndex **rcblock_index);
|
get_block_by_tx(const std::string itxhash, CBlock& rcblock, CBlockIndex **rcblock_index);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static bool
|
||||||
|
get_block_by_tx_unspent(const std::string itxhash, CBlock& rcblock, CBlockIndex **rcblock_index);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions
|
* Functions
|
||||||
*/
|
*/
|
||||||
|
@ -6209,6 +6214,12 @@ jstx_to_ctx(const Local<Object> jstx, CTransaction& ctx_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_LDB_ADDR
|
#if USE_LDB_ADDR
|
||||||
|
|
||||||
|
/**
|
||||||
|
LevelDB Parser
|
||||||
|
DB: blocks/blk/revXXXXX.dat
|
||||||
|
*/
|
||||||
|
|
||||||
static ctx_list *
|
static ctx_list *
|
||||||
read_addr(const std::string addr, const int64_t blockheight, const int64_t blocktime) {
|
read_addr(const std::string addr, const int64_t blockheight, const int64_t blocktime) {
|
||||||
ctx_list *head = new ctx_list();
|
ctx_list *head = new ctx_list();
|
||||||
|
@ -6235,7 +6246,8 @@ read_addr(const std::string addr, const int64_t blockheight, const int64_t block
|
||||||
// Blockchain Index Structure:
|
// Blockchain Index Structure:
|
||||||
// http://bitcoin.stackexchange.com/questions/28168
|
// http://bitcoin.stackexchange.com/questions/28168
|
||||||
|
|
||||||
// File info record structure (Key: 4-byte file number)
|
// File info record structure
|
||||||
|
// 'f' + 4-byte file number
|
||||||
// Number of blocks stored in block file
|
// Number of blocks stored in block file
|
||||||
// Size of block file: blocks/blkXXXXX.dat
|
// Size of block file: blocks/blkXXXXX.dat
|
||||||
// Size of undo file: blocks/revXXXXX.dat
|
// Size of undo file: blocks/revXXXXX.dat
|
||||||
|
@ -6245,31 +6257,35 @@ read_addr(const std::string addr, const int64_t blockheight, const int64_t block
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last block file number used structure (Key: no key)
|
// Last block file number used structure
|
||||||
|
// 'l'
|
||||||
// 4-byte file number
|
// 4-byte file number
|
||||||
if (type == 'l') {
|
if (type == 'l') {
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reindexing structure (Key: no key)
|
// Reindexing structure
|
||||||
|
// 'R'
|
||||||
// 1-byte Boolean (1 if reindexing)
|
// 1-byte Boolean (1 if reindexing)
|
||||||
if (type == 'R') {
|
if (type == 'R') {
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flags structure (Key: 1-byte flag name + flag name string)
|
// Flags structure
|
||||||
|
// 'F' + 1-byte flag name + flag name string
|
||||||
// 1-byte Boolean (key may be `txindex` if transaction index is enabled)
|
// 1-byte Boolean (key may be `txindex` if transaction index is enabled)
|
||||||
if (type == 'F') {
|
if (type == 'F') {
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block Structure:
|
// Block Structure:
|
||||||
// CBlockHeader - headers
|
// 'b' + 32-byte block hash
|
||||||
// nHeight
|
// The block header
|
||||||
// nTx
|
// The block height
|
||||||
// validation state
|
// The number of transactions
|
||||||
// CDiskBlockPos - block file and pos
|
// The block validation state
|
||||||
// CDiskBlockPos - undo file and pos
|
// The block file and pos
|
||||||
|
// The undo file and pos
|
||||||
if (type == 'b') {
|
if (type == 'b') {
|
||||||
leveldb::Slice slValue = pcursor->value();
|
leveldb::Slice slValue = pcursor->value();
|
||||||
|
|
||||||
|
@ -6278,17 +6294,41 @@ read_addr(const std::string addr, const int64_t blockheight, const int64_t block
|
||||||
uint256 blockhash;
|
uint256 blockhash;
|
||||||
ssKey >> blockhash;
|
ssKey >> blockhash;
|
||||||
|
|
||||||
|
// class CBlockIndex {
|
||||||
|
// const uint256* phashBlock;
|
||||||
|
// CBlockIndex* pprev;
|
||||||
|
// CBlockIndex* pskip;
|
||||||
|
// int nHeight;
|
||||||
|
// int nFile;
|
||||||
|
// unsigned int nDataPos;
|
||||||
|
// unsigned int nUndoPos;
|
||||||
|
// uint256 nChainWork;
|
||||||
|
// unsigned int nTx;
|
||||||
|
// unsigned int nChainTx;
|
||||||
|
// unsigned int nStatus;
|
||||||
|
// int nVersion;
|
||||||
|
// uint256 hashMerkleRoot;
|
||||||
|
// unsigned int nTime;
|
||||||
|
// unsigned int nBits;
|
||||||
|
// unsigned int nNonce;
|
||||||
|
// uint32_t nSequenceId;
|
||||||
|
// };
|
||||||
|
// class CDiskBlockIndex : public CBlockIndex {
|
||||||
|
// uint256 hashPrev;
|
||||||
|
// };
|
||||||
|
|
||||||
CDiskBlockIndex index;
|
CDiskBlockIndex index;
|
||||||
ssValue >> index;
|
ssValue >> index;
|
||||||
|
|
||||||
//if (blockheight != -1 && index.nHeight < blockheight) {
|
|
||||||
// goto next;
|
|
||||||
//}
|
|
||||||
|
|
||||||
if (blocktime != -1 && index.GetBlockTime() < blocktime) {
|
if (blocktime != -1 && index.GetBlockTime() < blocktime) {
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// struct CDiskBlockPos {
|
||||||
|
// int nFile;
|
||||||
|
// unsigned int nPos;
|
||||||
|
// };
|
||||||
|
|
||||||
CDiskBlockPos blockPos;
|
CDiskBlockPos blockPos;
|
||||||
blockPos.nFile = index.nFile;
|
blockPos.nFile = index.nFile;
|
||||||
blockPos.nPos = index.nDataPos;
|
blockPos.nPos = index.nDataPos;
|
||||||
|
@ -6353,9 +6393,10 @@ read_addr(const std::string addr, const int64_t blockheight, const int64_t block
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transaction Structure:
|
// Transaction Structure:
|
||||||
// CDiskBlockPos.nFile - block file
|
// 't' + 32-byte tx hash
|
||||||
// CDiskBlockPos.nPos - block pos
|
// Which block file the tx is stored in
|
||||||
// CDiskTxPos.nTxOffset - offset from top of block
|
// Which offset in the block file the tx resides
|
||||||
|
// The offset from the top of the block containing the tx
|
||||||
if (type == 't') {
|
if (type == 't') {
|
||||||
leveldb::Slice slValue = pcursor->value();
|
leveldb::Slice slValue = pcursor->value();
|
||||||
|
|
||||||
|
@ -6364,16 +6405,13 @@ read_addr(const std::string addr, const int64_t blockheight, const int64_t block
|
||||||
uint256 txhash;
|
uint256 txhash;
|
||||||
ssKey >> txhash;
|
ssKey >> txhash;
|
||||||
|
|
||||||
// CDiskBlockPos blockPos;
|
// struct CDiskBlockPos {
|
||||||
// ssValue >> blockPos.nFile;
|
// int nFile;
|
||||||
// ssValue >> blockPos.nPos;
|
// unsigned int nPos;
|
||||||
|
// };
|
||||||
// CDiskTxPos txPos;
|
// struct CDiskTxPos : public CDiskBlockPos {
|
||||||
// // ssValue >> txPos.nFile;
|
// unsigned int nTxOffset;
|
||||||
// // ssValue >> txPos.nPos;
|
// };
|
||||||
// txPos.nFile = blockPos.nFile;
|
|
||||||
// txPos.nPos = blockPos.nPos;
|
|
||||||
// ssValue >> txPos.nTxOffset;
|
|
||||||
|
|
||||||
CDiskTxPos txPos;
|
CDiskTxPos txPos;
|
||||||
ssValue >> txPos;
|
ssValue >> txPos;
|
||||||
|
@ -6453,13 +6491,9 @@ read_addr(const std::string addr, const int64_t blockheight, const int64_t block
|
||||||
next:
|
next:
|
||||||
pcursor->Next();
|
pcursor->Next();
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
//pcursor->Next();
|
|
||||||
//continue;
|
|
||||||
leveldb::Slice lastKey = pcursor->key();
|
|
||||||
std::string lastKeyHex = HexStr(lastKey.ToString());
|
|
||||||
head->err_msg = std::string(e.what()
|
head->err_msg = std::string(e.what()
|
||||||
+ std::string(" : Deserialize error. Key: ")
|
+ std::string(" : Deserialize error. Key: ")
|
||||||
+ lastKeyHex);
|
+ pcursor->key().ToString());
|
||||||
delete pcursor;
|
delete pcursor;
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
@ -6476,6 +6510,11 @@ error:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
LevelDB Parser
|
||||||
|
DB: blocks/blk/revXXXXX.dat
|
||||||
|
*/
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
get_block_by_tx(const std::string itxhash, CBlock& rcblock, CBlockIndex **rcblock_index) {
|
get_block_by_tx(const std::string itxhash, CBlock& rcblock, CBlockIndex **rcblock_index) {
|
||||||
leveldb::Iterator* pcursor = pblocktree->pdb->NewIterator(pblocktree->iteroptions);
|
leveldb::Iterator* pcursor = pblocktree->pdb->NewIterator(pblocktree->iteroptions);
|
||||||
|
@ -6492,6 +6531,14 @@ get_block_by_tx(const std::string itxhash, CBlock& rcblock, CBlockIndex **rcbloc
|
||||||
char type;
|
char type;
|
||||||
ssKey >> type;
|
ssKey >> type;
|
||||||
|
|
||||||
|
// Blockchain Index Structure:
|
||||||
|
// http://bitcoin.stackexchange.com/questions/28168
|
||||||
|
|
||||||
|
// Transaction Structure:
|
||||||
|
// 't' + 32-byte tx hash
|
||||||
|
// Which block file the tx is stored in
|
||||||
|
// Which offset in the block file the tx resides
|
||||||
|
// The offset from the top of the block containing the tx
|
||||||
if (type == 't') {
|
if (type == 't') {
|
||||||
uint256 txhash;
|
uint256 txhash;
|
||||||
ssKey >> txhash;
|
ssKey >> txhash;
|
||||||
|
@ -6500,16 +6547,13 @@ get_block_by_tx(const std::string itxhash, CBlock& rcblock, CBlockIndex **rcbloc
|
||||||
|
|
||||||
CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION);
|
CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION);
|
||||||
|
|
||||||
// CDiskBlockPos blockPos;
|
// struct CDiskBlockPos {
|
||||||
// ssValue >> blockPos.nFile;
|
// int nFile;
|
||||||
// ssValue >> blockPos.nPos;
|
// unsigned int nPos;
|
||||||
|
// };
|
||||||
// CDiskTxPos txPos;
|
// struct CDiskTxPos : public CDiskBlockPos {
|
||||||
// // ssValue >> txPos.nFile;
|
// unsigned int nTxOffset;
|
||||||
// // ssValue >> txPos.nPos;
|
// };
|
||||||
// txPos.nFile = blockPos.nFile;
|
|
||||||
// txPos.nPos = blockPos.nPos;
|
|
||||||
// ssValue >> txPos.nTxOffset;
|
|
||||||
|
|
||||||
CDiskTxPos txPos;
|
CDiskTxPos txPos;
|
||||||
ssValue >> txPos;
|
ssValue >> txPos;
|
||||||
|
@ -6559,6 +6603,96 @@ error:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/**
|
||||||
|
LevelDB Parser
|
||||||
|
DB: chainstate*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// XXX static - will not work:
|
||||||
|
// extern CCoinsViewDB *pcoinsdbview;
|
||||||
|
|
||||||
|
static bool
|
||||||
|
get_block_by_tx_unspent(const std::string itxhash, CBlock& rcblock, CBlockIndex **rcblock_index) {
|
||||||
|
// XXX Will not work - db is protected property:
|
||||||
|
CCoinsViewDB *pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
|
||||||
|
bool fReindex = GetBoolArg("-reindex", false);
|
||||||
|
size_t nCoinDBCache = (GetArg("-dbcache", nDefaultDbCache) << 20) / 2;
|
||||||
|
nCoinCacheSize = nCoinDBCache / 300;
|
||||||
|
boost::scoped_ptr<leveldb::Iterator> pcursor(const_cast<CLevelDBWrapper*>(&pcoinsdbview->db)->NewIterator());
|
||||||
|
|
||||||
|
pcursor->SeekToFirst();
|
||||||
|
|
||||||
|
while (pcursor->Valid()) {
|
||||||
|
boost::this_thread::interruption_point();
|
||||||
|
try {
|
||||||
|
leveldb::Slice slKey = pcursor->key();
|
||||||
|
|
||||||
|
CDataStream ssKey(slKey.data(), slKey.data() + slKey.size(), SER_DISK, CLIENT_VERSION);
|
||||||
|
|
||||||
|
char type;
|
||||||
|
ssKey >> type;
|
||||||
|
|
||||||
|
// Blockchain Index Structure:
|
||||||
|
// http://bitcoin.stackexchange.com/questions/28168
|
||||||
|
|
||||||
|
// Unspent Output Transaction Structure:
|
||||||
|
// 'c' + 32-byte tx hash
|
||||||
|
// Version of the tx
|
||||||
|
// Whether transaction was a coinbase
|
||||||
|
// Which height block contains the tx
|
||||||
|
// Which outputs of the tx are unspent
|
||||||
|
// The scriptPubKey and amount for these unspent outputs
|
||||||
|
if (type == 'c') {
|
||||||
|
uint256 txhash;
|
||||||
|
ssKey >> txhash;
|
||||||
|
if (txhash.GetHex() == itxhash) {
|
||||||
|
leveldb::Slice slValue = pcursor->value();
|
||||||
|
CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION);
|
||||||
|
|
||||||
|
// class CCoins {
|
||||||
|
// bool fCoinBase;
|
||||||
|
// std::vector<CTxOut> vout;
|
||||||
|
// int nHeight;
|
||||||
|
// int nVersion;
|
||||||
|
// }
|
||||||
|
|
||||||
|
CCoins coins;
|
||||||
|
ssValue >> coins;
|
||||||
|
|
||||||
|
CBlockIndex* pblockindex = chainActive[coins.nHeight];
|
||||||
|
CBlock cblock;
|
||||||
|
if (ReadBlockFromDisk(cblock, pblockindex)) {
|
||||||
|
*rcblock_index = pblockindex;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unspent Output Block Hash Structure
|
||||||
|
// 'B' + 32-byte block hash: The block hash up to which the db represents
|
||||||
|
// the unspent tx outputs
|
||||||
|
if (type == 'B') {
|
||||||
|
uint256 blockhash;
|
||||||
|
ssKey >> blockhash;
|
||||||
|
// CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION);
|
||||||
|
// uint256 blockhash;
|
||||||
|
// ssValue >> blockhash;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcursor->Next();
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int64_t
|
static int64_t
|
||||||
SatoshiFromAmount(const CAmount& amount) {
|
SatoshiFromAmount(const CAmount& amount) {
|
||||||
return (int64_t)amount;
|
return (int64_t)amount;
|
||||||
|
|
Loading…
Reference in New Issue