chain: only expose state if block is successfully written.

This commit is contained in:
Christopher Jeffrey 2016-11-17 03:02:46 -08:00
parent 1af3b5131b
commit 97703e4c7d
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -249,17 +249,18 @@ Chain.prototype._close = function close() {
*/ */
Chain.prototype.verifyContext = co(function* verifyContext(block, prev) { Chain.prototype.verifyContext = co(function* verifyContext(block, prev) {
var state = yield this.verify(block, prev); var state, view;
var view;
// Initial non-contextual verification.
state = yield this.verify(block, prev);
// BIP30 - Verify there are no duplicate txids.
yield this.verifyDuplicates(block, prev, state); yield this.verifyDuplicates(block, prev, state);
// Verify scripts, spend and add coins.
view = yield this.verifyInputs(block, prev, state); view = yield this.verifyInputs(block, prev, state);
// Expose the state globally. return new ContextResult(view, state);
this.state = state;
return view;
}); });
/** /**
@ -869,7 +870,7 @@ Chain.prototype.disconnect = co(function* disconnect(entry) {
Chain.prototype.reconnect = co(function* reconnect(entry) { Chain.prototype.reconnect = co(function* reconnect(entry) {
var block = yield this.db.getBlock(entry.hash); var block = yield this.db.getBlock(entry.hash);
var prev, view; var prev, result;
if (this.options.spv) { if (this.options.spv) {
assert(!block); assert(!block);
@ -882,7 +883,7 @@ Chain.prototype.reconnect = co(function* reconnect(entry) {
assert(prev); assert(prev);
try { try {
view = yield this.verifyContext(block, prev); result = yield this.verifyContext(block, prev);
} catch (e) { } catch (e) {
if (e.type === 'VerifyError') { if (e.type === 'VerifyError') {
if (!e.malleated) if (!e.malleated)
@ -892,10 +893,11 @@ Chain.prototype.reconnect = co(function* reconnect(entry) {
throw e; throw e;
} }
yield this.db.reconnect(entry, block, view); yield this.db.reconnect(entry, block, result.view);
this.tip = entry; this.tip = entry;
this.height = entry.height; this.height = entry.height;
this.state = result.state;
this.bestHeight = entry.height; this.bestHeight = entry.height;
this.network.updateHeight(entry.height); this.network.updateHeight(entry.height);
@ -918,7 +920,7 @@ Chain.prototype.reconnect = co(function* reconnect(entry) {
*/ */
Chain.prototype.setBestChain = co(function* setBestChain(entry, block, prev) { Chain.prototype.setBestChain = co(function* setBestChain(entry, block, prev) {
var view; var result;
// A higher fork has arrived. // A higher fork has arrived.
// Time to reorganize the chain. // Time to reorganize the chain.
@ -938,7 +940,7 @@ Chain.prototype.setBestChain = co(function* setBestChain(entry, block, prev) {
// now that we're certain its previous // now that we're certain its previous
// block is in the chain. // block is in the chain.
try { try {
view = yield this.verifyContext(block, prev); result = yield this.verifyContext(block, prev);
} catch (e) { } catch (e) {
// Couldn't verify block. // Couldn't verify block.
// Revert the height. // Revert the height.
@ -954,10 +956,12 @@ Chain.prototype.setBestChain = co(function* setBestChain(entry, block, prev) {
} }
// Save block and connect inputs. // Save block and connect inputs.
yield this.db.save(entry, block, view); yield this.db.save(entry, block, result.view);
// Expose the new state.
this.tip = entry; this.tip = entry;
this.height = entry.height; this.height = entry.height;
this.state = result.state;
this.emit('tip', entry); this.emit('tip', entry);
}); });
@ -2290,6 +2294,15 @@ function LockTimes(height, time) {
this.time = time; this.time = time;
} }
/*
* ContextResult
*/
function ContextResult(view, state) {
this.view = view;
this.state = state;
}
/* /*
* Expose * Expose
*/ */