parse leveldb correctly.
This commit is contained in:
parent
5ad347c892
commit
628b20b982
@ -187,7 +187,7 @@ using namespace v8;
|
|||||||
#define EMPTY ("\\x01")
|
#define EMPTY ("\\x01")
|
||||||
|
|
||||||
// LevelDB options
|
// LevelDB options
|
||||||
#define USE_LDB_ADDR 1
|
#define USE_LDB_ADDR 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node.js Exposed Function Templates
|
* Node.js Exposed Function Templates
|
||||||
@ -5885,15 +5885,49 @@ read_addr(const std::string addr) {
|
|||||||
|
|
||||||
while (pcursor->Valid()) {
|
while (pcursor->Valid()) {
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
char *k_debug = NULL;
|
|
||||||
leveldb::Slice lastKey = pcursor->key();
|
|
||||||
leveldb::Slice lastVal = pcursor->value();
|
|
||||||
try {
|
try {
|
||||||
leveldb::Slice slKey = pcursor->key();
|
leveldb::Slice slKey = pcursor->key();
|
||||||
|
|
||||||
CDataStream ssKey(slKey.data(), slKey.data() + slKey.size(), SER_DISK, CLIENT_VERSION);
|
CDataStream ssKey(slKey.data(), slKey.data() + slKey.size(), SER_DISK, CLIENT_VERSION);
|
||||||
|
|
||||||
char type;
|
char type;
|
||||||
ssKey >> type;
|
ssKey >> type;
|
||||||
|
|
||||||
|
// Blockchain Index Structure:
|
||||||
|
// http://bitcoin.stackexchange.com/questions/28168
|
||||||
|
|
||||||
|
// File info record structure (Key: 4-byte file number)
|
||||||
|
// Number of blocks stored in block file
|
||||||
|
// Size of block file: blocks/blkXXXXX.dat
|
||||||
|
// Size of undo file: blocks/revXXXXX.dat
|
||||||
|
// Low and high heights of blocks stored in file
|
||||||
|
// Low and high timestamps of blocks stored in file
|
||||||
|
if (type == 'f') {
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last block file number used structure (Key: no key)
|
||||||
|
// 4-byte file number
|
||||||
|
if (type == 'l') {
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reindexing structure (Key: no key)
|
||||||
|
// 1-byte Boolean (1 if reindexing)
|
||||||
|
if (type == 'R') {
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flags structure (Key: 1-byte flag name + flag name string)
|
||||||
|
// 1-byte Boolean (key may be `txindex` if transaction index is enabled)
|
||||||
|
if (type == 'F') {
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block Structure:
|
||||||
|
// CBlockHeader - headers
|
||||||
|
// CDiskBlockPos - block file and pos
|
||||||
|
// CDiskBlockPos - undo file and pos
|
||||||
if (type == 'b') {
|
if (type == 'b') {
|
||||||
leveldb::Slice slValue = pcursor->value();
|
leveldb::Slice slValue = pcursor->value();
|
||||||
|
|
||||||
@ -5905,19 +5939,51 @@ read_addr(const std::string addr) {
|
|||||||
CBlockHeader header;
|
CBlockHeader header;
|
||||||
ssValue >> header;
|
ssValue >> header;
|
||||||
|
|
||||||
|
// XXX This is not being parsed right. Check math/logic.
|
||||||
CDiskBlockPos blockPos;
|
CDiskBlockPos blockPos;
|
||||||
ssValue >> blockPos;
|
ssValue >> blockPos;
|
||||||
|
|
||||||
CDiskBlockPos undoPos;
|
// CDiskBlockPos undoPos;
|
||||||
ssValue >> undoPos;
|
// ssValue >> undoPos;
|
||||||
|
|
||||||
CBlock cblock;
|
CBlock cblock;
|
||||||
if (ReadBlockFromDisk(cblock, blockPos)) {
|
|
||||||
k_debug = strdup(blockhash.GetHex().c_str());
|
|
||||||
|
|
||||||
BOOST_FOREACH(const CTransaction& ctx, cblock.vtx) {
|
if (!ReadBlockFromDisk(cblock, blockPos)) {
|
||||||
BOOST_FOREACH(const CTxIn& txin, ctx.vin) {
|
goto found;
|
||||||
if (txin.scriptSig.ToString() != expectedScriptSig.ToString()) {
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH(const CTransaction& ctx, cblock.vtx) {
|
||||||
|
BOOST_FOREACH(const CTxIn& txin, ctx.vin) {
|
||||||
|
if (txin.scriptSig.ToString() != expectedScriptSig.ToString()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cur == NULL) {
|
||||||
|
head->ctx = ctx;
|
||||||
|
head->blockhash = blockhash;
|
||||||
|
head->next = NULL;
|
||||||
|
cur = head;
|
||||||
|
} else {
|
||||||
|
ctx_list *item = new ctx_list();
|
||||||
|
item->ctx = ctx;
|
||||||
|
item->blockhash = blockhash;
|
||||||
|
item->next = NULL;
|
||||||
|
cur->next = item;
|
||||||
|
cur = item;
|
||||||
|
}
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int vo = 0; vo < ctx.vout.size(); vo++) {
|
||||||
|
const CTxOut& txout = ctx.vout[vo];
|
||||||
|
const CScript& scriptPubKey = txout.scriptPubKey;
|
||||||
|
int nRequired;
|
||||||
|
txnouttype type;
|
||||||
|
vector<CTxDestination> addresses;
|
||||||
|
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
BOOST_FOREACH(const CTxDestination& address, addresses) {
|
||||||
|
if (CBitcoinAddress(address).ToString() != addr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cur == NULL) {
|
if (cur == NULL) {
|
||||||
@ -5935,39 +6001,14 @@ read_addr(const std::string addr) {
|
|||||||
}
|
}
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
for (unsigned int vo = 0; vo < ctx.vout.size(); vo++) {
|
|
||||||
const CTxOut& txout = ctx.vout[vo];
|
|
||||||
const CScript& scriptPubKey = txout.scriptPubKey;
|
|
||||||
int nRequired;
|
|
||||||
txnouttype type;
|
|
||||||
vector<CTxDestination> addresses;
|
|
||||||
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
BOOST_FOREACH(const CTxDestination& address, addresses) {
|
|
||||||
if (CBitcoinAddress(address).ToString() != addr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (cur == NULL) {
|
|
||||||
head->ctx = ctx;
|
|
||||||
head->blockhash = blockhash;
|
|
||||||
head->next = NULL;
|
|
||||||
cur = head;
|
|
||||||
} else {
|
|
||||||
ctx_list *item = new ctx_list();
|
|
||||||
item->ctx = ctx;
|
|
||||||
item->blockhash = blockhash;
|
|
||||||
item->next = NULL;
|
|
||||||
cur->next = item;
|
|
||||||
cur = item;
|
|
||||||
}
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transaction Structure:
|
||||||
|
// CDiskBlockPos.nFile - block file
|
||||||
|
// CDiskBlockPos.nPos - block pos
|
||||||
|
// CDiskTxPos.nTxOffset - offset from top of block
|
||||||
if (type == 't') {
|
if (type == 't') {
|
||||||
leveldb::Slice slValue = pcursor->value();
|
leveldb::Slice slValue = pcursor->value();
|
||||||
|
|
||||||
@ -5976,61 +6017,112 @@ read_addr(const std::string addr) {
|
|||||||
uint256 txhash;
|
uint256 txhash;
|
||||||
ssKey >> txhash;
|
ssKey >> txhash;
|
||||||
|
|
||||||
k_debug = strdup(txhash.GetHex().c_str());
|
|
||||||
|
|
||||||
CDiskBlockPos blockPos;
|
CDiskBlockPos blockPos;
|
||||||
ssValue >> blockPos.nFile;
|
ssValue >> blockPos.nFile;
|
||||||
ssValue >> blockPos.nPos;
|
ssValue >> blockPos.nPos;
|
||||||
|
|
||||||
CDiskTxPos txPos;
|
CDiskTxPos txPos;
|
||||||
//ssValue >> txPos.nFile;
|
// ssValue >> txPos.nFile;
|
||||||
//ssValue >> txPos.nPos;
|
// ssValue >> txPos.nPos;
|
||||||
txPos.nFile = blockPos.nFile;
|
txPos.nFile = blockPos.nFile;
|
||||||
txPos.nPos = blockPos.nPos;
|
txPos.nPos = blockPos.nPos;
|
||||||
|
|
||||||
ssValue >> txPos.nTxOffset;
|
ssValue >> txPos.nTxOffset;
|
||||||
}
|
|
||||||
|
|
||||||
found:
|
CTransaction ctx;
|
||||||
if (k_debug != NULL) {
|
uint256 blockhash;
|
||||||
free(k_debug);
|
|
||||||
|
if (!pblocktree->ReadTxIndex(txhash, txPos)) {
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAutoFile file(OpenBlockFile(txPos, true), SER_DISK, CLIENT_VERSION);
|
||||||
|
CBlockHeader header;
|
||||||
|
try {
|
||||||
|
file >> header;
|
||||||
|
fseek(file.Get(), txPos.nTxOffset, SEEK_CUR);
|
||||||
|
file >> ctx;
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (ctx.GetHash() != txhash) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
blockhash = header.GetHash();
|
||||||
|
|
||||||
|
BOOST_FOREACH(const CTxIn& txin, ctx.vin) {
|
||||||
|
if (txin.scriptSig.ToString() != expectedScriptSig.ToString()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cur == NULL) {
|
||||||
|
head->ctx = ctx;
|
||||||
|
head->blockhash = blockhash;
|
||||||
|
head->next = NULL;
|
||||||
|
cur = head;
|
||||||
|
} else {
|
||||||
|
ctx_list *item = new ctx_list();
|
||||||
|
item->ctx = ctx;
|
||||||
|
item->blockhash = blockhash;
|
||||||
|
item->next = NULL;
|
||||||
|
cur->next = item;
|
||||||
|
cur = item;
|
||||||
|
}
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int vo = 0; vo < ctx.vout.size(); vo++) {
|
||||||
|
const CTxOut& txout = ctx.vout[vo];
|
||||||
|
const CScript& scriptPubKey = txout.scriptPubKey;
|
||||||
|
int nRequired;
|
||||||
|
txnouttype type;
|
||||||
|
vector<CTxDestination> addresses;
|
||||||
|
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
BOOST_FOREACH(const CTxDestination& address, addresses) {
|
||||||
|
if (CBitcoinAddress(address).ToString() != addr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cur == NULL) {
|
||||||
|
head->ctx = ctx;
|
||||||
|
head->blockhash = blockhash;
|
||||||
|
head->next = NULL;
|
||||||
|
cur = head;
|
||||||
|
} else {
|
||||||
|
ctx_list *item = new ctx_list();
|
||||||
|
item->ctx = ctx;
|
||||||
|
item->blockhash = blockhash;
|
||||||
|
item->next = NULL;
|
||||||
|
cur->next = item;
|
||||||
|
cur = item;
|
||||||
|
}
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
k_debug = NULL;
|
found:
|
||||||
pcursor->Next();
|
pcursor->Next();
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
//CDataStream ssk(SER_NETWORK, PROTOCOL_VERSION);
|
pcursor->Next();
|
||||||
//ssk << lastKey.ToString();
|
continue;
|
||||||
//std::string lastKeyHex = HexStr(ssk.begin(), ssk.end());
|
leveldb::Slice lastKey = pcursor->key();
|
||||||
std::string lastKeyHex = HexStr(lastKey.ToString());
|
std::string lastKeyHex = HexStr(lastKey.ToString());
|
||||||
|
head->err_msg = std::string(e.what()
|
||||||
//CDataStream ssv(SER_NETWORK, PROTOCOL_VERSION);
|
+ std::string(" : Deserialize error. Key: ")
|
||||||
//ssv << lastVal.ToString();
|
+ lastKeyHex);
|
||||||
//std::string lastValHex = HexStr(ssv.begin(), ssv.end());
|
|
||||||
std::string lastValHex = HexStr(lastVal.ToString());
|
|
||||||
|
|
||||||
head->err_msg = std::string(lastKeyHex + std::string(": ") + lastValHex);
|
|
||||||
|
|
||||||
//head->err_msg = std::string(
|
|
||||||
// e.what()
|
|
||||||
// + std::string(" : Deserialize or I/O error. Key: ")
|
|
||||||
// + (k_debug != NULL ? std::string(k_debug) : std::string("NULL"))
|
|
||||||
//);
|
|
||||||
|
|
||||||
if (k_debug != NULL) {
|
|
||||||
free(k_debug);
|
|
||||||
}
|
|
||||||
k_debug = NULL;
|
|
||||||
|
|
||||||
delete pcursor;
|
delete pcursor;
|
||||||
return head;
|
return head;
|
||||||
|
|
||||||
//pcursor->Next();
|
|
||||||
//continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete pcursor;
|
delete pcursor;
|
||||||
|
|
||||||
|
return head;
|
||||||
|
|
||||||
|
error:
|
||||||
|
head->err_msg = std::string("Deserialize Error.");
|
||||||
|
|
||||||
|
delete pcursor;
|
||||||
|
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user