Skip to content

Commit 2f6fc6e

Browse files
author
Braydon Fuller
committed
Merge pull request #202 from pnagurny/feature/main-chain
Add isMainChain method
2 parents 2469c6d + 83a83b4 commit 2f6fc6e

File tree

7 files changed

+56
-2
lines changed

7 files changed

+56
-2
lines changed

docs/services/bitcoind.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ The bitcoin service adds a native interface to Bitcoin Core for querying informa
88
- `bitcoind.getBlock(blockHash|blockHeight, callback)` - Get any block asynchronously by block hash or height as a node buffer.
99
- `bitcoind.isSpent(txid, outputIndex)` - Returns a boolean if a txid and outputIndex is already spent.
1010
- `bitcoind.getBlockIndex(blockHash)` - Will return the block chain work and previous hash.
11+
- `bitcoind.isMainChain(blockHash)` - Returns true if block is on the main chain. Returns false if it is an orphan.
1112
- `bitcoind.estimateFee(blocks)` - Estimates the fees required to have a transaction included in the number of blocks specified as the first argument.
1213
- `bitcoind.sendTransaction(transaction, allowAbsurdFees)` - Will attempt to add a transaction to the mempool and broadcast to peers.
1314
- `bitcoind.getTransaction(txid, queryMempool, callback)` - Get any tx asynchronously by reading it from disk, with an argument to optionally not include the mempool.

integration/regtest-node.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ describe('Node Functionality', function() {
137137
});
138138
});
139139

140+
var invalidatedBlockHash;
141+
140142
it('will handle a reorganization', function(done) {
141143

142144
var count;
@@ -157,12 +159,12 @@ describe('Node Functionality', function() {
157159
if (err) {
158160
return next(err);
159161
}
160-
blockHash = response.result;
162+
invalidatedBlockHash = response.result;
161163
next();
162164
});
163165
},
164166
function(next) {
165-
client.invalidateBlock(blockHash, next);
167+
client.invalidateBlock(invalidatedBlockHash, next);
166168
},
167169
function(next) {
168170
client.getBlockCount(function(err, response) {
@@ -212,4 +214,9 @@ describe('Node Functionality', function() {
212214
});
213215

214216
});
217+
218+
it('isMainChain() will return false for stale/orphan block', function(done) {
219+
node.services.bitcoind.isMainChain(invalidatedBlockHash).should.equal(false);
220+
setImmediate(done);
221+
});
215222
});

integration/regtest.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,14 @@ describe('Daemon Binding Functionality', function() {
251251
});
252252
});
253253

254+
describe('isMainChain', function() {
255+
[1,2,3,4,5,6,7,8,9].forEach(function(i) {
256+
it('block ' + i + ' is on the main chain', function() {
257+
bitcoind.isMainChain(blockHashes[i]).should.equal(true);
258+
});
259+
});
260+
});
261+
254262
describe('send transaction functionality', function() {
255263

256264
it('will not error and return the transaction hash', function() {

lib/services/bitcoind.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ Bitcoin.prototype.getBlockIndex = function(blockHash) {
189189
return bindings.getBlockIndex(blockHash);
190190
};
191191

192+
Bitcoin.prototype.isMainChain = function(blockHash) {
193+
return bindings.isMainChain(blockHash);
194+
};
195+
192196
Bitcoin.prototype.estimateFee = function(blocks) {
193197
return bindings.estimateFee(blocks);
194198
};

src/libbitcoind.cc

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,6 +1350,36 @@ NAN_METHOD(GetBlockIndex) {
13501350
NanReturnValue(obj);
13511351
};
13521352

1353+
1354+
/**
1355+
* IsMainChain()
1356+
* bitcoind.isMainChain()
1357+
*
1358+
* @param {string} - block hash
1359+
* @returns {boolean} - True if the block is in the main chain. False if it is an orphan.
1360+
*/
1361+
NAN_METHOD(IsMainChain) {
1362+
Isolate* isolate = Isolate::GetCurrent();
1363+
HandleScope scope(isolate);
1364+
1365+
CBlockIndex* blockIndex;
1366+
1367+
String::Utf8Value hash_(args[0]->ToString());
1368+
std::string hashStr = std::string(*hash_);
1369+
uint256 hash = uint256S(hashStr);
1370+
if (mapBlockIndex.count(hash) == 0) {
1371+
NanReturnValue(Undefined(isolate));
1372+
} else {
1373+
blockIndex = mapBlockIndex[hash];
1374+
}
1375+
1376+
if (chainActive.Contains(blockIndex)) {
1377+
NanReturnValue(NanNew<Boolean>(true));
1378+
} else {
1379+
NanReturnValue(NanNew<Boolean>(false));
1380+
}
1381+
}
1382+
13531383
/**
13541384
* GetInfo()
13551385
* bitcoindjs.getInfo()
@@ -1606,6 +1636,7 @@ init(Handle<Object> target) {
16061636
NODE_SET_METHOD(target, "getInfo", GetInfo);
16071637
NODE_SET_METHOD(target, "isSpent", IsSpent);
16081638
NODE_SET_METHOD(target, "getBlockIndex", GetBlockIndex);
1639+
NODE_SET_METHOD(target, "isMainChain", IsMainChain);
16091640
NODE_SET_METHOD(target, "getMempoolOutputs", GetMempoolOutputs);
16101641
NODE_SET_METHOD(target, "addMempoolUncheckedTransaction", AddMempoolUncheckedTransaction);
16111642
NODE_SET_METHOD(target, "sendTransaction", SendTransaction);

src/libbitcoind.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ NAN_METHOD(OnBlocksReady);
2222
NAN_METHOD(OnTipUpdate);
2323
NAN_METHOD(StopBitcoind);
2424
NAN_METHOD(GetBlock);
25+
NAN_METHOD(GetBlockIndex);
26+
NAN_METHOD(IsMainChain);
2527
NAN_METHOD(GetTransaction);
2628
NAN_METHOD(GetInfo);
2729
NAN_METHOD(IsSpent);

test/services/bitcoind.unit.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ describe('Bitcoin Service', function() {
371371
['getBlock', 2],
372372
['isSpent', 2],
373373
['getBlockIndex', 1],
374+
['isMainChain', 1],
374375
['estimateFee', 1],
375376
['sendTransaction', 2],
376377
['getTransaction', 3],

0 commit comments

Comments
 (0)