This commit is contained in:
Christopher Jeffrey 2016-03-05 06:48:17 -08:00
parent 49bb2d44e4
commit 23285d282b
2 changed files with 86 additions and 73 deletions

View File

@ -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
*/

View File

@ -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);
});
});