diff --git a/docs/networks.md b/docs/networks.md index 0922cd1..e8a54e2 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 3ea7c01..3a9381c 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,36 +146,113 @@ addNetwork({ ] }); -addNetwork({ - name: 'testnet', - alias: 'testnet', - pubkeyhash: 0x6f, - privatekey: 0xef, - scripthash: 0xc4, - xpubkey: 0x043587cf, - xprivkey: 0x04358394, - networkMagic: 0x0b110907, - port: 18333, - dnsSeeds: [ - 'testnet-seed.bitcoin.petertodd.org', - 'testnet-seed.bluematt.me', - 'testnet-seed.alexykot.me', - 'testnet-seed.bitcoin.schildbach.de' - ], -}); - /** * @instance * @member Networks#livenet */ var livenet = get('livenet'); +addNetwork({ + name: 'testnet', + alias: 'regtest', + pubkeyhash: 0x6f, + privatekey: 0xef, + scripthash: 0xc4, + xpubkey: 0x043587cf, + 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; + } + } +}); + +/** + * @function + * @member Networks#enableRegtest + * Will enable regtest features for testnet + */ +function enableRegtest() { + testnet.regtestEnabled = true; +} + +/** + * @function + * @member Networks#disableRegtest + * Will disable regtest features for 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 c3f9b8b..7d82f92 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',