blockdb cleanup.
This commit is contained in:
parent
2a20e56f7b
commit
299126225c
@ -32,15 +32,21 @@ function BlockDB(options) {
|
||||
options = { file: options };
|
||||
|
||||
if (!options.file)
|
||||
options.file = process.env.HOME + '/bcoin-server-' + network.type + '.ldb';
|
||||
options.file = process.env.HOME + '/bcoin-index-' + network.type + '.db';
|
||||
|
||||
this.options = options;
|
||||
|
||||
this.parser = new bcoin.protocol.parser();
|
||||
|
||||
this.data = new BlockData();
|
||||
|
||||
this.index = levelup(options.file, {
|
||||
keyEncoding: 'ascii',
|
||||
valueEncoding: 'binary',
|
||||
cacheSize: 16 * 1024 * 1024
|
||||
cacheSize: 16 * 1024 * 1024,
|
||||
db: bcoin.isBrowser
|
||||
? require('memdown')
|
||||
: require('level' + 'down')
|
||||
});
|
||||
}
|
||||
|
||||
@ -83,22 +89,28 @@ BlockDB.prototype.saveBlock = function saveBlock(block, callback) {
|
||||
var batch = this.index.batch();
|
||||
|
||||
this.data.saveAsync(block._raw, function(err, data) {
|
||||
var batch, blockOffset;
|
||||
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
var blockOffset = self.createOffset(data.size, data.offset, block.height);
|
||||
batch = self.index.batch();
|
||||
|
||||
blockOffset = self.createOffset(data.size, data.offset, block.height);
|
||||
|
||||
var batch = self.index.batch();
|
||||
batch.put('b/b/' + block.hash('hex'), blockOffset);
|
||||
batch.put('b/h/' + block.height, blockOffset);
|
||||
|
||||
block.txs.forEach(function(tx, i) {
|
||||
var txOffset = self.createOffset(
|
||||
tx._size, data.offset + tx._offset,
|
||||
block.height);
|
||||
|
||||
var hash = tx.hash('hex');
|
||||
var uniq = {};
|
||||
var txOffset;
|
||||
|
||||
txOffset = self.createOffset(
|
||||
tx._size,
|
||||
data.offset + tx._offset,
|
||||
block.height
|
||||
);
|
||||
|
||||
batch.put('t/t/' + hash, txOffset);
|
||||
|
||||
@ -122,8 +134,12 @@ BlockDB.prototype.saveBlock = function saveBlock(block, callback) {
|
||||
if (uaddr)
|
||||
batch.put('t/a/' + uaddr + '/' + hash, txOffset);
|
||||
|
||||
if (address)
|
||||
batch.del('u/a/' + address + '/' + input.prevout.hash + '/' + input.prevout.index);
|
||||
if (address) {
|
||||
batch.del(
|
||||
'u/a/' + address
|
||||
+ '/' + input.prevout.hash
|
||||
+ '/' + input.prevout.index);
|
||||
}
|
||||
|
||||
batch.del('u/t/' + input.prevout.hash + '/' + input.prevout.index);
|
||||
});
|
||||
@ -131,7 +147,7 @@ BlockDB.prototype.saveBlock = function saveBlock(block, callback) {
|
||||
tx.outputs.forEach(function(output) {
|
||||
var type = output.getType();
|
||||
var address = output.getAddress();
|
||||
var uaddr;
|
||||
var uaddr, coinOffset;
|
||||
|
||||
if (type === 'pubkey' || type === 'multisig')
|
||||
address = null;
|
||||
@ -145,10 +161,11 @@ BlockDB.prototype.saveBlock = function saveBlock(block, callback) {
|
||||
uaddr = null;
|
||||
}
|
||||
|
||||
var coinOffset = self.createOffset(
|
||||
coinOffset = self.createOffset(
|
||||
output._size,
|
||||
data.offset + tx._offset + output._offset,
|
||||
block.height);
|
||||
block.height
|
||||
);
|
||||
|
||||
if (uaddr)
|
||||
batch.put('t/a/' + uaddr + '/' + hash, txOffset);
|
||||
@ -207,7 +224,7 @@ BlockDB.prototype.removeBlock = function removeBlock(hash, callback) {
|
||||
tx.inputs.forEach(function(input) {
|
||||
var type = input.getType();
|
||||
var address = input.getAddress();
|
||||
var uaddr;
|
||||
var uaddr, coinOffset;
|
||||
|
||||
if (type === 'pubkey' || type === 'multisig')
|
||||
address = null;
|
||||
@ -224,15 +241,23 @@ BlockDB.prototype.removeBlock = function removeBlock(hash, callback) {
|
||||
if (uaddr)
|
||||
batch.del('t/a/' + uaddr + '/' + hash);
|
||||
|
||||
var coinOffset = self.createOffset(
|
||||
coinOffset = self.createOffset(
|
||||
input.output._size,
|
||||
block._fileOffset + tx._offset + input.output._offset,
|
||||
block.height);
|
||||
block.height
|
||||
);
|
||||
|
||||
if (address)
|
||||
batch.put('u/a/' + address + '/' + input.output.hash + '/' + input.output.index, coinOffset);
|
||||
if (address) {
|
||||
batch.put('u/a/' + address
|
||||
+ '/' + input.output.hash
|
||||
+ '/' + input.output.index,
|
||||
coinOffset);
|
||||
}
|
||||
|
||||
batch.put('u/t/' + input.output.hash + '/' + input.output.index, coinOffset);
|
||||
batch.put('u/t/'
|
||||
+ input.output.hash
|
||||
+ '/' + input.output.index,
|
||||
coinOffset);
|
||||
});
|
||||
|
||||
tx.outputs.forEach(function(output) {
|
||||
@ -272,6 +297,11 @@ BlockDB.prototype.fillTX = function fillTX(tx, callback) {
|
||||
var self = this;
|
||||
var pending = tx.inputs.length;
|
||||
|
||||
callback = utils.asyncify(callback);
|
||||
|
||||
if (!pending)
|
||||
return callback();
|
||||
|
||||
tx.inputs.forEach(function(input) {
|
||||
if (input.output) {
|
||||
if (!--pending)
|
||||
@ -295,6 +325,11 @@ BlockDB.prototype.fillTX2 = function fillTX2(tx, callback) {
|
||||
var self = this;
|
||||
var pending = tx.inputs.length;
|
||||
|
||||
callback = utils.asyncify(callback);
|
||||
|
||||
if (!pending)
|
||||
return callback();
|
||||
|
||||
tx.inputs.forEach(function(input) {
|
||||
if (input.output) {
|
||||
if (!--pending)
|
||||
@ -324,7 +359,7 @@ BlockDB.prototype.getCoinsByAddress = function getCoinsByAddress(addresses, call
|
||||
|
||||
addresses = utils.uniqs(addresses);
|
||||
|
||||
var pending = addresses.length;
|
||||
pending = addresses.length;
|
||||
|
||||
addresses.forEach(function(address) {
|
||||
self._getCoinsByAddress(address, function(err, coin) {
|
||||
@ -345,10 +380,11 @@ BlockDB.prototype._getCoinsByAddress = function _getCoinsByAddress(address, call
|
||||
var pending = 0;
|
||||
var coins = [];
|
||||
var done = false;
|
||||
var stream;
|
||||
|
||||
callback = utils.asyncify(callback);
|
||||
|
||||
var stream = this.index.createReadStream({
|
||||
stream = this.index.createReadStream({
|
||||
start: 'u/a/' + address,
|
||||
end: 'u/a/' + address + '~'
|
||||
});
|
||||
@ -366,7 +402,11 @@ BlockDB.prototype._getCoinsByAddress = function _getCoinsByAddress(address, call
|
||||
return callback(err);
|
||||
|
||||
if (data) {
|
||||
data = self.parser.parseTXOut(data);
|
||||
try {
|
||||
data = self.parser.parseTXOut(data);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
coin = bcoin.coin({
|
||||
version: 1,
|
||||
hash: hash,
|
||||
@ -403,7 +443,7 @@ BlockDB.prototype.getCoin = function getCoin(hash, index, callback) {
|
||||
var self = this;
|
||||
var id = 'u/t/' + hash + '/' + index;
|
||||
|
||||
this.index.get(id, { valueEncoding: 'binary' }, function(err, record) {
|
||||
this.index.get(id, function(err, record) {
|
||||
if (err) {
|
||||
if (err.type === 'NotFoundError')
|
||||
return callback();
|
||||
@ -419,7 +459,11 @@ BlockDB.prototype.getCoin = function getCoin(hash, index, callback) {
|
||||
return callback(err);
|
||||
|
||||
if (data) {
|
||||
data = self.parser.parseTXOut(data);
|
||||
try {
|
||||
data = self.parser.parseTXOut(data);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
coin = bcoin.coin({
|
||||
version: 1,
|
||||
hash: hash,
|
||||
@ -493,8 +537,13 @@ BlockDB.prototype._getTXByAddress = function _getTXByAddress(address, callback)
|
||||
return callback(err);
|
||||
|
||||
if (data) {
|
||||
tx = bcoin.tx.fromRaw(data);
|
||||
entry = bcoin.chain.global.db.get(record.height);
|
||||
try {
|
||||
tx = bcoin.tx.fromRaw(data);
|
||||
entry = bcoin.chain.global.db.get(record.height);
|
||||
assert(entry);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
tx.height = record.height;
|
||||
tx.ts = entry.ts;
|
||||
tx.block = entry.hash;
|
||||
@ -525,7 +574,7 @@ BlockDB.prototype.getTX = function getTX(hash, callback) {
|
||||
var self = this;
|
||||
var id = 't/t/' + hash;
|
||||
|
||||
this.index.get(id, { valueEncoding: 'binary' }, function(err, record) {
|
||||
this.index.get(id, function(err, record) {
|
||||
if (err) {
|
||||
if (err.type === 'NotFoundError')
|
||||
return callback();
|
||||
@ -541,8 +590,13 @@ BlockDB.prototype.getTX = function getTX(hash, callback) {
|
||||
return callback(err);
|
||||
|
||||
if (data) {
|
||||
tx = bcoin.tx.fromRaw(data);
|
||||
entry = bcoin.chain.global.db.get(record.height);
|
||||
try {
|
||||
tx = bcoin.tx.fromRaw(data);
|
||||
entry = bcoin.chain.global.db.get(record.height);
|
||||
assert(entry);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
tx.height = record.height;
|
||||
tx.ts = entry.ts;
|
||||
tx.block = entry.hash;
|
||||
@ -560,7 +614,7 @@ BlockDB.prototype.getBlock = function getBlock(hash, callback) {
|
||||
if (typeof hash === 'number')
|
||||
id = 'b/h/' + value;
|
||||
|
||||
this.index.get(id, { valueEncoding: 'binary' }, function(err, record) {
|
||||
this.index.get(id, function(err, record) {
|
||||
if (err) {
|
||||
if (err.type === 'NotFoundError')
|
||||
return callback();
|
||||
@ -576,7 +630,11 @@ BlockDB.prototype.getBlock = function getBlock(hash, callback) {
|
||||
return callback(err);
|
||||
|
||||
if (data) {
|
||||
block = bcoin.block.fromRaw(data);
|
||||
try {
|
||||
block = bcoin.block.fromRaw(data);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
block._fileOffset = record.offset;
|
||||
block.height = record.height;
|
||||
}
|
||||
@ -590,19 +648,18 @@ BlockDB.prototype.getBlock = function getBlock(hash, callback) {
|
||||
* BlockData
|
||||
*/
|
||||
|
||||
function BlockData(chain, options) {
|
||||
function BlockData(options) {
|
||||
if (!(this instanceof BlockData))
|
||||
return new BlockData(chain, options);
|
||||
return new BlockData(options);
|
||||
|
||||
if (!options)
|
||||
options = {};
|
||||
|
||||
this.options = options;
|
||||
this.chain = chain;
|
||||
this.file = options.file;
|
||||
|
||||
if (!this.file)
|
||||
this.file = process.env.HOME + '/bcoin-' + network.type + '.data';
|
||||
this.file = process.env.HOME + '/bcoin-data-' + network.type + '.db';
|
||||
|
||||
this._queue = [];
|
||||
this._cache = {};
|
||||
@ -628,10 +685,8 @@ BlockData.prototype._init = function _init() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.exists()) {
|
||||
fs.writeFileSync(this.file, new Buffer(0));
|
||||
fs.truncateSync(this.file, 0);
|
||||
}
|
||||
if (!this.exists())
|
||||
fs.writeFileSync(this.file, new Buffer([]));
|
||||
|
||||
this.size = this.getSize();
|
||||
|
||||
@ -757,9 +812,8 @@ BlockData.prototype.saveAsync = function saveAsync(data, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
BlockData.prototype.truncate = function truncate(height) {
|
||||
this.size = (height + 1) * BLOCK_SIZE;
|
||||
this.tip = height;
|
||||
BlockData.prototype.truncate = function truncate(size) {
|
||||
this.size = size;
|
||||
|
||||
if (!bcoin.fs) {
|
||||
this.ramdisk.truncate(this.size);
|
||||
|
||||
@ -33,7 +33,7 @@ function ChainDB(chain, options) {
|
||||
this.file = options.file;
|
||||
|
||||
if (!this.file)
|
||||
this.file = process.env.HOME + '/bcoin-' + network.type + '.blockchain';
|
||||
this.file = process.env.HOME + '/bcoin-chain-' + network.type + '.db';
|
||||
|
||||
this._queue = [];
|
||||
this._cache = {};
|
||||
@ -70,10 +70,8 @@ ChainDB.prototype._init = function _init() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.exists()) {
|
||||
fs.writeFileSync(this.file, new Buffer(0));
|
||||
fs.truncateSync(this.file, 0);
|
||||
}
|
||||
if (!this.exists())
|
||||
fs.writeFileSync(this.file, new Buffer([]));
|
||||
|
||||
this.size = this.getSize();
|
||||
|
||||
|
||||
@ -148,7 +148,7 @@ TX.prototype.input = TX.prototype.addInput;
|
||||
// tx._addInput({ hash: hash, index: index })
|
||||
// tx._addInput({ tx: tx, index: index })
|
||||
TX.prototype._addInput = function _addInput(options, index) {
|
||||
var coin, input, ex, i, prevout;
|
||||
var coin, input, ex, i, prevout, isInput;
|
||||
|
||||
if (options instanceof TX) {
|
||||
options = { tx: options, index: index };
|
||||
@ -162,7 +162,6 @@ TX.prototype._addInput = function _addInput(options, index) {
|
||||
if (options.seq != null)
|
||||
options.sequence = options.seq;
|
||||
|
||||
var isInput;
|
||||
if (!options.prevout) {
|
||||
if (options instanceof bcoin.coin) {
|
||||
options = {
|
||||
@ -780,8 +779,7 @@ TX.prototype.scriptOutput = function scriptOutput(index, options) {
|
||||
script = [
|
||||
bcoin.script.array(options.locktime),
|
||||
'checklocktimeverify',
|
||||
'drop',
|
||||
'codeseparator'
|
||||
'drop'
|
||||
].concat(script);
|
||||
}
|
||||
hash = utils.ripesha(bcoin.script.encode(script));
|
||||
@ -808,6 +806,9 @@ TX.prototype.signatureHash = function signatureHash(index, s, type) {
|
||||
var copy = this.clone();
|
||||
var i, msg, hash;
|
||||
|
||||
if (typeof index !== 'number')
|
||||
index = this.inputs.indexOf(index);
|
||||
|
||||
if (!Array.isArray(s)) {
|
||||
type = s;
|
||||
s = this.inputs[index].output.script;
|
||||
@ -815,9 +816,6 @@ TX.prototype.signatureHash = function signatureHash(index, s, type) {
|
||||
s = bcoin.script.getRedeem(this.inputs[index].script);
|
||||
}
|
||||
|
||||
if (typeof index !== 'number')
|
||||
index = this.inputs.indexOf(index);
|
||||
|
||||
if (typeof type === 'string')
|
||||
type = constants.hashType[type];
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user