Use prevHash from bitcoind block index

- Changed method getChainWork into getBlockIndex
- Added prevHash to getBlockIndex result
This commit is contained in:
Braydon Fuller 2015-07-22 15:34:15 -04:00
parent 8905333e3f
commit 7b8268d0e0
8 changed files with 65 additions and 22 deletions

View File

@ -12,6 +12,7 @@ if (process.env.BITCOINDJS_ENV !== 'test') {
var chai = require('chai');
var bitcore = require('bitcore');
var BN = bitcore.crypto.BN;
var rimraf = require('rimraf');
var bitcoind;
@ -261,4 +262,20 @@ describe('Daemon Binding Functionality', function() {
});
describe('get block index', function() {
var expectedWork = new BN(6);
[1,2,3,4,5,6,7,8,9].forEach(function(i) {
it('generate block ' + i, function() {
var blockIndex = bitcoind.getBlockIndex(blockHashes[i]);
should.exist(blockIndex);
should.exist(blockIndex.chainWork);
var work = new BN(blockIndex.chainWork, 'hex');
work.cmp(expectedWork).should.equal(0);
expectedWork = expectedWork.add(new BN(2));
should.exist(blockIndex.prevHash);
blockIndex.prevHash.should.equal(blockHashes[i - 1]);
});
});
});
});

View File

@ -85,13 +85,14 @@ Chain.prototype.buildGenesisBlock = function buildGenesisBlock(options) {
Chain.prototype.getWeight = function getWeight(blockHash, callback) {
var self = this;
var blockIndex = self.db.bitcoind.getBlockIndex(blockHash);
setImmediate(function() {
var weight = self.db.bitcoind.getChainWork(blockHash);
if(weight === undefined) {
if (blockIndex) {
callback(null, new BN(blockIndex.chainWork, 'hex'));
} else {
return callback(new Error('Weight not found for ' + blockHash));
}
callback(null, new BN(weight, 'hex'));
});
};

View File

@ -340,8 +340,8 @@ Daemon.prototype.isSpent = function(txid, outputIndex) {
return bitcoindjs.isSpent(txid, outputIndex);
};
Daemon.prototype.getChainWork = function(blockHash) {
return bitcoindjs.getChainWork(blockHash);
Daemon.prototype.getBlockIndex = function(blockHash) {
return bitcoindjs.getBlockIndex(blockHash);
};
Daemon.prototype.sendTransaction = function(transaction, allowAbsurdFees) {

View File

@ -46,10 +46,20 @@ DB.prototype.getBlock = function(hash, callback) {
});
};
DB.prototype.getPrevHash = function(blockHash, callback) {
var blockIndex = this.bitcoind.getBlockIndex(blockHash);
setImmediate(function() {
if (blockIndex) {
callback(null, blockIndex.prevHash);
} else {
callback(new Error('Could not get prevHash, block not found'));
}
});
};
DB.prototype.putBlock = function(block, callback) {
// block is already stored in bitcoind, but we need to update
// our prevhash index still
this._updatePrevHashIndex(block, callback);
// block is already stored in bitcoind
setImmediate(callback);
};
DB.prototype.getTransaction = function(txid, queryMempool, callback) {
@ -67,6 +77,11 @@ DB.prototype.validateBlockData = function(block, callback) {
setImmediate(callback);
};
DB.prototype._updatePrevHashIndex = function(block, callback) {
// bitcoind has the previous hash for each block
setImmediate(callback);
};
DB.prototype._updateWeight = function(hash, weight, callback) {
// bitcoind has all work for each block
setImmediate(callback);

View File

@ -980,12 +980,14 @@ NAN_METHOD(IsSpent) {
};
/**
* GetChainWork()
* bitcoindjs.getChainWork()
* Get the total amount of work (expected number of hashes) in the chain up to
* and including this block.
* GetBlockIndex()
* bitcoindjs.getBlockIndex()
* Get index information about a block by hash including:
* - the total amount of work (expected number of hashes) in the chain up to
* and including this block.
* - the previous hash of the block
*/
NAN_METHOD(GetChainWork) {
NAN_METHOD(GetBlockIndex) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
@ -1000,7 +1002,15 @@ NAN_METHOD(GetChainWork) {
} else {
blockIndex = mapBlockIndex[hash];
arith_uint256 cw = blockIndex->nChainWork;
NanReturnValue(Local<Value>::New(isolate, NanNew<String>(cw.GetHex())));
CBlockIndex* prevBlockIndex = blockIndex->pprev;
const uint256* prevHash = prevBlockIndex->phashBlock;
Local<Object> obj = NanNew<Object>();
obj->Set(NanNew<String>("chainWork"), NanNew<String>(cw.GetHex()));
obj->Set(NanNew<String>("prevHash"), NanNew<String>(prevHash->GetHex()));
NanReturnValue(obj);
}
};
@ -1229,7 +1239,7 @@ init(Handle<Object> target) {
NODE_SET_METHOD(target, "getTransaction", GetTransaction);
NODE_SET_METHOD(target, "getInfo", GetInfo);
NODE_SET_METHOD(target, "isSpent", IsSpent);
NODE_SET_METHOD(target, "getChainWork", GetChainWork);
NODE_SET_METHOD(target, "getBlockIndex", GetBlockIndex);
NODE_SET_METHOD(target, "getMempoolOutputs", GetMempoolOutputs);
NODE_SET_METHOD(target, "addMempoolUncheckedTransaction", AddMempoolUncheckedTransaction);
NODE_SET_METHOD(target, "verifyScript", VerifyScript);

View File

@ -23,7 +23,7 @@ NAN_METHOD(GetBlock);
NAN_METHOD(GetTransaction);
NAN_METHOD(GetInfo);
NAN_METHOD(IsSpent);
NAN_METHOD(GetChainWork);
NAN_METHOD(GetBlockIndex);
NAN_METHOD(GetMempoolOutputs);
NAN_METHOD(AddMempoolUncheckedTransaction);
NAN_METHOD(VerifyScript);

View File

@ -93,20 +93,22 @@ describe('Bitcoin Chain', function() {
var chain = new Chain();
chain.db = {
bitcoind: {
getChainWork: sinon.stub().returns(work)
getBlockIndex: sinon.stub().returns({
chainWork: work
})
}
};
it('should give the weight as a BN', function(done) {
chain.getWeight('hash', function(err, weight) {
should.not.exist(err);
weight.toString(16).should.equal('5a7b3c42ea8b844374e9');
weight.toString(16, 64).should.equal(work);
done();
});
});
it('should give an error if the weight is undefined', function(done) {
chain.db.bitcoind.getChainWork = sinon.stub().returns(undefined);
chain.db.bitcoind.getBlockIndex = sinon.stub().returns(undefined);
chain.getWeight('hash2', function(err, weight) {
should.exist(err);
done();

View File

@ -42,12 +42,10 @@ describe('Bitcoin DB', function() {
});
describe('#putBlock', function() {
it('should call _updatePrevHashIndex', function(done) {
it('should call callback', function(done) {
var db = new DB({store: memdown});
db._updatePrevHashIndex = sinon.stub().callsArg(1);
db.putBlock('block', function(err) {
should.not.exist(err);
db._updatePrevHashIndex.called.should.equal(true);
done();
});
});