Added regtests for all routes.
This commit is contained in:
parent
da8920c4dc
commit
32155cead7
299
package-lock.json
generated
299
package-lock.json
generated
@ -65,6 +65,12 @@
|
||||
"integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=",
|
||||
"optional": true
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
},
|
||||
"base64-arraybuffer": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
|
||||
@ -143,6 +149,12 @@
|
||||
"safe-buffer": "5.1.1"
|
||||
}
|
||||
},
|
||||
"bitcoind-rpc": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/bitcoind-rpc/-/bitcoind-rpc-0.7.0.tgz",
|
||||
"integrity": "sha1-2/YkkmfuMovkjeV3hwQpgAksi/I=",
|
||||
"dev": true
|
||||
},
|
||||
"bitcore-lib": {
|
||||
"version": "5.0.0-beta.1",
|
||||
"resolved": "https://registry.npmjs.org/bitcore-lib/-/bitcore-lib-5.0.0-beta.1.tgz",
|
||||
@ -239,6 +251,95 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"bitcore-p2p": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bitcore-p2p/-/bitcore-p2p-1.1.2.tgz",
|
||||
"integrity": "sha1-F5J8UiE92vDLQGczMrozleQAi1Q=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bitcore-lib": "0.14.0",
|
||||
"bloom-filter": "0.2.0",
|
||||
"buffers": "github:bitpay/node-buffers#04f4c4264e0d105db2b99b786843ed64f23230d8",
|
||||
"socks5-client": "0.3.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"bitcore-lib": {
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/bitcore-lib/-/bitcore-lib-0.14.0.tgz",
|
||||
"integrity": "sha1-IcsjWf57mXo7e3c+t9cnWuN9ZE4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bn.js": "2.0.4",
|
||||
"bs58": "2.0.0",
|
||||
"buffer-compare": "1.0.0",
|
||||
"elliptic": "3.0.3",
|
||||
"inherits": "2.0.1",
|
||||
"lodash": "3.10.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"bn.js": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-2.0.4.tgz",
|
||||
"integrity": "sha1-Igp81nf38b+pNif/QZN3b+eBlIA=",
|
||||
"dev": true
|
||||
},
|
||||
"bs58": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bs58/-/bs58-2.0.0.tgz",
|
||||
"integrity": "sha1-crcTvtIjoKxRi72g484/SBfznrU=",
|
||||
"dev": true
|
||||
},
|
||||
"buffer-compare": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer-compare/-/buffer-compare-1.0.0.tgz",
|
||||
"integrity": "sha1-rKp6lm6Y7un64Usxw5pfFY+zxKI=",
|
||||
"dev": true
|
||||
},
|
||||
"elliptic": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-3.0.3.tgz",
|
||||
"integrity": "sha1-hlybQgv75VAGuflp+XoNLESWZZU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bn.js": "2.0.4",
|
||||
"brorand": "1.0.5",
|
||||
"hash.js": "1.0.3",
|
||||
"inherits": "2.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"brorand": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.0.5.tgz",
|
||||
"integrity": "sha1-B7VMowKGq9Fxig4qgwgD79yb+gQ=",
|
||||
"dev": true
|
||||
},
|
||||
"hash.js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz",
|
||||
"integrity": "sha1-EzL/ABVsCg/92CNgE9B7d6BFFXM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"inherits": "2.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
|
||||
"integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
|
||||
"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"bl": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz",
|
||||
@ -253,6 +354,12 @@
|
||||
"resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
|
||||
"integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE="
|
||||
},
|
||||
"bloom-filter": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/bloom-filter/-/bloom-filter-0.2.0.tgz",
|
||||
"integrity": "sha1-hNY7v5Fy2DA+ZMH/FuudvzOpgaM=",
|
||||
"dev": true
|
||||
},
|
||||
"bn.js": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-2.0.4.tgz",
|
||||
@ -407,6 +514,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.8",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
|
||||
"integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"brorand": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
|
||||
@ -441,6 +558,10 @@
|
||||
"integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
|
||||
"optional": true
|
||||
},
|
||||
"buffers": {
|
||||
"version": "github:bitpay/node-buffers#04f4c4264e0d105db2b99b786843ed64f23230d8",
|
||||
"dev": true
|
||||
},
|
||||
"callsite": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
|
||||
@ -503,11 +624,37 @@
|
||||
"safe-buffer": "5.1.1"
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"version": "0.4.5",
|
||||
"resolved": "https://registry.npmjs.org/cli/-/cli-0.4.5.tgz",
|
||||
"integrity": "sha1-ePlIXNFhtWbppsctcXDEJw6B22E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "7.1.2"
|
||||
}
|
||||
},
|
||||
"cliff": {
|
||||
"version": "0.1.10",
|
||||
"resolved": "https://registry.npmjs.org/cliff/-/cliff-0.1.10.tgz",
|
||||
"integrity": "sha1-U74z6p9ZvshWCe4wCsQgdgPlIBM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"colors": "1.0.3",
|
||||
"eyes": "0.1.8",
|
||||
"winston": "0.8.3"
|
||||
}
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
|
||||
},
|
||||
"colors": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
|
||||
"integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
|
||||
"dev": true
|
||||
},
|
||||
"component-bind": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
|
||||
@ -616,6 +763,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
@ -657,6 +810,12 @@
|
||||
"sha.js": "2.4.8"
|
||||
}
|
||||
},
|
||||
"cycle": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
|
||||
"integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=",
|
||||
"dev": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.8",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
|
||||
@ -769,12 +928,24 @@
|
||||
"integrity": "sha1-bDAzIxd6YrGyLAcCefeGEoe2mxo=",
|
||||
"optional": true
|
||||
},
|
||||
"eyes": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
|
||||
"integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-future": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-future/-/fast-future-1.0.2.tgz",
|
||||
"integrity": "sha1-hDWpqqAteSSNF9cE52JZMB2ZKAo=",
|
||||
"optional": true
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
},
|
||||
"gauge": {
|
||||
"version": "2.7.4",
|
||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
|
||||
@ -797,6 +968,20 @@
|
||||
"integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=",
|
||||
"optional": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "1.0.0",
|
||||
"inflight": "1.0.6",
|
||||
"inherits": "2.0.1",
|
||||
"minimatch": "3.0.4",
|
||||
"once": "1.4.0",
|
||||
"path-is-absolute": "1.0.1"
|
||||
}
|
||||
},
|
||||
"has-binary2": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.2.tgz",
|
||||
@ -862,6 +1047,16 @@
|
||||
"resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
|
||||
"integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "1.4.0",
|
||||
"wrappy": "1.0.2"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
|
||||
@ -873,6 +1068,17 @@
|
||||
"integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
|
||||
"optional": true
|
||||
},
|
||||
"ipv6": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ipv6/-/ipv6-3.1.3.tgz",
|
||||
"integrity": "sha1-TZBk+cLa+g3RC4t9dv/KSq0xs7k=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cli": "0.4.5",
|
||||
"cliff": "0.1.10",
|
||||
"sprintf": "0.1.5"
|
||||
}
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
@ -886,6 +1092,12 @@
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
|
||||
"dev": true
|
||||
},
|
||||
"jsonparse": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
|
||||
@ -972,6 +1184,15 @@
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
|
||||
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "1.1.8"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
@ -1229,6 +1450,12 @@
|
||||
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
|
||||
"optional": true
|
||||
},
|
||||
"network-byte-order": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/network-byte-order/-/network-byte-order-0.2.0.tgz",
|
||||
"integrity": "sha1-asEb9Ev2ENrt2+kKCaXIF8bg0rM=",
|
||||
"dev": true
|
||||
},
|
||||
"node-abi": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.1.0.tgz",
|
||||
@ -1310,6 +1537,18 @@
|
||||
"better-assert": "1.0.2"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
},
|
||||
"pkginfo": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz",
|
||||
"integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=",
|
||||
"dev": true
|
||||
},
|
||||
"prebuild-install": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.2.2.tgz",
|
||||
@ -1808,6 +2047,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
|
||||
"integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "7.1.2"
|
||||
}
|
||||
},
|
||||
"ripemd160": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
|
||||
@ -2055,6 +2303,28 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"socks5-client": {
|
||||
"version": "0.3.6",
|
||||
"resolved": "https://registry.npmjs.org/socks5-client/-/socks5-client-0.3.6.tgz",
|
||||
"integrity": "sha1-QgW1eR8t93zwdSciJVj+TkasovE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ipv6": "3.1.3",
|
||||
"network-byte-order": "0.2.0"
|
||||
}
|
||||
},
|
||||
"sprintf": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/sprintf/-/sprintf-0.1.5.tgz",
|
||||
"integrity": "sha1-j4PjmpMXwaUCy324BQ5Rxnn27c8=",
|
||||
"dev": true
|
||||
},
|
||||
"stack-trace": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
|
||||
"integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=",
|
||||
"dev": true
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
|
||||
@ -2162,6 +2432,35 @@
|
||||
"string-width": "1.0.2"
|
||||
}
|
||||
},
|
||||
"winston": {
|
||||
"version": "0.8.3",
|
||||
"resolved": "https://registry.npmjs.org/winston/-/winston-0.8.3.tgz",
|
||||
"integrity": "sha1-ZLar9M0Brcrv1QCTk7HY6L7BnbA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"async": "0.2.10",
|
||||
"colors": "0.6.2",
|
||||
"cycle": "1.0.3",
|
||||
"eyes": "0.1.8",
|
||||
"isstream": "0.1.2",
|
||||
"pkginfo": "0.3.1",
|
||||
"stack-trace": "0.0.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "0.2.10",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
|
||||
"integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
|
||||
"dev": true
|
||||
},
|
||||
"colors": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
|
||||
"integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
|
||||
@ -21,7 +21,8 @@
|
||||
"node": ">=8.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "NODE_ENV=test mocha -R spec --recursive"
|
||||
"test": "NODE_ENV=test mocha -R spec --recursive",
|
||||
"regtest": "mocha -R spec regtest"
|
||||
},
|
||||
"main": "lib",
|
||||
"bitcoreNode": "lib",
|
||||
@ -39,9 +40,13 @@
|
||||
"request": "^2.64.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bitcoind-rpc": "^0.7.0",
|
||||
"bitcore-p2p": "^1.1.2",
|
||||
"chai": "^3.5.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mocha": "^2.4.5",
|
||||
"proxyquire": "^1.7.2",
|
||||
"rimraf": "^2.6.1",
|
||||
"should": "^8.3.1",
|
||||
"sinon": "^1.10.3"
|
||||
}
|
||||
|
||||
766
regtest/address.js
Normal file
766
regtest/address.js
Normal file
@ -0,0 +1,766 @@
|
||||
'use strict';
|
||||
|
||||
var expect = require('chai').expect;
|
||||
var spawn = require('child_process').spawn;
|
||||
var rimraf = require('rimraf');
|
||||
var mkdirp = require('mkdirp');
|
||||
var fs = require('fs');
|
||||
var async = require('async');
|
||||
var RPC = require('bitcoind-rpc');
|
||||
var http = require('http');
|
||||
|
||||
var rpc1Address;
|
||||
var rpc2Address;
|
||||
|
||||
var rpcConfig = {
|
||||
protocol: 'http',
|
||||
user: 'local',
|
||||
pass: 'localtest',
|
||||
host: '127.0.0.1',
|
||||
port: 58332,
|
||||
rejectUnauthorized: false
|
||||
};
|
||||
|
||||
var rpc1 = new RPC(rpcConfig);
|
||||
rpcConfig.port++;
|
||||
var rpc2 = new RPC(rpcConfig);
|
||||
var debug = true;
|
||||
var bitcoreDataDir = '/tmp/bitcore';
|
||||
var bitcoinDataDirs = ['/tmp/bitcoin1', '/tmp/bitcoin2'];
|
||||
|
||||
var bitcoin = {
|
||||
args: {
|
||||
datadir: null,
|
||||
listen: 1,
|
||||
regtest: 1,
|
||||
server: 1,
|
||||
rpcuser: 'local',
|
||||
rpcpassword: 'localtest',
|
||||
//printtoconsole: 1
|
||||
rpcport: 58332,
|
||||
},
|
||||
datadir: null,
|
||||
exec: 'bitcoind', //if this isn't on your PATH, then provide the absolute path, e.g. /usr/local/bin/bitcoind
|
||||
processes: []
|
||||
};
|
||||
|
||||
var bitcore = {
|
||||
configFile: {
|
||||
file: bitcoreDataDir + '/bitcore-node.json',
|
||||
conf: {
|
||||
network: 'regtest',
|
||||
port: 53001,
|
||||
datadir: bitcoreDataDir,
|
||||
services: [
|
||||
'p2p',
|
||||
'db',
|
||||
'header',
|
||||
'block',
|
||||
'address',
|
||||
'transaction',
|
||||
'mempool',
|
||||
'web',
|
||||
'insight-api',
|
||||
'fee',
|
||||
'timestamp'
|
||||
],
|
||||
servicesConfig: {
|
||||
'p2p': {
|
||||
'peers': [
|
||||
{ 'ip': { 'v4': '127.0.0.1' }, port: 18444 }
|
||||
]
|
||||
},
|
||||
'insight-api': {
|
||||
'routePrefix': 'api'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
httpOpts: {
|
||||
protocol: 'http:',
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
},
|
||||
opts: { cwd: bitcoreDataDir },
|
||||
datadir: bitcoreDataDir,
|
||||
exec: 'bitcored', //if this isn't on your PATH, then provide the absolute path, e.g. /usr/local/bin/bitcored
|
||||
args: ['start'],
|
||||
process: null
|
||||
};
|
||||
|
||||
var startBitcoind = function(count, callback) {
|
||||
|
||||
var listenCount = 0;
|
||||
async.timesSeries(count, function(n, next) {
|
||||
|
||||
var datadir = bitcoinDataDirs.shift();
|
||||
|
||||
bitcoin.datadir = datadir;
|
||||
bitcoin.args.datadir = datadir;
|
||||
|
||||
if (listenCount++ > 0) {
|
||||
bitcoin.args.listen = 0;
|
||||
bitcoin.args.rpcport++;
|
||||
bitcoin.args.connect = '127.0.0.1';
|
||||
}
|
||||
|
||||
rimraf(datadir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
mkdirp(datadir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
var args = bitcoin.args;
|
||||
var argList = Object.keys(args).map(function(key) {
|
||||
return '-' + key + '=' + args[key];
|
||||
});
|
||||
|
||||
var bitcoinProcess = spawn(bitcoin.exec, argList, bitcoin.opts);
|
||||
bitcoin.processes.push(bitcoinProcess);
|
||||
|
||||
bitcoinProcess.stdout.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stdout.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
bitcoinProcess.stderr.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stderr.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
next();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
}, function(err) {
|
||||
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var pids = bitcoin.processes.map(function(process) {
|
||||
return process.pid;
|
||||
});
|
||||
|
||||
console.log(count + ' bitcoind\'s started at pid(s): ' + pids);
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
var shutdownBitcoind = function(callback) {
|
||||
bitcoin.processes.forEach(function(process) {
|
||||
process.kill();
|
||||
});
|
||||
setTimeout(callback, 3000);
|
||||
};
|
||||
|
||||
var shutdownBitcore = function(callback) {
|
||||
if (bitcore.process) {
|
||||
bitcore.process.kill();
|
||||
}
|
||||
callback();
|
||||
};
|
||||
|
||||
var txid;
|
||||
var buildInitialChain = function(callback) {
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
console.log('checking to see if bitcoind\'s are connected to each other.');
|
||||
rpc1.getinfo(function(err, res) {
|
||||
if (err || res.result.connections !== 1) {
|
||||
next(err || new Error('bitcoind\'s not connected to each other.'));
|
||||
}
|
||||
next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
console.log('generating 101 blocks');
|
||||
rpc1.generate(101, next);
|
||||
},
|
||||
function(res, next) {
|
||||
console.log('getting new address from rpc2');
|
||||
rpc2.getNewAddress(function(err, res) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
rpc2Address = res.result;
|
||||
console.log(rpc2Address);
|
||||
next(null, rpc2Address);
|
||||
});
|
||||
},
|
||||
function(addr, next) {
|
||||
rpc1.sendToAddress(rpc2Address, 25, next);
|
||||
},
|
||||
function(res, next) {
|
||||
console.log('TXID: ' + res.result);
|
||||
console.log('generating 6 blocks');
|
||||
rpc1.generate(7, next);
|
||||
},
|
||||
function(res, next) {
|
||||
rpc2.getBalance(function(err, res) {
|
||||
console.log(res);
|
||||
next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
console.log('getting new address from rpc1');
|
||||
rpc1.getNewAddress(function(err, res) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
rpc1Address = res.result;
|
||||
next(null, rpc1Address);
|
||||
});
|
||||
},
|
||||
function(addr, next) {
|
||||
rpc2.sendToAddress(rpc1Address, 20, next);
|
||||
},
|
||||
function(res, next) {
|
||||
txid = res.result;
|
||||
console.log('sending from rpc2Address TXID: ', res);
|
||||
console.log('generating 6 blocks');
|
||||
rpc2.generate(6, next);
|
||||
}
|
||||
], function(err) {
|
||||
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
rpc1.getInfo(function(err, res) {
|
||||
console.log(res);
|
||||
callback();
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
var startBitcore = function(callback) {
|
||||
|
||||
rimraf(bitcoreDataDir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
mkdirp(bitcoreDataDir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
fs.writeFileSync(bitcore.configFile.file, JSON.stringify(bitcore.configFile.conf));
|
||||
|
||||
var args = bitcore.args;
|
||||
bitcore.process = spawn(bitcore.exec, args, bitcore.opts);
|
||||
|
||||
bitcore.process.stdout.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stdout.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
bitcore.process.stderr.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stderr.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
callback();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
describe('Address', function() {
|
||||
|
||||
this.timeout(60000);
|
||||
|
||||
before(function(done) {
|
||||
|
||||
async.series([
|
||||
function(next) {
|
||||
startBitcoind(2, next);
|
||||
},
|
||||
function(next) {
|
||||
setTimeout(function() {
|
||||
buildInitialChain(next);
|
||||
}, 8000);
|
||||
},
|
||||
function(next) {
|
||||
setTimeout(function() {
|
||||
startBitcore(next);
|
||||
}, 6000);
|
||||
}
|
||||
], function(err) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
setTimeout(done, 2000);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
shutdownBitcore(function() {
|
||||
shutdownBitcoind(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should get address info correctly: /addr/:addr', function(done) {
|
||||
|
||||
|
||||
var request = http.request('http://localhost:53001/api/addr/' + rpc2Address, function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(data);
|
||||
expect(data.balance).to.equal(0);
|
||||
expect(data.totalSent).to.equal(25);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
request.write('');
|
||||
request.end();
|
||||
});
|
||||
|
||||
it('should get a utxo: /addr/:addr/utxo', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/addr/' + rpc1Address + '/utxo', function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(data);
|
||||
expect(data.length).equal(1);
|
||||
expect(data[0].amount).equal(20);
|
||||
expect(data[0].satoshis).equal(2000000000);
|
||||
expect(data[0].confirmations).equal(6);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
request.write('');
|
||||
request.end();
|
||||
|
||||
});
|
||||
|
||||
it('should get multi-address utxos: /addrs/:addrs/utxo', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/addrs/' + rpc2Address + ',' + rpc1Address + '/utxo', function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(data);
|
||||
expect(data.length).to.equal(1);
|
||||
expect(data[0].amount).to.equal(20);
|
||||
expect(data[0].satoshis).to.equal(2000000000);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
request.write('');
|
||||
request.end();
|
||||
|
||||
});
|
||||
|
||||
it('should post a utxo: /addrs/:addrs/utxo', function(done) {
|
||||
|
||||
var body = JSON.stringify({
|
||||
addrs: [ rpc1Address, rpc2Address ]
|
||||
});
|
||||
|
||||
var httpOpts = {
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
path: '/api/addrs/utxo',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': body.length
|
||||
}
|
||||
};
|
||||
|
||||
var request = http.request(httpOpts, function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(data);
|
||||
expect(data.length).to.equal(1);
|
||||
expect(data[0].amount).to.equal(20);
|
||||
expect(data[0].satoshis).to.equal(2000000000);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
request.write(body);
|
||||
request.end();
|
||||
|
||||
});
|
||||
|
||||
it('should get txs for a set of addresses: /addrs/:addrs/txs', function(done) {
|
||||
|
||||
var httpOpts = {
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
path: '/api/addrs/' + rpc1Address + ',' + rpc2Address + '/txs',
|
||||
method: 'GET'
|
||||
};
|
||||
|
||||
var request = http.request(httpOpts, function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(resData);
|
||||
expect(data.items.length).to.equal(3);
|
||||
expect(data.from).to.equal(0);
|
||||
expect(data.to).to.equal(3);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
request.write('');
|
||||
request.end();
|
||||
|
||||
});
|
||||
|
||||
it('should post txs for a set of addresses: /addrs/txs', function(done) {
|
||||
|
||||
var body = JSON.stringify({
|
||||
addrs: [ rpc1Address, rpc2Address ]
|
||||
});
|
||||
|
||||
var httpOpts = {
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
path: '/api/addrs/txs',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
var request = http.request(httpOpts, function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(resData);
|
||||
expect(data.items.length).to.equal(3);
|
||||
expect(data.from).to.equal(0);
|
||||
expect(data.to).to.equal(3);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
request.write(body);
|
||||
request.end();
|
||||
|
||||
});
|
||||
|
||||
it('should get totalReceived for an address: /addr/:addr/totalReceived', function(done) {
|
||||
|
||||
var httpOpts = {
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
path: '/api/addr/' + rpc1Address + '/totalReceived',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
var request = http.request(httpOpts, function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
var data = JSON.parse(resData);
|
||||
expect(data).to.equal(2000000000);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
request.write('');
|
||||
request.end();
|
||||
|
||||
});
|
||||
|
||||
it('should get totalSent for an address: /addr/:addr/totalSent', function(done) {
|
||||
|
||||
var httpOpts = {
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
path: '/api/addr/' + rpc1Address + '/totalSent',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
var request = http.request(httpOpts, function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
expect(data).to.equal(0);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
request.write('');
|
||||
request.end();
|
||||
|
||||
});
|
||||
|
||||
it('should get unconfirmedBalance for an address: /addr/:addr/unconfirmedBalance', function(done) {
|
||||
|
||||
var httpOpts = {
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
path: '/api/addr/' + rpc1Address + '/unconfirmedBalance',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
var request = http.request(httpOpts, function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
expect(data).to.equal(0);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
request.write('');
|
||||
request.end();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
500
regtest/block.js
Normal file
500
regtest/block.js
Normal file
@ -0,0 +1,500 @@
|
||||
'use strict';
|
||||
|
||||
var expect = require('chai').expect;
|
||||
var spawn = require('child_process').spawn;
|
||||
var rimraf = require('rimraf');
|
||||
var mkdirp = require('mkdirp');
|
||||
var fs = require('fs');
|
||||
var async = require('async');
|
||||
var RPC = require('bitcoind-rpc');
|
||||
var http = require('http');
|
||||
|
||||
var rpc1Address;
|
||||
var rpc2Address;
|
||||
var tx1;
|
||||
var tx2;
|
||||
var block;
|
||||
|
||||
var rpcConfig = {
|
||||
protocol: 'http',
|
||||
user: 'local',
|
||||
pass: 'localtest',
|
||||
host: '127.0.0.1',
|
||||
port: 58332,
|
||||
rejectUnauthorized: false
|
||||
};
|
||||
|
||||
var rpc1 = new RPC(rpcConfig);
|
||||
rpcConfig.port++;
|
||||
var rpc2 = new RPC(rpcConfig);
|
||||
var debug = true;
|
||||
var bitcoreDataDir = '/tmp/bitcore';
|
||||
var bitcoinDataDirs = ['/tmp/bitcoin1', '/tmp/bitcoin2'];
|
||||
|
||||
var bitcoin = {
|
||||
args: {
|
||||
datadir: null,
|
||||
listen: 1,
|
||||
regtest: 1,
|
||||
server: 1,
|
||||
rpcuser: 'local',
|
||||
rpcpassword: 'localtest',
|
||||
//printtoconsole: 1
|
||||
rpcport: 58332,
|
||||
},
|
||||
datadir: null,
|
||||
exec: 'bitcoind', //if this isn't on your PATH, then provide the absolute path, e.g. /usr/local/bin/bitcoind
|
||||
processes: []
|
||||
};
|
||||
|
||||
var bitcore = {
|
||||
configFile: {
|
||||
file: bitcoreDataDir + '/bitcore-node.json',
|
||||
conf: {
|
||||
network: 'regtest',
|
||||
port: 53001,
|
||||
datadir: bitcoreDataDir,
|
||||
services: [
|
||||
'p2p',
|
||||
'db',
|
||||
'header',
|
||||
'block',
|
||||
'address',
|
||||
'transaction',
|
||||
'mempool',
|
||||
'web',
|
||||
'insight-api',
|
||||
'fee',
|
||||
'timestamp'
|
||||
],
|
||||
servicesConfig: {
|
||||
'p2p': {
|
||||
'peers': [
|
||||
{ 'ip': { 'v4': '127.0.0.1' }, port: 18444 }
|
||||
]
|
||||
},
|
||||
'insight-api': {
|
||||
'routePrefix': 'api'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
httpOpts: {
|
||||
protocol: 'http:',
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
},
|
||||
opts: { cwd: bitcoreDataDir },
|
||||
datadir: bitcoreDataDir,
|
||||
exec: 'bitcored', //if this isn't on your PATH, then provide the absolute path, e.g. /usr/local/bin/bitcored
|
||||
args: ['start'],
|
||||
process: null
|
||||
};
|
||||
|
||||
var startBitcoind = function(count, callback) {
|
||||
|
||||
var listenCount = 0;
|
||||
async.timesSeries(count, function(n, next) {
|
||||
|
||||
var datadir = bitcoinDataDirs.shift();
|
||||
|
||||
bitcoin.datadir = datadir;
|
||||
bitcoin.args.datadir = datadir;
|
||||
|
||||
if (listenCount++ > 0) {
|
||||
bitcoin.args.listen = 0;
|
||||
bitcoin.args.rpcport++;
|
||||
bitcoin.args.connect = '127.0.0.1';
|
||||
}
|
||||
|
||||
rimraf(datadir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
mkdirp(datadir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
var args = bitcoin.args;
|
||||
var argList = Object.keys(args).map(function(key) {
|
||||
return '-' + key + '=' + args[key];
|
||||
});
|
||||
|
||||
var bitcoinProcess = spawn(bitcoin.exec, argList, bitcoin.opts);
|
||||
bitcoin.processes.push(bitcoinProcess);
|
||||
|
||||
bitcoinProcess.stdout.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stdout.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
bitcoinProcess.stderr.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stderr.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
next();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
}, function(err) {
|
||||
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var pids = bitcoin.processes.map(function(process) {
|
||||
return process.pid;
|
||||
});
|
||||
|
||||
console.log(count + ' bitcoind\'s started at pid(s): ' + pids);
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
var shutdownBitcoind = function(callback) {
|
||||
bitcoin.processes.forEach(function(process) {
|
||||
process.kill();
|
||||
});
|
||||
setTimeout(callback, 3000);
|
||||
};
|
||||
|
||||
var shutdownBitcore = function(callback) {
|
||||
if (bitcore.process) {
|
||||
bitcore.process.kill();
|
||||
}
|
||||
callback();
|
||||
};
|
||||
|
||||
|
||||
var buildInitialChain = function(callback) {
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
console.log('checking to see if bitcoind\'s are connected to each other.');
|
||||
rpc1.getinfo(function(err, res) {
|
||||
if (err || res.result.connections !== 1) {
|
||||
next(err || new Error('bitcoind\'s not connected to each other.'));
|
||||
}
|
||||
next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
console.log('generating 101 blocks');
|
||||
rpc1.generate(101, next);
|
||||
},
|
||||
function(res, next) {
|
||||
console.log('getting new address from rpc2');
|
||||
rpc2.getNewAddress(function(err, res) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
rpc2Address = res.result;
|
||||
console.log(rpc2Address);
|
||||
next(null, rpc2Address);
|
||||
});
|
||||
},
|
||||
function(addr, next) {
|
||||
rpc1.sendToAddress(rpc2Address, 25, next);
|
||||
},
|
||||
function(res, next) {
|
||||
tx1 = res.result;
|
||||
console.log('TXID: ' + res.result);
|
||||
console.log('generating 7 blocks');
|
||||
rpc1.generate(7, next);
|
||||
},
|
||||
function(res, next) {
|
||||
block = res.result[res.result.length - 1];
|
||||
rpc2.getBalance(function(err, res) {
|
||||
console.log(res);
|
||||
next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
console.log('getting new address from rpc1');
|
||||
rpc1.getNewAddress(function(err, res) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
rpc1Address = res.result;
|
||||
next(null, rpc1Address);
|
||||
});
|
||||
},
|
||||
function(addr, next) {
|
||||
rpc2.sendToAddress(rpc1Address, 20, next);
|
||||
},
|
||||
function(res, next) {
|
||||
tx2 = res.result;
|
||||
console.log('sending from rpc2Address TXID: ', res);
|
||||
console.log('generating 6 blocks');
|
||||
rpc2.generate(6, next);
|
||||
}
|
||||
], function(err) {
|
||||
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
rpc1.getInfo(function(err, res) {
|
||||
console.log(res);
|
||||
callback();
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
var startBitcore = function(callback) {
|
||||
|
||||
rimraf(bitcoreDataDir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
mkdirp(bitcoreDataDir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
fs.writeFileSync(bitcore.configFile.file, JSON.stringify(bitcore.configFile.conf));
|
||||
|
||||
var args = bitcore.args;
|
||||
bitcore.process = spawn(bitcore.exec, args, bitcore.opts);
|
||||
|
||||
bitcore.process.stdout.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stdout.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
bitcore.process.stderr.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stderr.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
callback();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
describe('Block', function() {
|
||||
|
||||
this.timeout(60000);
|
||||
|
||||
before(function(done) {
|
||||
|
||||
async.series([
|
||||
function(next) {
|
||||
startBitcoind(2, next);
|
||||
},
|
||||
function(next) {
|
||||
setTimeout(function() {
|
||||
buildInitialChain(next);
|
||||
}, 8000);
|
||||
},
|
||||
function(next) {
|
||||
setTimeout(function() {
|
||||
startBitcore(next);
|
||||
}, 6000);
|
||||
}
|
||||
], function(err) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
setTimeout(done, 2000);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
shutdownBitcore(function() {
|
||||
shutdownBitcoind(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should get blocks: /blocks', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/blocks', function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
expect(data.length).to.equal(114);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
request.write('');
|
||||
request.end();
|
||||
});
|
||||
|
||||
it('should get a block: /block/:hash', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/block/' + block, function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
expect(data.hash).to.equal(block);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
request.write('');
|
||||
request.end();
|
||||
});
|
||||
|
||||
it('should get a block-index: /block-index/:height', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/block-index/' + '108', function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(resData);
|
||||
expect(data.blockHash).to.equal(block);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
request.write('');
|
||||
request.end();
|
||||
});
|
||||
|
||||
it('should get a raw block: /rawblock/:hash', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/rawblock/' + block, function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(resData);
|
||||
expect(data.rawblock).to.not.be.null;
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
request.write('');
|
||||
request.end();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
10
regtest/data/blocks.json
Normal file
10
regtest/data/blocks.json
Normal file
@ -0,0 +1,10 @@
|
||||
[
|
||||
"0000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f0520bf1be2e869376908f7c637214f9f0f9f4fd86c819a8c98a3c5f8d70a65f805ba9559ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0200f2052a01000000232103e91a98edf4e457b5d5aa1e50e35ce6afb67bf7a9ff98b5c36dabbe994b080205ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
|
||||
"00000020bd5725c4bc8fb66032523ca18eb2c809ca1935ab35baf5a1bbaf60ef9a616b2b373d5a12492652b1d22c28ce5c6eb6b22f03c69db1eae9a368e1b544147583eb06ba9559ffff7f20030000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03520101ffffffff0200f2052a01000000232103e91a98edf4e457b5d5aa1e50e35ce6afb67bf7a9ff98b5c36dabbe994b080205ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
|
||||
"00000020af97cfd581a5f0da7925c346c371f6c58131a6b00a95060562f90607aa111e5f97c7b866d2503ee4982569a486f6e25023e72bef588bdef60a06fc740e50001906ba9559ffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03530101ffffffff0200f2052a01000000232103e91a98edf4e457b5d5aa1e50e35ce6afb67bf7a9ff98b5c36dabbe994b080205ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
|
||||
"000000201c9d9eb8064b9508b3cd10de5927cc47347a6899b66946ecc22d52b04c2f3c5f99435c3a200a2419695565432e3115a5ff0d57ed1975b9efe0c7ad1a709a6a4e07ba9559ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03540101ffffffff0200f2052a01000000232103e91a98edf4e457b5d5aa1e50e35ce6afb67bf7a9ff98b5c36dabbe994b080205ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
|
||||
"00000020de37a9c9fbb1dc3ea5ca9e148e5310d639649814b45a424afe1d58a18db5d8327b529f7d58238330d55b82228ea14abcab965319de7e59c6534758c91c137fcb07ba9559ffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03550101ffffffff0200f2052a01000000232103e91a98edf4e457b5d5aa1e50e35ce6afb67bf7a9ff98b5c36dabbe994b080205ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
|
||||
"00000020e3aa93afbba267bec962a7a38bd064478e5c082e9a73e434b20544950ad8395b3b4a71816a4ce7973d0bcc6a583441fca260f71a175bd2887a9e3e40e4badcd355bb9559ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03560101ffffffff0200f2052a010000002321023886024ea5984e57b35c3b339f5aee097819ac55235e4fd5822a6ad0a4de1b55ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
|
||||
"000000201a3c951a20b5d603144ce060c86e95fed1869524e66acfc46bdf08d96f6642094916aa5b965b0016fb8ba8b58e99f6b3edbe1a844aa7948adaccf7f28f08f914b9cb9559ffff7f20030000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03570101ffffffff0200f2052a01000000232102a8ef631320be3e6203329acba88fe0a663c19d59fee8240592dc2a32553a4159ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000"
|
||||
|
||||
]
|
||||
4
regtest/data/blocks_reorg.json
Normal file
4
regtest/data/blocks_reorg.json
Normal file
@ -0,0 +1,4 @@
|
||||
[
|
||||
"000000201a3c951a20b5d603144ce060c86e95fed1869524e66acfc46bdf08d96f664209b4b1c32ec485f4ad27c5402a1b16a0b1135364b7c9b0dcf4276f9fa3fd215d1b08cc9559ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03570101ffffffff0200f2052a01000000232102a5566542d1f0f202541d98755628a41dcd4416b50db820e2b04d5ecb0bd02b73ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000"
|
||||
]
|
||||
|
||||
277
regtest/reorg.js
Normal file
277
regtest/reorg.js
Normal file
@ -0,0 +1,277 @@
|
||||
'use strict';
|
||||
|
||||
var expect = require('chai').expect;
|
||||
var net = require('net');
|
||||
var spawn = require('child_process').spawn;
|
||||
var rimraf = require('rimraf');
|
||||
var mkdirp = require('mkdirp');
|
||||
var fs = require('fs');
|
||||
var p2p = require('bitcore-p2p');
|
||||
var bitcore = require('bitcore-lib');
|
||||
var Networks = bitcore.Networks;
|
||||
var BlockHeader = bitcore.BlockHeader;
|
||||
var Block = bitcore.Block;
|
||||
var BcoinBlock = require('bcoin').block;
|
||||
var http = require('http');
|
||||
|
||||
Networks.enableRegtest();
|
||||
var messages = new p2p.Messages({ network: Networks.get('regtest'), Block: BcoinBlock, BlockHeader: BlockHeader });
|
||||
var server;
|
||||
var rawBlocks = require('./data/blocks.json');
|
||||
var rawReorgBlocks = require('./data/blocks_reorg.json')[0];
|
||||
|
||||
var reorgBlock = BcoinBlock.fromRaw(rawReorgBlocks, 'hex');
|
||||
|
||||
var blocks = rawBlocks.map(function(rawBlock) {
|
||||
return new Block(new Buffer(rawBlock, 'hex'));
|
||||
});
|
||||
|
||||
var headers = blocks.map(function(block) {
|
||||
return block.header;
|
||||
});
|
||||
|
||||
var debug = true;
|
||||
var bitcoreDataDir = '/tmp/bitcore';
|
||||
|
||||
var bitcore = {
|
||||
configFile: {
|
||||
file: bitcoreDataDir + '/bitcore-node.json',
|
||||
conf: {
|
||||
network: 'regtest',
|
||||
port: 53001,
|
||||
datadir: bitcoreDataDir,
|
||||
services: [
|
||||
'p2p',
|
||||
'db',
|
||||
'header',
|
||||
'block',
|
||||
'address',
|
||||
'transaction',
|
||||
'mempool',
|
||||
'web',
|
||||
'insight-api',
|
||||
'fee',
|
||||
'timestamp'
|
||||
],
|
||||
servicesConfig: {
|
||||
'p2p': {
|
||||
'peers': [
|
||||
{ 'ip': { 'v4': '127.0.0.1' }, port: 18444 }
|
||||
]
|
||||
},
|
||||
'insight-api': {
|
||||
'routePrefix': 'api'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
httpOpts: {
|
||||
protocol: 'http:',
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
},
|
||||
opts: { cwd: bitcoreDataDir },
|
||||
datadir: bitcoreDataDir,
|
||||
exec: 'bitcored', // ensure this on your path or add the full, absolute path.
|
||||
args: ['start'],
|
||||
process: null
|
||||
};
|
||||
|
||||
|
||||
var blockIndex = 0;
|
||||
var tcpSocket;
|
||||
|
||||
var startFakeNode = function() {
|
||||
server = net.createServer(function(socket) {
|
||||
|
||||
tcpSocket = socket;
|
||||
socket.on('end', function() {
|
||||
console.log('bitcore-node has ended the connection');
|
||||
});
|
||||
|
||||
socket.on('data', function(data) {
|
||||
|
||||
var command = data.slice(4, 16).toString('hex');
|
||||
var message;
|
||||
|
||||
if (command === '76657273696f6e0000000000') { //version
|
||||
message = messages.Version();
|
||||
}
|
||||
|
||||
if (command === '76657261636b000000000000') { //verack
|
||||
message = messages.VerAck();
|
||||
}
|
||||
|
||||
if (command === '676574686561646572730000') { //getheaders
|
||||
message = messages.Headers(headers);
|
||||
}
|
||||
|
||||
if (command === '676574626c6f636b73000000') { //getblocks
|
||||
var block = blocks[blockIndex];
|
||||
if (!block) {
|
||||
return;
|
||||
}
|
||||
var blockHash = block.hash;
|
||||
var inv = p2p.Inventory.forBlock(blockHash);
|
||||
message = messages.Inventory([inv]);
|
||||
}
|
||||
|
||||
if (command === '676574646174610000000000') { //getdata
|
||||
var raw = rawBlocks[blockIndex++];
|
||||
var blk = BcoinBlock.fromRaw(raw, 'hex');
|
||||
message = messages.Block(blk, { Block: BcoinBlock });
|
||||
}
|
||||
|
||||
if (message) {
|
||||
socket.write(message.toBuffer());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
socket.pipe(socket);
|
||||
});
|
||||
|
||||
server.listen(18444, '127.0.0.1');
|
||||
};
|
||||
|
||||
|
||||
var shutdownFakeNode = function() {
|
||||
server.close();
|
||||
};
|
||||
|
||||
var shutdownBitcore = function(callback) {
|
||||
if (bitcore.process) {
|
||||
bitcore.process.kill();
|
||||
}
|
||||
callback();
|
||||
};
|
||||
|
||||
var startBitcore = function(callback) {
|
||||
|
||||
rimraf(bitcoreDataDir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
mkdirp(bitcoreDataDir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
fs.writeFileSync(bitcore.configFile.file, JSON.stringify(bitcore.configFile.conf));
|
||||
|
||||
var args = bitcore.args;
|
||||
bitcore.process = spawn(bitcore.exec, args, bitcore.opts);
|
||||
|
||||
bitcore.process.stdout.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stdout.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
bitcore.process.stderr.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stderr.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
callback();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
describe('Reorg', function() {
|
||||
// 1. spin up bitcore-node and have it connect to our custom tcp socket
|
||||
// 2. feed it a few headers
|
||||
// 3. feed it a few blocks
|
||||
// 4. feed it a block that reorgs
|
||||
|
||||
this.timeout(60000);
|
||||
|
||||
before(function(done) {
|
||||
startFakeNode();
|
||||
startBitcore(done);
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
shutdownFakeNode();
|
||||
shutdownBitcore(function() {
|
||||
setTimeout(done, 3000);
|
||||
});
|
||||
});
|
||||
|
||||
it('should reorg correctly when already synced', function(done) {
|
||||
|
||||
// at this point we have a fully synced chain at height 7....
|
||||
// we now want to send a new block number 7 whose prev hash is block 6 (it should be block 7)
|
||||
// we then should reorg back to block 6 then back up to the new block 7
|
||||
|
||||
setTimeout(function() {
|
||||
|
||||
console.log('From Test: reorging to block: ' + reorgBlock.rhash());
|
||||
|
||||
// send the reorg block
|
||||
rawBlocks.push(rawReorgBlocks);
|
||||
var blockHash = reorgBlock.rhash();
|
||||
var inv = p2p.Inventory.forBlock(blockHash);
|
||||
var msg = messages.Inventory([inv]);
|
||||
tcpSocket.write(msg.toBuffer());
|
||||
|
||||
// wait 2 secs until the reorg happens, if it takes any longer the test ought to fail anyway
|
||||
setTimeout(function() {
|
||||
var error;
|
||||
var request = http.request('http://localhost:53001/api/block/' + reorgBlock.rhash(), function(res) {
|
||||
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
expect(data.height).to.equal(7);
|
||||
expect(data.hash).to.equal(reorgBlock.rhash());
|
||||
done(resError, resData);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
request.on('error', function(e) {
|
||||
error = e;
|
||||
done(error);
|
||||
});
|
||||
|
||||
request.write('');
|
||||
request.end();
|
||||
}, 2000);
|
||||
}, 2000);
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
549
regtest/status.js
Normal file
549
regtest/status.js
Normal file
@ -0,0 +1,549 @@
|
||||
'use strict';
|
||||
|
||||
var expect = require('chai').expect;
|
||||
var spawn = require('child_process').spawn;
|
||||
var rimraf = require('rimraf');
|
||||
var mkdirp = require('mkdirp');
|
||||
var fs = require('fs');
|
||||
var async = require('async');
|
||||
var RPC = require('bitcoind-rpc');
|
||||
var http = require('http');
|
||||
|
||||
var rpc1Address;
|
||||
var rpc2Address;
|
||||
var tx1;
|
||||
var tx2;
|
||||
var block;
|
||||
|
||||
var rpcConfig = {
|
||||
protocol: 'http',
|
||||
user: 'local',
|
||||
pass: 'localtest',
|
||||
host: '127.0.0.1',
|
||||
port: 58332,
|
||||
rejectUnauthorized: false
|
||||
};
|
||||
|
||||
var rpc1 = new RPC(rpcConfig);
|
||||
rpcConfig.port++;
|
||||
var rpc2 = new RPC(rpcConfig);
|
||||
var debug = true;
|
||||
var bitcoreDataDir = '/tmp/bitcore';
|
||||
var bitcoinDataDirs = ['/tmp/bitcoin1', '/tmp/bitcoin2'];
|
||||
|
||||
var bitcoin = {
|
||||
args: {
|
||||
datadir: null,
|
||||
listen: 1,
|
||||
regtest: 1,
|
||||
server: 1,
|
||||
rpcuser: 'local',
|
||||
rpcpassword: 'localtest',
|
||||
//printtoconsole: 1
|
||||
rpcport: 58332,
|
||||
},
|
||||
datadir: null,
|
||||
exec: 'bitcoind', //if this isn't on your PATH, then provide the absolute path, e.g. /usr/local/bin/bitcoind
|
||||
processes: []
|
||||
};
|
||||
|
||||
var bitcore = {
|
||||
configFile: {
|
||||
file: bitcoreDataDir + '/bitcore-node.json',
|
||||
conf: {
|
||||
network: 'regtest',
|
||||
port: 53001,
|
||||
datadir: bitcoreDataDir,
|
||||
services: [
|
||||
'p2p',
|
||||
'db',
|
||||
'header',
|
||||
'block',
|
||||
'address',
|
||||
'transaction',
|
||||
'mempool',
|
||||
'web',
|
||||
'insight-api',
|
||||
'fee',
|
||||
'timestamp'
|
||||
],
|
||||
servicesConfig: {
|
||||
'p2p': {
|
||||
'peers': [
|
||||
{ 'ip': { 'v4': '127.0.0.1' }, port: 18444 }
|
||||
]
|
||||
},
|
||||
'fee': {
|
||||
'rpc': {
|
||||
'user': 'local',
|
||||
'pass': 'localtest',
|
||||
'host': 'localhost',
|
||||
'protocol': 'http',
|
||||
'port': 58332
|
||||
}
|
||||
},
|
||||
'insight-api': {
|
||||
'routePrefix': 'api'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
httpOpts: {
|
||||
protocol: 'http:',
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
},
|
||||
opts: { cwd: bitcoreDataDir },
|
||||
datadir: bitcoreDataDir,
|
||||
exec: 'bitcored',
|
||||
args: ['start'],
|
||||
process: null
|
||||
};
|
||||
|
||||
var startBitcoind = function(count, callback) {
|
||||
|
||||
var listenCount = 0;
|
||||
async.timesSeries(count, function(n, next) {
|
||||
|
||||
var datadir = bitcoinDataDirs.shift();
|
||||
|
||||
bitcoin.datadir = datadir;
|
||||
bitcoin.args.datadir = datadir;
|
||||
|
||||
if (listenCount++ > 0) {
|
||||
bitcoin.args.listen = 0;
|
||||
bitcoin.args.rpcport++;
|
||||
bitcoin.args.connect = '127.0.0.1';
|
||||
}
|
||||
|
||||
rimraf(datadir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
mkdirp(datadir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
var args = bitcoin.args;
|
||||
var argList = Object.keys(args).map(function(key) {
|
||||
return '-' + key + '=' + args[key];
|
||||
});
|
||||
|
||||
var bitcoinProcess = spawn(bitcoin.exec, argList, bitcoin.opts);
|
||||
bitcoin.processes.push(bitcoinProcess);
|
||||
|
||||
bitcoinProcess.stdout.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stdout.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
bitcoinProcess.stderr.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stderr.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
next();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
}, function(err) {
|
||||
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var pids = bitcoin.processes.map(function(process) {
|
||||
return process.pid;
|
||||
});
|
||||
|
||||
console.log(count + ' bitcoind\'s started at pid(s): ' + pids);
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
var shutdownBitcoind = function(callback) {
|
||||
bitcoin.processes.forEach(function(process) {
|
||||
process.kill();
|
||||
});
|
||||
setTimeout(callback, 3000);
|
||||
};
|
||||
|
||||
var shutdownBitcore = function(callback) {
|
||||
if (bitcore.process) {
|
||||
bitcore.process.kill();
|
||||
}
|
||||
callback();
|
||||
};
|
||||
|
||||
|
||||
var buildInitialChain = function(callback) {
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
console.log('checking to see if bitcoind\'s are connected to each other.');
|
||||
rpc1.getinfo(function(err, res) {
|
||||
if (err || res.result.connections !== 1) {
|
||||
next(err || new Error('bitcoind\'s not connected to each other.'));
|
||||
}
|
||||
next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
console.log('generating 101 blocks');
|
||||
rpc1.generate(101, next);
|
||||
},
|
||||
function(res, next) {
|
||||
console.log('getting new address from rpc2');
|
||||
rpc2.getNewAddress(function(err, res) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
rpc2Address = res.result;
|
||||
console.log(rpc2Address);
|
||||
next(null, rpc2Address);
|
||||
});
|
||||
},
|
||||
function(addr, next) {
|
||||
rpc1.sendToAddress(rpc2Address, 25, next);
|
||||
},
|
||||
function(res, next) {
|
||||
tx1 = res.result;
|
||||
console.log('TXID: ' + res.result);
|
||||
console.log('generating 7 blocks');
|
||||
rpc1.generate(7, next);
|
||||
},
|
||||
function(res, next) {
|
||||
block = res.result[res.result.length - 1];
|
||||
rpc2.getBalance(function(err, res) {
|
||||
console.log(res);
|
||||
next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
console.log('getting new address from rpc1');
|
||||
rpc1.getNewAddress(function(err, res) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
rpc1Address = res.result;
|
||||
next(null, rpc1Address);
|
||||
});
|
||||
},
|
||||
function(addr, next) {
|
||||
rpc2.sendToAddress(rpc1Address, 20, next);
|
||||
},
|
||||
function(res, next) {
|
||||
tx2 = res.result;
|
||||
console.log('sending from rpc2Address TXID: ', res);
|
||||
console.log('generating 6 blocks');
|
||||
rpc2.generate(6, next);
|
||||
}
|
||||
], function(err) {
|
||||
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
rpc1.getInfo(function(err, res) {
|
||||
console.log(res);
|
||||
callback();
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
var startBitcore = function(callback) {
|
||||
|
||||
rimraf(bitcoreDataDir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
mkdirp(bitcoreDataDir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
fs.writeFileSync(bitcore.configFile.file, JSON.stringify(bitcore.configFile.conf));
|
||||
|
||||
var args = bitcore.args;
|
||||
bitcore.process = spawn(bitcore.exec, args, bitcore.opts);
|
||||
|
||||
bitcore.process.stdout.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stdout.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
bitcore.process.stderr.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stderr.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
callback();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
describe('Status', function() {
|
||||
|
||||
this.timeout(60000);
|
||||
|
||||
before(function(done) {
|
||||
|
||||
async.series([
|
||||
function(next) {
|
||||
startBitcoind(2, next);
|
||||
},
|
||||
function(next) {
|
||||
setTimeout(function() {
|
||||
buildInitialChain(next);
|
||||
}, 8000);
|
||||
},
|
||||
function(next) {
|
||||
setTimeout(function() {
|
||||
startBitcore(next);
|
||||
}, 6000);
|
||||
}
|
||||
], function(err) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
setTimeout(done, 2000);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
shutdownBitcore(function() {
|
||||
shutdownBitcoind(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should get status: /status', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/status', function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
expect(data.info).to.not.be.null;
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
request.write('');
|
||||
request.end();
|
||||
});
|
||||
|
||||
it('should get status: /sync', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/sync', function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(data);
|
||||
expect(data.status).to.equal('finished');
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
request.write('');
|
||||
request.end();
|
||||
});
|
||||
|
||||
it('should get peer: /peer', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/peer', function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(data);
|
||||
expect(data.connected).to.be.true;
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
request.write('');
|
||||
request.end();
|
||||
});
|
||||
|
||||
it('should get version: /version', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/version', function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(data);
|
||||
expect(data.version).to.not.be.null;
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
request.write('');
|
||||
request.end();
|
||||
|
||||
});
|
||||
|
||||
it('should estimate fee: /estimateFee', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/utils/estimateFee', function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(data);
|
||||
expect(data['2']).to.not.be.null;
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
request.write('');
|
||||
request.end();
|
||||
|
||||
});
|
||||
});
|
||||
448
regtest/transaction.js
Normal file
448
regtest/transaction.js
Normal file
@ -0,0 +1,448 @@
|
||||
'use strict';
|
||||
|
||||
var expect = require('chai').expect;
|
||||
var spawn = require('child_process').spawn;
|
||||
var rimraf = require('rimraf');
|
||||
var mkdirp = require('mkdirp');
|
||||
var fs = require('fs');
|
||||
var async = require('async');
|
||||
var RPC = require('bitcoind-rpc');
|
||||
var http = require('http');
|
||||
|
||||
var rpc1Address;
|
||||
var rpc2Address;
|
||||
var tx1;
|
||||
var tx2;
|
||||
var block;
|
||||
|
||||
var rpcConfig = {
|
||||
protocol: 'http',
|
||||
user: 'local',
|
||||
pass: 'localtest',
|
||||
host: '127.0.0.1',
|
||||
port: 58332,
|
||||
rejectUnauthorized: false
|
||||
};
|
||||
|
||||
var rpc1 = new RPC(rpcConfig);
|
||||
rpcConfig.port++;
|
||||
var rpc2 = new RPC(rpcConfig);
|
||||
var debug = true;
|
||||
var bitcoreDataDir = '/tmp/bitcore';
|
||||
var bitcoinDataDirs = ['/tmp/bitcoin1', '/tmp/bitcoin2'];
|
||||
|
||||
var bitcoin = {
|
||||
args: {
|
||||
datadir: null,
|
||||
listen: 1,
|
||||
regtest: 1,
|
||||
server: 1,
|
||||
rpcuser: 'local',
|
||||
rpcpassword: 'localtest',
|
||||
//printtoconsole: 1
|
||||
rpcport: 58332,
|
||||
},
|
||||
datadir: null,
|
||||
exec: 'bitcoind', //if this isn't on your PATH, then provide the absolute path, e.g. /usr/local/bin/bitcoind
|
||||
processes: []
|
||||
};
|
||||
|
||||
var bitcore = {
|
||||
configFile: {
|
||||
file: bitcoreDataDir + '/bitcore-node.json',
|
||||
conf: {
|
||||
network: 'regtest',
|
||||
port: 53001,
|
||||
datadir: bitcoreDataDir,
|
||||
services: [
|
||||
'p2p',
|
||||
'db',
|
||||
'header',
|
||||
'block',
|
||||
'address',
|
||||
'transaction',
|
||||
'mempool',
|
||||
'web',
|
||||
'insight-api',
|
||||
'fee',
|
||||
'timestamp'
|
||||
],
|
||||
servicesConfig: {
|
||||
'p2p': {
|
||||
'peers': [
|
||||
{ 'ip': { 'v4': '127.0.0.1' }, port: 18444 }
|
||||
]
|
||||
},
|
||||
'insight-api': {
|
||||
'routePrefix': 'api'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
httpOpts: {
|
||||
protocol: 'http:',
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
},
|
||||
opts: { cwd: bitcoreDataDir },
|
||||
datadir: bitcoreDataDir,
|
||||
exec: 'bitcored', //if this isn't on your PATH, then provide the absolute path, e.g. /usr/local/bin/bitcored
|
||||
args: ['start'],
|
||||
process: null
|
||||
};
|
||||
|
||||
var startBitcoind = function(count, callback) {
|
||||
|
||||
var listenCount = 0;
|
||||
async.timesSeries(count, function(n, next) {
|
||||
|
||||
var datadir = bitcoinDataDirs.shift();
|
||||
|
||||
bitcoin.datadir = datadir;
|
||||
bitcoin.args.datadir = datadir;
|
||||
|
||||
if (listenCount++ > 0) {
|
||||
bitcoin.args.listen = 0;
|
||||
bitcoin.args.rpcport++;
|
||||
bitcoin.args.connect = '127.0.0.1';
|
||||
}
|
||||
|
||||
rimraf(datadir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
mkdirp(datadir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
var args = bitcoin.args;
|
||||
var argList = Object.keys(args).map(function(key) {
|
||||
return '-' + key + '=' + args[key];
|
||||
});
|
||||
|
||||
var bitcoinProcess = spawn(bitcoin.exec, argList, bitcoin.opts);
|
||||
bitcoin.processes.push(bitcoinProcess);
|
||||
|
||||
bitcoinProcess.stdout.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stdout.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
bitcoinProcess.stderr.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stderr.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
next();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
}, function(err) {
|
||||
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var pids = bitcoin.processes.map(function(process) {
|
||||
return process.pid;
|
||||
});
|
||||
|
||||
console.log(count + ' bitcoind\'s started at pid(s): ' + pids);
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
var shutdownBitcoind = function(callback) {
|
||||
bitcoin.processes.forEach(function(process) {
|
||||
process.kill();
|
||||
});
|
||||
setTimeout(callback, 3000);
|
||||
};
|
||||
|
||||
var shutdownBitcore = function(callback) {
|
||||
if (bitcore.process) {
|
||||
bitcore.process.kill();
|
||||
}
|
||||
callback();
|
||||
};
|
||||
|
||||
|
||||
var buildInitialChain = function(callback) {
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
console.log('checking to see if bitcoind\'s are connected to each other.');
|
||||
rpc1.getinfo(function(err, res) {
|
||||
if (err || res.result.connections !== 1) {
|
||||
next(err || new Error('bitcoind\'s not connected to each other.'));
|
||||
}
|
||||
next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
console.log('generating 101 blocks');
|
||||
rpc1.generate(101, next);
|
||||
},
|
||||
function(res, next) {
|
||||
console.log('getting new address from rpc2');
|
||||
rpc2.getNewAddress(function(err, res) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
rpc2Address = res.result;
|
||||
console.log(rpc2Address);
|
||||
next(null, rpc2Address);
|
||||
});
|
||||
},
|
||||
function(addr, next) {
|
||||
rpc1.sendToAddress(rpc2Address, 25, next);
|
||||
},
|
||||
function(res, next) {
|
||||
tx1 = res.result;
|
||||
console.log('TXID: ' + res.result);
|
||||
console.log('generating 6 blocks');
|
||||
rpc1.generate(7, next);
|
||||
},
|
||||
function(res, next) {
|
||||
block = res.result[res.result.length - 1];
|
||||
rpc2.getBalance(function(err, res) {
|
||||
console.log(res);
|
||||
next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
console.log('getting new address from rpc1');
|
||||
rpc1.getNewAddress(function(err, res) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
rpc1Address = res.result;
|
||||
next(null, rpc1Address);
|
||||
});
|
||||
},
|
||||
function(addr, next) {
|
||||
rpc2.sendToAddress(rpc1Address, 20, next);
|
||||
},
|
||||
function(res, next) {
|
||||
tx2 = res.result;
|
||||
console.log('sending from rpc2Address TXID: ', res);
|
||||
console.log('generating 6 blocks');
|
||||
rpc2.generate(6, next);
|
||||
}
|
||||
], function(err) {
|
||||
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
rpc1.getInfo(function(err, res) {
|
||||
console.log(res);
|
||||
callback();
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
var startBitcore = function(callback) {
|
||||
|
||||
rimraf(bitcoreDataDir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
mkdirp(bitcoreDataDir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
fs.writeFileSync(bitcore.configFile.file, JSON.stringify(bitcore.configFile.conf));
|
||||
|
||||
var args = bitcore.args;
|
||||
bitcore.process = spawn(bitcore.exec, args, bitcore.opts);
|
||||
|
||||
bitcore.process.stdout.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stdout.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
bitcore.process.stderr.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stderr.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
callback();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
describe('Transaction', function() {
|
||||
|
||||
this.timeout(60000);
|
||||
|
||||
before(function(done) {
|
||||
|
||||
async.series([
|
||||
function(next) {
|
||||
startBitcoind(2, next);
|
||||
},
|
||||
function(next) {
|
||||
setTimeout(function() {
|
||||
buildInitialChain(next);
|
||||
}, 8000);
|
||||
},
|
||||
function(next) {
|
||||
setTimeout(function() {
|
||||
startBitcore(next);
|
||||
}, 6000);
|
||||
}
|
||||
], function(err) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
setTimeout(done, 2000);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
shutdownBitcore(function() {
|
||||
shutdownBitcoind(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should get a transaction: /tx/:txid', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/tx/' + tx1, function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
expect(data.txid).to.equal(tx1);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
request.write('');
|
||||
request.end();
|
||||
});
|
||||
|
||||
it('should get transactions: /txs', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/txs?block=' + block, function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(resData);
|
||||
expect(data.txs.length).to.equal(1);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
request.write('');
|
||||
request.end();
|
||||
});
|
||||
|
||||
it('should get a raw transactions: /rawtx/:txid', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/rawtx/' + tx2, function(res) {
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(resData);
|
||||
expect(data.rawtx).to.not.be.null;
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
request.write('');
|
||||
request.end();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
@ -184,8 +184,8 @@ var utxos = [
|
||||
describe('Addresses', function() {
|
||||
var summary = {
|
||||
balance: 0,
|
||||
totalReceived: 2782729129,
|
||||
totalSpent: 2782729129,
|
||||
totalReceivedSat: 2782729129,
|
||||
totalSent: 2782729129,
|
||||
unconfirmedBalance: 0,
|
||||
appearances: 2,
|
||||
unconfirmedAppearances: 0,
|
||||
|
||||
@ -13,60 +13,60 @@ describe('Transactions', function() {
|
||||
it('should have correct data', function(done) {
|
||||
|
||||
var insight = {
|
||||
"txid": "eac9723230b8b632117ac3d75288d6f8eb81cf1ea553eb9fd42562d5f767d54a",
|
||||
"version": 1,
|
||||
"locktime": 0,
|
||||
"vin": [
|
||||
'txid': 'eac9723230b8b632117ac3d75288d6f8eb81cf1ea553eb9fd42562d5f767d54a',
|
||||
'version': 1,
|
||||
'locktime': 0,
|
||||
'vin': [
|
||||
{
|
||||
"txid": "46e58a68bb9ec9b458a9599dc2bac1e1fa09ad15c29c7f923c8f6f0aa33d6456",
|
||||
"vout": 1,
|
||||
"sequence": 4294967295,
|
||||
"n": 0,
|
||||
"scriptSig": {
|
||||
"hex": "47304402203ddb49db43074b421ec6d5604ae91aac37f4715139e0c83ea1145379e8cbf02702207fbc92c4038ad501989b097844ae4e337c9388f0713110620b40e582b85fdff3012102cd90aa18ec8e3b35c0447ffc713c945cb837429d33d075d1b0f050c72ea838d2",
|
||||
"asm": "304402203ddb49db43074b421ec6d5604ae91aac37f4715139e0c83ea1145379e8cbf02702207fbc92c4038ad501989b097844ae4e337c9388f0713110620b40e582b85fdff301 02cd90aa18ec8e3b35c0447ffc713c945cb837429d33d075d1b0f050c72ea838d2"
|
||||
'txid': '46e58a68bb9ec9b458a9599dc2bac1e1fa09ad15c29c7f923c8f6f0aa33d6456',
|
||||
'vout': 1,
|
||||
'sequence': 4294967295,
|
||||
'n': 0,
|
||||
'scriptSig': {
|
||||
'hex': '47304402203ddb49db43074b421ec6d5604ae91aac37f4715139e0c83ea1145379e8cbf02702207fbc92c4038ad501989b097844ae4e337c9388f0713110620b40e582b85fdff3012102cd90aa18ec8e3b35c0447ffc713c945cb837429d33d075d1b0f050c72ea838d2',
|
||||
'asm': '304402203ddb49db43074b421ec6d5604ae91aac37f4715139e0c83ea1145379e8cbf02702207fbc92c4038ad501989b097844ae4e337c9388f0713110620b40e582b85fdff301 02cd90aa18ec8e3b35c0447ffc713c945cb837429d33d075d1b0f050c72ea838d2'
|
||||
},
|
||||
"addr": "1NqgMfGUeELP2BfxD4hQuJSRq2d3DVJcCi",
|
||||
"valueSat": 1546063700,
|
||||
"value": 15.460637,
|
||||
"doubleSpentTxID": null
|
||||
'addr': '1NqgMfGUeELP2BfxD4hQuJSRq2d3DVJcCi',
|
||||
'valueSat': 1546063700,
|
||||
'value': 15.460637,
|
||||
'doubleSpentTxID': null
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
'vout': [
|
||||
{
|
||||
"value": "0.37100000",
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"hex": "76a914bc345e0e0e5b0dbddb7b35ef3430fedd528dd1b788ac",
|
||||
"asm": "OP_DUP OP_HASH160 bc345e0e0e5b0dbddb7b35ef3430fedd528dd1b7 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
"addresses": [
|
||||
"1JA8mcfrBv1YYsASAp9jtohm8x2q7LnUhs"
|
||||
'value': '0.37100000',
|
||||
'n': 0,
|
||||
'scriptPubKey': {
|
||||
'hex': '76a914bc345e0e0e5b0dbddb7b35ef3430fedd528dd1b788ac',
|
||||
'asm': 'OP_DUP OP_HASH160 bc345e0e0e5b0dbddb7b35ef3430fedd528dd1b7 OP_EQUALVERIFY OP_CHECKSIG',
|
||||
'addresses': [
|
||||
'1JA8mcfrBv1YYsASAp9jtohm8x2q7LnUhs'
|
||||
],
|
||||
"type": "pubkeyhash"
|
||||
'type': 'pubkeyhash'
|
||||
}
|
||||
},
|
||||
{
|
||||
"value": "15.08763700",
|
||||
"n": 1,
|
||||
"scriptPubKey": {
|
||||
"hex": "76a914c2c74d7519d4425fc1a253f066d980164341554a88ac",
|
||||
"asm": "OP_DUP OP_HASH160 c2c74d7519d4425fc1a253f066d980164341554a OP_EQUALVERIFY OP_CHECKSIG",
|
||||
"addresses": [
|
||||
"1Jktr121Hm63qtWBMV8dCNJNW2KtWXy4fp"
|
||||
'value': '15.08763700',
|
||||
'n': 1,
|
||||
'scriptPubKey': {
|
||||
'hex': '76a914c2c74d7519d4425fc1a253f066d980164341554a88ac',
|
||||
'asm': 'OP_DUP OP_HASH160 c2c74d7519d4425fc1a253f066d980164341554a OP_EQUALVERIFY OP_CHECKSIG',
|
||||
'addresses': [
|
||||
'1Jktr121Hm63qtWBMV8dCNJNW2KtWXy4fp'
|
||||
],
|
||||
"type": "pubkeyhash"
|
||||
'type': 'pubkeyhash'
|
||||
}
|
||||
}
|
||||
],
|
||||
"blockhash": "0000000000000000009d2e9b7a984d55c6c99ba62f98e9bc7dad8b1e779045a3",
|
||||
"blockheight": 481763,
|
||||
"confirmations": 4,
|
||||
"time": 1503507151,
|
||||
"blocktime": 1503507151,
|
||||
"valueOut": 15.458637,
|
||||
"size": 225,
|
||||
"valueIn": 15.460637,
|
||||
"fees": 0.002
|
||||
'blockhash': '0000000000000000009d2e9b7a984d55c6c99ba62f98e9bc7dad8b1e779045a3',
|
||||
'blockheight': 481763,
|
||||
'confirmations': 4,
|
||||
'time': 1503507151,
|
||||
'blocktime': 1503507151,
|
||||
'valueOut': 15.458637,
|
||||
'size': 225,
|
||||
'valueIn': 15.460637,
|
||||
'fees': 0.002
|
||||
};
|
||||
|
||||
var bcoinTx = bcoin.tx.fromRaw('010000000156643da30a6f8f3c927f9cc215ad09fae1c1bac29d59a958b4c99ebb688ae546010000006a47304402203ddb49db43074b421ec6d5604ae91aac37f4715139e0c83ea1145379e8cbf02702207fbc92c4038ad501989b097844ae4e337c9388f0713110620b40e582b85fdff3012102cd90aa18ec8e3b35c0447ffc713c945cb837429d33d075d1b0f050c72ea838d2ffffffff02e0193602000000001976a914bc345e0e0e5b0dbddb7b35ef3430fedd528dd1b788ac34e8ed59000000001976a914c2c74d7519d4425fc1a253f066d980164341554a88ac00000000', 'hex');
|
||||
@ -85,7 +85,7 @@ describe('Transactions', function() {
|
||||
getTip: sinon.stub().returns({ height: 481766 })
|
||||
},
|
||||
transaction: {
|
||||
getDetailedTransaction: sinon.stub().callsArgWith(1, null, bcoinTx)
|
||||
getDetailedTransaction: sinon.stub().callsArgWith(2, null, bcoinTx)
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -156,41 +156,41 @@ describe('Transactions', function() {
|
||||
var transactions = new TxController(node);
|
||||
|
||||
var insight = {
|
||||
"pagesTotal": 1,
|
||||
"txs": [
|
||||
'pagesTotal': 1,
|
||||
'txs': [
|
||||
{
|
||||
"txid": "9b0fc92260312ce44e74ef369f5c66bbb85848f2eddd5a7a1cde251e54ccfdd5",
|
||||
"version": 1,
|
||||
"locktime": 0,
|
||||
"vin": [
|
||||
'txid': '9b0fc92260312ce44e74ef369f5c66bbb85848f2eddd5a7a1cde251e54ccfdd5',
|
||||
'version': 1,
|
||||
'locktime': 0,
|
||||
'vin': [
|
||||
{
|
||||
"coinbase": "04ffff001d010b",
|
||||
"sequence": 4294967295,
|
||||
"n": 0
|
||||
'coinbase': '04ffff001d010b',
|
||||
'sequence': 4294967295,
|
||||
'n': 0
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
'vout': [
|
||||
{
|
||||
"value": "50.00000000",
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"hex": "41047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77ac",
|
||||
"asm": "047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77 OP_CHECKSIG",
|
||||
"addresses": [
|
||||
"1HLoD9E4SDFFPDiYfNYnkBLQ85Y51J3Zb1"
|
||||
'value': '50.00000000',
|
||||
'n': 0,
|
||||
'scriptPubKey': {
|
||||
'hex': '41047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77ac',
|
||||
'asm': '047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77 OP_CHECKSIG',
|
||||
'addresses': [
|
||||
'1HLoD9E4SDFFPDiYfNYnkBLQ85Y51J3Zb1'
|
||||
],
|
||||
"type": "pubkeyhash"
|
||||
'type': 'pubkeyhash'
|
||||
}
|
||||
}
|
||||
],
|
||||
"blockhash": "000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd",
|
||||
"blockheight": 2,
|
||||
"confirmations": 481772,
|
||||
"time": 1231469744,
|
||||
"blocktime": 1231469744,
|
||||
"isCoinBase": true,
|
||||
"valueOut": 50,
|
||||
"size": 134
|
||||
'blockhash': '000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd',
|
||||
'blockheight': 2,
|
||||
'confirmations': 481772,
|
||||
'time': 1231469744,
|
||||
'blocktime': 1231469744,
|
||||
'isCoinBase': true,
|
||||
'valueOut': 50,
|
||||
'size': 134
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -238,49 +238,49 @@ describe('Transactions', function() {
|
||||
};
|
||||
|
||||
var insight = {
|
||||
"pagesTotal": 1,
|
||||
"txs": [
|
||||
'pagesTotal': 1,
|
||||
'txs': [
|
||||
{
|
||||
"txid": "1c01a2090db0850e1f1049bea02e4bbf44b6790dfeb8e054f2beb69339ef52d4",
|
||||
"version": 1,
|
||||
"locktime": 0,
|
||||
"vin": [
|
||||
'txid': '1c01a2090db0850e1f1049bea02e4bbf44b6790dfeb8e054f2beb69339ef52d4',
|
||||
'version': 1,
|
||||
'locktime': 0,
|
||||
'vin': [
|
||||
{
|
||||
"coinbase": "03835807244d696e656420627920416e74506f6f6c6a2f4542312f4144362f4e59412f1d205999aaa02b1200001fff0200",
|
||||
"sequence": 4294967295,
|
||||
"n": 0
|
||||
'coinbase': '03835807244d696e656420627920416e74506f6f6c6a2f4542312f4144362f4e59412f1d205999aaa02b1200001fff0200',
|
||||
'sequence': 4294967295,
|
||||
'n': 0
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
'vout': [
|
||||
{
|
||||
"value": "12.85927535",
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"hex": "76a914ad7309dfc032d7f6b652e0c29ee353e63fffec6688ac",
|
||||
"asm": "OP_DUP OP_HASH160 ad7309dfc032d7f6b652e0c29ee353e63fffec66 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
"addresses": [
|
||||
"1Gp7iCzDGMZiV55Kt8uKsux6VyoHe1aJaN"
|
||||
'value': '12.85927535',
|
||||
'n': 0,
|
||||
'scriptPubKey': {
|
||||
'hex': '76a914ad7309dfc032d7f6b652e0c29ee353e63fffec6688ac',
|
||||
'asm': 'OP_DUP OP_HASH160 ad7309dfc032d7f6b652e0c29ee353e63fffec66 OP_EQUALVERIFY OP_CHECKSIG',
|
||||
'addresses': [
|
||||
'1Gp7iCzDGMZiV55Kt8uKsux6VyoHe1aJaN'
|
||||
],
|
||||
"type": "pubkeyhash"
|
||||
'type': 'pubkeyhash'
|
||||
}
|
||||
},
|
||||
{
|
||||
"value": "0.00000000",
|
||||
"n": 1,
|
||||
"scriptPubKey": {
|
||||
"hex": "6a24aa21a9ed55882e9fed16c5d3b6d77e4160a56f58c70d354d02888a99486125b638231c81",
|
||||
"asm": "OP_RETURN aa21a9ed55882e9fed16c5d3b6d77e4160a56f58c70d354d02888a99486125b638231c81"
|
||||
'value': '0.00000000',
|
||||
'n': 1,
|
||||
'scriptPubKey': {
|
||||
'hex': '6a24aa21a9ed55882e9fed16c5d3b6d77e4160a56f58c70d354d02888a99486125b638231c81',
|
||||
'asm': 'OP_RETURN aa21a9ed55882e9fed16c5d3b6d77e4160a56f58c70d354d02888a99486125b638231c81'
|
||||
}
|
||||
}
|
||||
],
|
||||
"blockhash": "000000000000000000926a0cd4a05ef116514cbf1852edc306d13eb951ec0b54",
|
||||
"blockheight": 481411,
|
||||
"confirmations": 52813,
|
||||
"time": 1503242912,
|
||||
"blocktime": 1503242912,
|
||||
"isCoinBase": true,
|
||||
"valueOut": 12.85927535,
|
||||
"size": 181
|
||||
'blockhash': '000000000000000000926a0cd4a05ef116514cbf1852edc306d13eb951ec0b54',
|
||||
'blockheight': 481411,
|
||||
'confirmations': 52813,
|
||||
'time': 1503242912,
|
||||
'blocktime': 1503242912,
|
||||
'isCoinBase': true,
|
||||
'valueOut': 12.85927535,
|
||||
'size': 181
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -321,6 +321,7 @@ describe('Transactions', function() {
|
||||
|
||||
var transactions = new TxController(node);
|
||||
|
||||
var txid = '25a988e54b02e0e5df146a0f8fa7b9db56210533a9f04bdfda5f4ceb6f77aadd';
|
||||
var res = {};
|
||||
var req = {
|
||||
params: {
|
||||
@ -331,7 +332,6 @@ describe('Transactions', function() {
|
||||
should(req.rawTransaction.rawtx).eql(hex);
|
||||
done();
|
||||
};
|
||||
var txid = '25a988e54b02e0e5df146a0f8fa7b9db56210533a9f04bdfda5f4ceb6f77aadd';
|
||||
transactions.rawTransaction(req, res, next);
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user