improve get_block_by_tx.

This commit is contained in:
Christopher Jeffrey 2014-12-10 16:22:30 -08:00
parent 20934c285e
commit 78aceaf12e

View File

@ -192,7 +192,7 @@ using namespace v8;
// LevelDB options // LevelDB options
#define USE_LDB_ADDR 0 #define USE_LDB_ADDR 0
#define USE_LDB_TX 0 #define USE_LDB_TX 1
static termios orig_termios; static termios orig_termios;
@ -479,6 +479,7 @@ struct async_block_tx_data {
std::string txid; std::string txid;
CBlock cblock; CBlock cblock;
CBlockIndex* cblock_index; CBlockIndex* cblock_index;
CTransaction ctx;
Persistent<Function> callback; Persistent<Function> callback;
}; };
@ -613,7 +614,7 @@ read_addr(const std::string addr, const int64_t blockheight, const int64_t block
#if USE_LDB_TX #if USE_LDB_TX
static bool static bool
get_block_by_tx(const std::string itxid, CBlock& rcblock, CBlockIndex **rcblock_index); get_block_by_tx(const std::string itxid, CBlock& rcblock, CBlockIndex **rcblock_index, CTransaction& rctx);
#endif #endif
#if 0 #if 0
@ -2230,10 +2231,11 @@ parse:
CBlockIndex* pblockindex = chainActive[i]; CBlockIndex* pblockindex = chainActive[i];
CBlock cblock; CBlock cblock;
if (ReadBlockFromDisk(cblock, pblockindex)) { if (ReadBlockFromDisk(cblock, pblockindex)) {
BOOST_FOREACH(const CTransaction& ctx, cblock.vtx) { BOOST_FOREACH(const CTransaction& tx, cblock.vtx) {
if (ctx.GetHash().GetHex() == data->txid) { if (tx.GetHash().GetHex() == data->txid) {
data->cblock = cblock; data->cblock = cblock;
data->cblock_index = pblockindex; data->cblock_index = pblockindex;
data->ctx = tx;
return; return;
} }
} }
@ -2243,12 +2245,7 @@ parse:
return; return;
#if USE_LDB_TX #if USE_LDB_TX
} }
CBlock cblock; if (!get_block_by_tx(data->txid, data->cblock, &data->cblock_index, data->ctx)) {
CBlockIndex *cblock_index;
if (get_block_by_tx(data->txid, cblock, &cblock_index)) {
data->cblock = cblock;
data->cblock_index = cblock_index;
} else {
goto parse; goto parse;
} }
#endif #endif
@ -2271,14 +2268,19 @@ async_block_tx_after(uv_work_t *req) {
} else { } else {
const CBlock& cblock = data->cblock; const CBlock& cblock = data->cblock;
CBlockIndex* cblock_index = data->cblock_index; CBlockIndex* cblock_index = data->cblock_index;
const CTransaction& ctx = data->ctx;
Local<Object> jsblock = NanNew<Object>(); Local<Object> jsblock = NanNew<Object>();
cblock_to_jsblock(cblock, cblock_index, jsblock, false); cblock_to_jsblock(cblock, cblock_index, jsblock, false);
Local<Object> jstx = NanNew<Object>();
ctx_to_jstx(ctx, cblock.GetHash(), jstx);
const unsigned argc = 2; const unsigned argc = 2;
Local<Value> argv[argc] = { Local<Value> argv[argc] = {
Local<Value>::New(Null()), Local<Value>::New(Null()),
Local<Value>::New(jsblock) Local<Value>::New(jsblock),
Local<Value>::New(jstx)
}; };
TryCatch try_catch; TryCatch try_catch;
data->callback->Call(Context::GetCurrent()->Global(), argc, argv); data->callback->Call(Context::GetCurrent()->Global(), argc, argv);
@ -6541,90 +6543,65 @@ error:
#if USE_LDB_TX #if USE_LDB_TX
static bool static bool
get_block_by_tx(const std::string itxid, CBlock& rcblock, CBlockIndex **rcblock_index) { get_block_by_tx(const std::string itxid, CBlock& rcblock, CBlockIndex **rcblock_index, CTransaction& rctx) {
leveldb::Iterator* pcursor = pblocktree->pdb->NewIterator(pblocktree->iteroptions); const char *txkey = std::string(std::string("t") + itxid).c_str();
std::string slValue;
//leveldb::Slice slValue;
pcursor->SeekToFirst(); pblocktree->pdb->Get(leveldb::ReadOptions(), txkey, &slValue);
while (pcursor->Valid()) { CDataStream ssValue(slValue.begin(), slValue.end(), SER_DISK, CLIENT_VERSION);
boost::this_thread::interruption_point(); //CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION);
try {
leveldb::Slice slKey = pcursor->key();
CDataStream ssKey(slKey.data(), slKey.data() + slKey.size(), SER_DISK, CLIENT_VERSION); // Blockchain Index Structure:
// http://bitcoin.stackexchange.com/questions/28168
char type; // Transaction Structure:
ssKey >> type; // '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
// Blockchain Index Structure: // struct CDiskBlockPos {
// http://bitcoin.stackexchange.com/questions/28168 // int nFile;
// unsigned int nPos;
// };
// struct CDiskTxPos : public CDiskBlockPos {
// unsigned int nTxOffset;
// };
// Transaction Structure: CDiskTxPos txPos;
// 't' + 32-byte tx hash ssValue >> txPos;
// 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') {
uint256 txid;
ssKey >> txid;
if (txid.GetHex() == itxid) {
leveldb::Slice slValue = pcursor->value();
CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION); CTransaction ctx;
uint256 blockhash;
// struct CDiskBlockPos { if (!pblocktree->ReadTxIndex(txid, txPos)) {
// int nFile; goto error;
// unsigned int nPos; }
// };
// struct CDiskTxPos : public CDiskBlockPos { CAutoFile file(OpenBlockFile(txPos, true), SER_DISK, CLIENT_VERSION);
// unsigned int nTxOffset; CBlockHeader header;
// }; try {
file >> header;
CDiskTxPos txPos; fseek(file.Get(), txPos.nTxOffset, SEEK_CUR);
ssValue >> txPos; file >> ctx;
} catch (std::exception &e) {
CTransaction ctx; goto error;
uint256 blockhash; }
if (ctx.GetHash() != txid) {
if (!pblocktree->ReadTxIndex(txid, txPos)) { goto error;
goto error; }
} blockhash = header.GetHash();
CAutoFile file(OpenBlockFile(txPos, true), SER_DISK, CLIENT_VERSION); CBlockIndex* pblockindex = mapBlockIndex[blockhash];
CBlockHeader header;
try { if (ReadBlockFromDisk(rcblock, pblockindex)) {
file >> header; *rcblock_index = pblockindex;
fseek(file.Get(), txPos.nTxOffset, SEEK_CUR); rctx = ctx;
file >> ctx; return true;
} catch (std::exception &e) {
goto error;
}
if (ctx.GetHash() != txid) {
goto error;
}
blockhash = header.GetHash();
CBlockIndex* pblockindex = mapBlockIndex[blockhash];
if (ReadBlockFromDisk(rcblock, pblockindex)) {
*rcblock_index = pblockindex;
delete pcursor;
return true;
}
goto error;
}
}
pcursor->Next();
} catch (std::exception &e) {
delete pcursor;
return false;
}
} }
error:
delete pcursor;
return false; return false;
} }
#endif #endif