Skip to content

Commit

Permalink
Merge pull request #202 from pnagurny/feature/main-chain
Browse files Browse the repository at this point in the history
Add isMainChain method
  • Loading branch information
Braydon Fuller committed Sep 9, 2015
2 parents 2469c6d + 83a83b4 commit 2f6fc6e
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/services/bitcoind.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ The bitcoin service adds a native interface to Bitcoin Core for querying informa
- `bitcoind.getBlock(blockHash|blockHeight, callback)` - Get any block asynchronously by block hash or height as a node buffer.
- `bitcoind.isSpent(txid, outputIndex)` - Returns a boolean if a txid and outputIndex is already spent.
- `bitcoind.getBlockIndex(blockHash)` - Will return the block chain work and previous hash.
- `bitcoind.isMainChain(blockHash)` - Returns true if block is on the main chain. Returns false if it is an orphan.
- `bitcoind.estimateFee(blocks)` - Estimates the fees required to have a transaction included in the number of blocks specified as the first argument.
- `bitcoind.sendTransaction(transaction, allowAbsurdFees)` - Will attempt to add a transaction to the mempool and broadcast to peers.
- `bitcoind.getTransaction(txid, queryMempool, callback)` - Get any tx asynchronously by reading it from disk, with an argument to optionally not include the mempool.
Expand Down
11 changes: 9 additions & 2 deletions integration/regtest-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ describe('Node Functionality', function() {
});
});

var invalidatedBlockHash;

it('will handle a reorganization', function(done) {

var count;
Expand All @@ -157,12 +159,12 @@ describe('Node Functionality', function() {
if (err) {
return next(err);
}
blockHash = response.result;
invalidatedBlockHash = response.result;
next();
});
},
function(next) {
client.invalidateBlock(blockHash, next);
client.invalidateBlock(invalidatedBlockHash, next);
},
function(next) {
client.getBlockCount(function(err, response) {
Expand Down Expand Up @@ -212,4 +214,9 @@ describe('Node Functionality', function() {
});

});

it('isMainChain() will return false for stale/orphan block', function(done) {
node.services.bitcoind.isMainChain(invalidatedBlockHash).should.equal(false);
setImmediate(done);
});
});
8 changes: 8 additions & 0 deletions integration/regtest.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,14 @@ describe('Daemon Binding Functionality', function() {
});
});

describe('isMainChain', function() {
[1,2,3,4,5,6,7,8,9].forEach(function(i) {
it('block ' + i + ' is on the main chain', function() {
bitcoind.isMainChain(blockHashes[i]).should.equal(true);
});
});
});

describe('send transaction functionality', function() {

it('will not error and return the transaction hash', function() {
Expand Down
4 changes: 4 additions & 0 deletions lib/services/bitcoind.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ Bitcoin.prototype.getBlockIndex = function(blockHash) {
return bindings.getBlockIndex(blockHash);
};

Bitcoin.prototype.isMainChain = function(blockHash) {
return bindings.isMainChain(blockHash);
};

Bitcoin.prototype.estimateFee = function(blocks) {
return bindings.estimateFee(blocks);
};
Expand Down
31 changes: 31 additions & 0 deletions src/libbitcoind.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1350,6 +1350,36 @@ NAN_METHOD(GetBlockIndex) {
NanReturnValue(obj);
};


/**
* IsMainChain()
* bitcoind.isMainChain()
*
* @param {string} - block hash
* @returns {boolean} - True if the block is in the main chain. False if it is an orphan.
*/
NAN_METHOD(IsMainChain) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);

CBlockIndex* blockIndex;

String::Utf8Value hash_(args[0]->ToString());
std::string hashStr = std::string(*hash_);
uint256 hash = uint256S(hashStr);
if (mapBlockIndex.count(hash) == 0) {
NanReturnValue(Undefined(isolate));
} else {
blockIndex = mapBlockIndex[hash];
}

if (chainActive.Contains(blockIndex)) {
NanReturnValue(NanNew<Boolean>(true));
} else {
NanReturnValue(NanNew<Boolean>(false));
}
}

/**
* GetInfo()
* bitcoindjs.getInfo()
Expand Down Expand Up @@ -1606,6 +1636,7 @@ init(Handle<Object> target) {
NODE_SET_METHOD(target, "getInfo", GetInfo);
NODE_SET_METHOD(target, "isSpent", IsSpent);
NODE_SET_METHOD(target, "getBlockIndex", GetBlockIndex);
NODE_SET_METHOD(target, "isMainChain", IsMainChain);
NODE_SET_METHOD(target, "getMempoolOutputs", GetMempoolOutputs);
NODE_SET_METHOD(target, "addMempoolUncheckedTransaction", AddMempoolUncheckedTransaction);
NODE_SET_METHOD(target, "sendTransaction", SendTransaction);
Expand Down
2 changes: 2 additions & 0 deletions src/libbitcoind.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ NAN_METHOD(OnBlocksReady);
NAN_METHOD(OnTipUpdate);
NAN_METHOD(StopBitcoind);
NAN_METHOD(GetBlock);
NAN_METHOD(GetBlockIndex);
NAN_METHOD(IsMainChain);
NAN_METHOD(GetTransaction);
NAN_METHOD(GetInfo);
NAN_METHOD(IsSpent);
Expand Down
1 change: 1 addition & 0 deletions test/services/bitcoind.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ describe('Bitcoin Service', function() {
['getBlock', 2],
['isSpent', 2],
['getBlockIndex', 1],
['isMainChain', 1],
['estimateFee', 1],
['sendTransaction', 2],
['getTransaction', 3],
Expand Down

0 comments on commit 2f6fc6e

Please sign in to comment.