walletdb: improve block handling.

This commit is contained in:
Christopher Jeffrey 2016-10-23 22:24:00 -07:00
parent 37e3219c4c
commit 11a7515bfd
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 41 additions and 34 deletions

View File

@ -1170,15 +1170,17 @@ WalletDB.prototype._rescan = co(function* rescan(chaindb, height) {
}
blocks = this.height - height;
assert(blocks >= 0);
if (blocks < 0)
throw new Error('Cannot rescan future blocks.');
if (this.prune) {
if (blocks <= this.network.block.keepBlocks)
yield this.rollback(height);
} else {
yield this.rollback(height);
if (blocks > this.network.block.keepBlocks)
throw new Error('Cannot roll back beyond keepBlocks.');
}
yield this.rollback(height);
hashes = yield this.getHashes();
this.logger.info('Scanning for %d addresses.', hashes.length);
@ -1588,16 +1590,6 @@ WalletDB.prototype.rollback = co(function* rollback(height) {
WalletDB.prototype.addBlock = co(function* addBlock(entry, txs) {
var unlock = yield this.txLock.lock();
try {
yield this.rollback(entry.height - 1);
if (entry.height <= this.height) {
this.logger.warning('Node is connecting low blocks in wallet.');
return 0;
}
if (entry.height !== this.height + 1)
throw new Error('Bad connection (height mismatch).');
return yield this._addBlock(entry, txs);
} finally {
unlock();
@ -1615,6 +1607,13 @@ WalletDB.prototype._addBlock = co(function* addBlock(entry, txs) {
var total = 0;
var i, block, tx;
// Special case for the guh-naysis block.
if (entry.hash === this.network.genesis.hash)
return;
if (entry.height !== this.height + 1)
throw new Error('Bad connection (height mismatch).');
if (this.options.useCheckpoints) {
if (entry.height <= this.network.checkpoints.lastHeight) {
block = WalletBlock.fromEntry(entry);
@ -1655,16 +1654,6 @@ WalletDB.prototype._addBlock = co(function* addBlock(entry, txs) {
WalletDB.prototype.removeBlock = co(function* removeBlock(entry) {
var unlock = yield this.txLock.lock();
try {
yield this.rollback(entry.height);
if (entry.height > this.height) {
this.logger.warning('Node is disconnecting high blocks in wallet.');
return 0;
}
if (entry.height !== this.height)
throw new Error('Bad disconnection (height mismatch).');
return yield this._removeBlock(entry);
} finally {
unlock();
@ -1680,13 +1669,17 @@ WalletDB.prototype.removeBlock = co(function* removeBlock(entry) {
WalletDB.prototype._removeBlock = co(function* removeBlock(entry) {
var block = yield this.getBlock(entry.height);
var i, tx, prev;
var prev = yield this.getBlock(entry.height - 1);
var i, tx;
if (!block)
return 0;
throw new Error('Bad disconnection (block not found).');
prev = yield this.getBlock(entry.height - 1);
assert(prev);
if (!prev)
throw new Error('Bad disconnection (no previous block).');
if (entry.height !== this.height)
throw new Error('Bad disconnection (height mismatch).');
if (block.txs.length === 0) {
yield this.setBlock(prev);

View File

@ -19,12 +19,26 @@ var KEY2 = 'xprv9s21ZrQH143K3mqiSThzPtWAabQ22Pjp3uSNnZ53A5bQ4udp'
+ 'faKekc2m4AChLYH1XDzANhrSdxHYWUeTWjYJwFwWFyHkTMnMeAcW4JyRCZa';
var globalHeight = 1;
var globalTime = utils.now();
function nextBlock(height) {
var hash;
height = height != null ? height : globalHeight++;
var hash, prev;
if (height == null)
height = globalHeight++;
hash = crypto.hash256(utils.U32(height)).toString('hex');
return new WalletBlock(hash, height++, utils.now());
prev = crypto.hash256(utils.U32(height - 1)).toString('hex');
return {
hash: hash,
height: height,
prevBlock: prev,
ts: globalTime + height,
merkleRoot: constants.NULL_HASH,
nonce: 0,
bits: 0
};
}
function dummy(hash) {
@ -709,9 +723,9 @@ describe('Wallet', function() {
// Simulate a confirmation
var block = nextBlock();
utx.ts = block.ts;
utx.height = block.height;
utx.block = block.hash;
utx.ts = block.ts;
utx.index = 0;
assert.equal(w1[depth], 1);
@ -752,9 +766,9 @@ describe('Wallet', function() {
// Simulate a confirmation
var block = nextBlock();
send.ts = block.ts;
send.height = block.height;
send.block = block.hash;
send.ts = block.ts;
send.index = 0;
yield walletdb.addBlock(block, [send]);