fast
This commit is contained in:
parent
49bb2d44e4
commit
23285d282b
@ -384,6 +384,65 @@ Block.fromRaw = function fromRaw(data, enc, type) {
|
||||
return new Block(Block._fromRaw(data, enc));
|
||||
};
|
||||
|
||||
Block.prototype.toSmall = function toSmall() {
|
||||
var block = this.abbr();
|
||||
var buf = new Buffer(block.length + 4 + this.txs.length * 32);
|
||||
var height = this.height;
|
||||
var off = 0;
|
||||
|
||||
if (height === -1)
|
||||
height = 0x7fffffff;
|
||||
|
||||
off += utils.copy(block, buf, off);
|
||||
off += utils.writeU32(buf, height, off);
|
||||
|
||||
off += utils.writeIntv(buf, this.txs.length, off);
|
||||
this.txs.forEach(function(tx) {
|
||||
off += utils.copy(tx.hash(), buf, off);
|
||||
});
|
||||
|
||||
return buf;
|
||||
};
|
||||
|
||||
Block.fromSmall = function fromSmall(buf) {
|
||||
var tx, txCount, i;
|
||||
var off = 0;
|
||||
var hashes = [];
|
||||
|
||||
var version = utils.read32(buf, 0);
|
||||
var prevBlock = buf.slice(4, 36);
|
||||
var merkleRoot = buf.slice(36, 68);
|
||||
var ts = utils.readU32(buf, 68);
|
||||
var bits = utils.readU32(buf, 72);
|
||||
var nonce = utils.readU32(buf, 76);
|
||||
var height = utils.readU32(buf, 80);
|
||||
var txCount = utils.readIntv(buf, 84);
|
||||
off = txCount.off;
|
||||
txCount = txCount.r;
|
||||
|
||||
for (i = 0; i < txCount; i++) {
|
||||
if (off + 32 > buf.length)
|
||||
throw new Error('Bad TX count.');
|
||||
hashes.push(utils.toHex(buf.slice(off, off + 32)));
|
||||
off += 32;
|
||||
}
|
||||
|
||||
if (height === 0x7fffffff)
|
||||
height = -1;
|
||||
|
||||
return {
|
||||
version: version,
|
||||
prevBlock: utils.toHex(prevBlock),
|
||||
merkleRoot: utils.toHex(merkleRoot),
|
||||
ts: ts,
|
||||
bits: bits,
|
||||
nonce: nonce,
|
||||
height: height,
|
||||
totalTX: txCount,
|
||||
hashes: hashes
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose
|
||||
*/
|
||||
|
||||
@ -161,23 +161,11 @@ BlockDB.prototype.parseOffset = function parseOffset(data) {
|
||||
BlockDB.prototype.saveBlock = function saveBlock(block, callback) {
|
||||
var self = this;
|
||||
|
||||
this.data.saveAsync(block._raw, function(err, data) {
|
||||
var batch, blockOffset;
|
||||
var batch = self.index.batch();
|
||||
|
||||
if (err)
|
||||
return callback(err);
|
||||
batch.put('b/b/' + block.hash('hex'), block.toSmall());
|
||||
|
||||
batch = self.index.batch();
|
||||
|
||||
block._fileOffset = data.offset;
|
||||
assert(block._size === data.size);
|
||||
|
||||
blockOffset = self.createOffset(block._size, block._fileOffset, block.height);
|
||||
|
||||
batch.put('b/b/' + block.hash('hex'), blockOffset);
|
||||
|
||||
self.connectBlock(block, callback, batch, blockOffset);
|
||||
});
|
||||
self.connectBlock(block, callback, batch);
|
||||
};
|
||||
|
||||
BlockDB.prototype.removeBlock = function removeBlock(hash, callback) {
|
||||
@ -229,23 +217,14 @@ BlockDB.prototype.connectBlock = function connectBlock(block, callback, batch, b
|
||||
if (!batch)
|
||||
batch = self.index.batch();
|
||||
|
||||
if (!blockOffset)
|
||||
blockOffset = self.createOffset(block._size, block._fileOffset, block.height);
|
||||
|
||||
batch.put('b/h/' + block.height, blockOffset);
|
||||
batch.put('b/h/' + block.height, block.hash());
|
||||
|
||||
block.txs.forEach(function(tx, i) {
|
||||
var hash = tx.hash('hex');
|
||||
var uniq = {};
|
||||
var txOffset;
|
||||
|
||||
txOffset = self.createOffset(
|
||||
tx._size,
|
||||
block._fileOffset + tx._offset,
|
||||
block.height
|
||||
);
|
||||
|
||||
batch.put('t/t/' + hash, txOffset);
|
||||
batch.put('t/t/' + hash, tx.toExtended());
|
||||
|
||||
tx.inputs.forEach(function(input) {
|
||||
var type = input.getType();
|
||||
@ -268,7 +247,7 @@ BlockDB.prototype.connectBlock = function connectBlock(block, callback, batch, b
|
||||
}
|
||||
|
||||
if (uaddr)
|
||||
batch.put('t/a/' + uaddr + '/' + hash, txOffset);
|
||||
batch.put('t/a/' + uaddr + '/' + hash, new Buffer([]));
|
||||
|
||||
if (address) {
|
||||
batch.del(
|
||||
@ -300,19 +279,13 @@ BlockDB.prototype.connectBlock = function connectBlock(block, callback, batch, b
|
||||
uaddr = null;
|
||||
}
|
||||
|
||||
coinOffset = self.createOffset(
|
||||
output._size,
|
||||
block._fileOffset + tx._offset + output._offset,
|
||||
block.height
|
||||
);
|
||||
|
||||
if (uaddr)
|
||||
batch.put('t/a/' + uaddr + '/' + hash, txOffset);
|
||||
batch.put('t/a/' + uaddr + '/' + hash, new Buffer([]));
|
||||
|
||||
if (address)
|
||||
batch.put('u/a/' + address + '/' + hash + '/' + i, coinOffset);
|
||||
batch.put('u/a/' + address + '/' + hash + '/' + i, new Buffer([]));
|
||||
|
||||
batch.put('u/t/' + hash + '/' + i, coinOffset);
|
||||
batch.put('u/t/' + hash + '/' + i, bcoin.coin(tx, i).toRaw());
|
||||
});
|
||||
});
|
||||
|
||||
@ -516,7 +489,6 @@ BlockDB.prototype.fillTX = function fillTX(tx, callback) {
|
||||
|
||||
if (tx) {
|
||||
input.output = bcoin.coin(tx, input.prevout.index);
|
||||
input.output._fileOffset = tx._fileOffset + input.output._offset;
|
||||
}
|
||||
|
||||
next();
|
||||
@ -633,6 +605,7 @@ BlockDB.prototype.getCoin = function getCoin(hash, index, callback) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
return callback(null, bcoin.coin.fromRaw(record));
|
||||
record = self.parseOffset(record);
|
||||
|
||||
self.data.getAsync(record.size, record.offset, function(err, data) {
|
||||
@ -790,6 +763,7 @@ BlockDB.prototype.getTX = function getTX(hash, callback) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
return callback(null, bcoin.tx.fromExtended(record));
|
||||
record = self.parseOffset(record);
|
||||
|
||||
self.data.getAsync(record.size, record.offset, function(err, data) {
|
||||
@ -931,47 +905,27 @@ BlockDB.prototype.getBlock = function getBlock(hash, callback) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
record = self.parseOffset(record);
|
||||
var block = bcoin.block.fromSmall(record);
|
||||
block.txs = [];
|
||||
|
||||
self.data.getAsync(record.size, record.offset, function(err, data) {
|
||||
var block;
|
||||
utils.forEach(block.hashes, function(hash, next, i) {
|
||||
self.getTX(hash, function(err, tx) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
if (!tx)
|
||||
return next(new Error('TX not found.'));
|
||||
|
||||
block.txs[i] = tx;
|
||||
|
||||
next();
|
||||
})
|
||||
}, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (data) {
|
||||
try {
|
||||
block = bcoin.protocol.parser.parseBlock(data);
|
||||
block = new bcoin.block(block);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
block._fileOffset = record.offset;
|
||||
block.height = record.height;
|
||||
block.txs.forEach(function(tx) {
|
||||
tx.height = block.height;
|
||||
});
|
||||
if (self.options.paranoid) {
|
||||
if (typeof hash === 'number') {
|
||||
self._getEntry(hash, function(err, entry) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!entry)
|
||||
return callback(null, block);
|
||||
|
||||
if (block.hash('hex') !== entry.hash)
|
||||
return callback(new Error('BlockDB is corrupt. All is lost.'));
|
||||
|
||||
return callback(null, block);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (block.hash('hex') !== hash)
|
||||
return callback(new Error('BlockDB is corrupt. All is lost.'));
|
||||
}
|
||||
}
|
||||
|
||||
delete block.hashes;
|
||||
block = new bcoin.block(block);
|
||||
return callback(null, block);
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user