From 0c983c9c4afcd379ff3802cff7a9cff9ed3494db Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Wed, 3 Feb 2016 17:57:44 -0500 Subject: [PATCH] Networks: Added regtest to networks Brings better compatibility between "testnet" and "regtest". Services such as Bitcore Wallet Service and wallets such as Copay that have "testnet" and not "regtest" will be compatible with "regtest" if enabled in a Bitcore node. This adds two new API methods to enable/disable regtest on the testnet network: - `bitcore.Networks.enableRegtest()` - `bitcore.Networks.disableRegtest()` --- docs/networks.md | 17 +++++++ lib/networks.js | 127 ++++++++++++++++++++++++++++++++++++++++------- test/networks.js | 23 +++++++++ 3 files changed, 150 insertions(+), 17 deletions(-) diff --git a/docs/networks.md b/docs/networks.md index 0922cd17a..e8a54e20a 100644 --- a/docs/networks.md +++ b/docs/networks.md @@ -3,6 +3,23 @@ Bitcore provides support for the main bitcoin network as well as for `testnet3`, The `Network` namespace has a function, `get(...)` that returns an instance of a `Network` or `undefined`. The only argument to this function is some kind of identifier of the network: either its name, a reference to a Network object, or a number used as a magic constant to identify the network (for example, the value `0` that gives bitcoin addresses the distinctive `'1'` at its beginning on livenet, is a `0x6F` for testnet). +## Regtest + +The regtest network is useful for development as it's possible to programmatically and instantly generate blocks for testing. It's currently supported as a variation of testnet. Here is an example of how to use regtest with the Bitcore Library: + +```js +// Standard testnet +> bitcore.Networks.testnet.networkMagic; + +``` + +```js +// Enabling testnet to use the regtest port and magicNumber +> bitcore.Networks.enableRegtest(); +> bitcore.Networks.testnet.networkMagic; + +``` + ## Setting the Default Network Most projects will only need to work with one of the networks. The value of `Networks.defaultNetwork` can be set to `Networks.testnet` if the project will need to only to work on testnet (the default is `Networks.livenet`). diff --git a/lib/networks.js b/lib/networks.js index 3ea7c010c..3a9381c5d 100644 --- a/lib/networks.js +++ b/lib/networks.js @@ -75,12 +75,26 @@ function addNetwork(data) { privatekey: data.privatekey, scripthash: data.scripthash, xpubkey: data.xpubkey, - xprivkey: data.xprivkey, - networkMagic: BufferUtil.integerAsBuffer(data.networkMagic), - port: data.port, - dnsSeeds: data.dnsSeeds + xprivkey: data.xprivkey }); + if (data.networkMagic) { + JSUtil.defineImmutable(network, { + networkMagic: BufferUtil.integerAsBuffer(data.networkMagic) + }); + } + + if (data.port) { + JSUtil.defineImmutable(network, { + port: data.port + }); + } + + if (data.dnsSeeds) { + JSUtil.defineImmutable(network, { + dnsSeeds: data.dnsSeeds + }); + } _.each(network, function(value) { if (!_.isUndefined(value) && !_.isObject(value)) { networkMaps[value] = network; @@ -132,35 +146,112 @@ addNetwork({ ] }); +/** + * @instance + * @member Networks#livenet + */ +var livenet = get('livenet'); + addNetwork({ name: 'testnet', - alias: 'testnet', + alias: 'regtest', pubkeyhash: 0x6f, privatekey: 0xef, scripthash: 0xc4, xpubkey: 0x043587cf, - xprivkey: 0x04358394, - networkMagic: 0x0b110907, - port: 18333, - dnsSeeds: [ + xprivkey: 0x04358394 +}); + +/** + * @instance + * @member Networks#testnet + */ +var testnet = get('testnet'); + +// Add configurable values for testnet/regtest + +var TESTNET = { + PORT: 18333, + NETWORK_MAGIC: BufferUtil.integerAsBuffer(0x0b110907), + DNS_SEEDS: [ 'testnet-seed.bitcoin.petertodd.org', 'testnet-seed.bluematt.me', 'testnet-seed.alexykot.me', 'testnet-seed.bitcoin.schildbach.de' - ], + ] +}; + +for (var key in TESTNET) { + if (!_.isObject(TESTNET[key])) { + networkMaps[TESTNET[key]] = testnet; + } +} + +var REGTEST = { + PORT: 18444, + NETWORK_MAGIC: BufferUtil.integerAsBuffer(0xfabfb5da), + DNS_SEEDS: [] +}; + +for (var key in REGTEST) { + if (!_.isObject(REGTEST[key])) { + networkMaps[REGTEST[key]] = testnet; + } +} + +Object.defineProperty(testnet, 'port', { + enumerable: true, + configurable: false, + get: function() { + if (this.regtestEnabled) { + return REGTEST.PORT; + } else { + return TESTNET.PORT; + } + } +}); + +Object.defineProperty(testnet, 'networkMagic', { + enumerable: true, + configurable: false, + get: function() { + if (this.regtestEnabled) { + return REGTEST.NETWORK_MAGIC; + } else { + return TESTNET.NETWORK_MAGIC; + } + } +}); + +Object.defineProperty(testnet, 'dnsSeeds', { + enumerable: true, + configurable: false, + get: function() { + if (this.regtestEnabled) { + return REGTEST.DNS_SEEDS; + } else { + return TESTNET.DNS_SEEDS; + } + } }); /** - * @instance - * @member Networks#livenet + * @function + * @member Networks#enableRegtest + * Will enable regtest features for testnet */ -var livenet = get('livenet'); +function enableRegtest() { + testnet.regtestEnabled = true; +} /** - * @instance - * @member Networks#testnet + * @function + * @member Networks#disableRegtest + * Will disable regtest features for testnet */ -var testnet = get('testnet'); +function disableRegtest() { + testnet.regtestEnabled = false; +} /** * @namespace Networks @@ -172,5 +263,7 @@ module.exports = { livenet: livenet, mainnet: livenet, testnet: testnet, - get: get + get: get, + enableRegtest: enableRegtest, + disableRegtest: disableRegtest }; diff --git a/test/networks.js b/test/networks.js index c3f9b8be1..7d82f927f 100644 --- a/test/networks.js +++ b/test/networks.js @@ -15,6 +15,29 @@ describe('Networks', function() { should.exist(networks.defaultNetwork); }); + it('will enable/disable regtest Network', function() { + networks.enableRegtest(); + networks.testnet.networkMagic.should.deep.equal(new Buffer('fabfb5da', 'hex')); + networks.testnet.port.should.equal(18444); + networks.testnet.dnsSeeds.should.deep.equal([]); + networks.testnet.regtestEnabled.should.equal(true); + + networks.disableRegtest(); + networks.testnet.networkMagic.should.deep.equal(new Buffer('0b110907', 'hex')); + networks.testnet.port.should.equal(18333); + networks.testnet.dnsSeeds.should.deep.equal([ + 'testnet-seed.bitcoin.petertodd.org', + 'testnet-seed.bluematt.me', + 'testnet-seed.alexykot.me', + 'testnet-seed.bitcoin.schildbach.de' + ]); + }); + + it('will get network based on string "regtest" value', function() { + var network = networks.get('regtest'); + network.should.equal(networks.testnet); + }); + it('should be able to define a custom Network', function() { var custom = { name: 'customnet',