From 9c2726b09cfdb8bf2ec69e8a8b9beb180b8c8194 Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Tue, 7 Jul 2015 23:24:22 -0400 Subject: [PATCH] Read block as a buffer --- src/bitcoindjs.cc | 60 +++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/src/bitcoindjs.cc b/src/bitcoindjs.cc index 3611d043..8b11078d 100644 --- a/src/bitcoindjs.cc +++ b/src/bitcoindjs.cc @@ -189,6 +189,8 @@ struct async_block_data { std::string err_msg; std::string hash; int64_t height; + char* buffer; + uint32_t size; CBlock cblock; CBlockIndex* cblock_index; Eternal callback; @@ -835,34 +837,45 @@ static void async_get_block(uv_work_t *req) { async_block_data* data = static_cast(req->data); - if (data->height != -1) { - CBlockIndex* pblockindex = chainActive[data->height]; - CBlock cblock; - if (ReadBlockFromDisk(cblock, pblockindex)) { - data->cblock = cblock; - data->cblock_index = pblockindex; - } else { - data->err_msg = std::string("Block not found."); - } - return; - } - std::string strHash = data->hash; uint256 hash(strHash); if (mapBlockIndex.count(hash) == 0) { - data->err_msg = std::string("Block not found."); + data->err_msg = std::string("Block not found."); } else { - CBlock block; CBlockIndex* pblockindex = mapBlockIndex[hash]; - if(!ReadBlockFromDisk(block, pblockindex)) { - data->err_msg = std::string("Can't read block from disk"); - } else { - data->cblock = block; - data->cblock_index = pblockindex; + const CDiskBlockPos& pos = pblockindex->GetBlockPos(); + + // We can read directly from the file, and pass that, we don't need to + // deserialize the entire block only for it to then be serialized + // and then deserialized again in JavaScript + + // Open history file to read + CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); + if (filein.IsNull()) { + data->err_msg = std::string("ReadBlockFromDisk: OpenBlockFile failed"); + return; } + + // Get the actual file, seeked position and rewind a uint32_t + FILE* blockFile = filein.release(); + long int filePos = ftell(blockFile); + fseek(blockFile, filePos - sizeof(uint32_t), SEEK_SET); + + // Read the size of the block + uint32_t size = 0; + fread(&size, sizeof(uint32_t), 1, blockFile); + + // Read block + char buffer[size]; + fread((void *)buffer, sizeof(char), size, blockFile); + fclose(blockFile); + + data->buffer = buffer; + data->size = size; + data->cblock_index = pblockindex; } } @@ -883,19 +896,14 @@ async_get_block_after(uv_work_t *req) { node::FatalException(try_catch); } } else { - const CBlock& cblock = data->cblock; CBlockIndex* cblock_index = data->cblock_index; - CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); - ssBlock << cblock; - std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); - - Local jsblock = NanNew(strHex); + Local rawNodeBuffer = node::Buffer::New(isolate, data->buffer, data->size); const unsigned argc = 2; Local argv[argc] = { Local::New(isolate, NanNull()), - Local::New(isolate, jsblock) + rawNodeBuffer }; TryCatch try_catch; cb->Call(isolate->GetCurrentContext()->Global(), argc, argv);