UNPKG

blockstack

Version:

The Blockstack Javascript library for authentication, identity, and storage.

392 lines (358 loc) 17 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.runIntegrationTests = runIntegrationTests; var _child_process = require('child_process'); var _tape = require('tape'); var _tape2 = _interopRequireDefault(_tape); var _lib = require('../../../lib'); var _utils = require('../../../lib/operations/utils'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var BLOCKSTACK_TEST = !!process.env.BLOCKSTACK_TEST; function pExec(cmd) { return new Promise(function (resolve, reject) { (0, _child_process.exec)(cmd, function (err, stdout, stderr) { if (err) { reject(err); } else { resolve(stdout, stderr); } }); }); } function initializeBlockstackCore() { if (BLOCKSTACK_TEST) { // running with an external test suite return Promise.resolve(); } else { return pExec('docker pull quay.io/blockstack/integrationtests:develop').then(function () { console.log('Pulled latest docker image'); return pExec('docker stop test-bsk-core ;\n docker rm test-bsk-core ;\n rm -rf /tmp/.blockstack_int_test').catch(function () { return true; }); }).then(function () { return pExec('docker run --name test-bsk-core -dt ' + '-p 16268:16268 -p 18332:18332 -p 30001:30001 ' + '-e BLOCKSTACK_TEST_CLIENT_RPC_PORT=16268 ' + '-e BLOCKSTACK_TEST_CLIENT_BIND=0.0.0.0 ' + '-e BLOCKSTACK_TEST_BITCOIND_ALLOWIP=172.17.0.0/16 ' + '-e BLOCKSTACK_WEB_TEST_BIND=0.0.0.0 ' + 'quay.io/blockstack/integrationtests:develop ' + 'blockstack-test-scenario --interactive 2 ' + 'blockstack_integration_tests.scenarios.portal_test_env'); }).then(function () { console.log('Started regtest container, waiting until initialized'); return pExec('docker logs -f test-bsk-core | grep -q \'Test finished\''); }).then(function () { // try to avoid race with nextBlock() console.log('Wait 10 seconds for test server to bind'); return new Promise(function (resolve) { return setTimeout(resolve, 10000); }); }); } } function nextBlock(numBlocks) { if (BLOCKSTACK_TEST) { var options = { method: 'POST' }; if (!!numBlocks) { options.body = 'numblocks=' + numBlocks; } var url = 'http://localhost:30001/nextblock'; return fetch(url, options).then(function (resp) { if (resp.status >= 400) { throw new Error('Bad test framework status: ' + resp.status); } else { return true; } }); } else { return new Promise(function (resolve) { return setTimeout(resolve, 30000); }); } } function shutdownBlockstackCore() { if (BLOCKSTACK_TEST) { return Promise.resolve(); } else { return pExec('docker stop test-bsk-core'); } } function runIntegrationTests() { (0, _tape2.default)('registerIdName', function (t) { t.plan(8); _lib.config.network = _lib.network.defaults.LOCAL_REGTEST; var myNet = _lib.config.network; var dest = '19238846ac60fa62f8f8bb8898b03df79bc6112600181f36061835ad8934086001'; var destAddress = (0, _lib.hexStringToECPair)(dest).getAddress(); var btcDest = '897f1b92041b798580f96b8be379053f6276f04eb7590a9042a62059d46d6fc301'; var btcDestAddress = (0, _lib.hexStringToECPair)(btcDest).getAddress(); var payer = 'bb68eda988e768132bc6c7ca73a87fb9b0918e9a38d3618b74099be25f7cab7d01'; var secondOwner = '54164693e3803223f7fa9a004997bfbf1475f5c44f65593fa45c6783086dafec01'; var transferDestination = (0, _lib.hexStringToECPair)(secondOwner).getAddress(); var renewalDestination = 'myPgwEX2ddQxPPqWBRkXNqL3TwuWbY29DJ'; var zfTest = '$ORIGIN aaron.id\n$TTL 3600\n_http._tcp URI 10 1 ' + ('"https://gaia.blockstacktest.org/hub/' + destAddress + '/0/profile.json"'); var zfTest2 = '$ORIGIN aaron.id\n$TTL 3600\n_http._tcp URI 10 1 ' + ('"https://gaia.blockstacktest.org/hub/' + destAddress + '/3/profile.json"'); var renewalZF = '$ORIGIN aaron.id\n$TTL 3600\n_http._tcp URI 10 1 ' + ('"https://gaia.blockstacktest.org/hub/' + destAddress + '/4/profile.json"'); initializeBlockstackCore().then(function () { console.log('Blockstack Core initialized.'); return _lib.transactions.makePreorder('aaron.id', destAddress, payer); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('PREORDER broadcasted, waiting 30 seconds.'); return nextBlock(); }).then(function () { return _lib.transactions.makeRegister('aaron.id', destAddress, payer, zfTest); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('REGISTER broadcasted, waiting 30 seconds.'); return nextBlock(); }).then(function () { return myNet.broadcastZoneFile(zfTest); }).then(function () { return fetch(myNet.blockstackAPIUrl + '/v1/names/aaron.id'); }).then(function (resp) { return resp.json(); }).then(function (nameInfo) { t.equal(myNet.coerceAddress(nameInfo.address), destAddress, 'aaron.id should be owned by ' + destAddress); t.equal(nameInfo.zonefile, zfTest, 'zonefile should be properly set'); }).then(function () { return _lib.transactions.makeUpdate('aaron.id', dest, payer, zfTest2); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('UPDATE broadcasted, waiting 30 seconds.'); return nextBlock(); }).then(function () { return myNet.broadcastZoneFile(zfTest2); }).then(function () { return fetch(myNet.blockstackAPIUrl + '/v1/names/aaron.id'); }).then(function (resp) { return resp.json(); }).then(function (nameInfo) { t.equal(nameInfo.zonefile, zfTest2, 'zonefile should be updated'); }).then(function () { return _lib.transactions.makeTransfer('aaron.id', transferDestination, dest, payer); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('TRANSFER broadcasted, waiting 30 seconds.'); return nextBlock(); }).then(function () { return fetch(myNet.blockstackAPIUrl + '/v1/names/aaron.id'); }).then(function (resp) { return resp.json(); }).then(function (nameInfo) { t.equal(myNet.coerceAddress(nameInfo.address), transferDestination, 'aaron.id should be owned by ' + transferDestination); }).then(function () { return _lib.transactions.makeRenewal('aaron.id', renewalDestination, secondOwner, payer, renewalZF); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('RENEWAL broadcasted, waiting 30 seconds.'); return nextBlock(); }).then(function () { return myNet.broadcastZoneFile(renewalZF); }).then(function () { return fetch(myNet.blockstackAPIUrl + '/v1/names/aaron.id'); }).then(function (resp) { return resp.json(); }).then(function (nameInfo) { t.equal(nameInfo.zonefile, renewalZF, 'zonefile should be updated'); t.equal(myNet.coerceAddress(nameInfo.address), renewalDestination, 'aaron.id should be owned by ' + renewalDestination); }).then(function () { return _lib.transactions.makeBitcoinSpend(btcDestAddress, payer, 500000); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('broadcasted SPEND, waiting 10 seconds.'); return nextBlock(); }).then(function () { return myNet.getUTXOs(btcDestAddress); }).then(function (utxos) { t.equal(utxos.length, 1, 'Destination address ' + btcDestAddress + ' should have 1 UTXO'); var satoshis = utxos.reduce(function (agg, utxo) { return agg + utxo.value; }, 0); console.log(btcDestAddress + ' has ' + satoshis + ' satoshis'); }).then(function () { return shutdownBlockstackCore(); }).then(function () { return t.pass('Finished test'); }); }); (0, _tape2.default)('helloNamespace', function (t) { t.plan(11); _lib.config.network = _lib.network.defaults.LOCAL_REGTEST; var myNet = _lib.config.network; var nsPay = '6e50431b955fe73f079469b24f06480aee44e4519282686433195b3c4b5336ef01'; var nsReveal = 'c244642ce0b4eb68da8e098facfcad889e3063c36a68b7951fb4c085de49df1b01'; var nsRevealAddress = (0, _lib.hexStringToECPair)(nsReveal).getAddress(); var dest = '19238846ac60fa62f8f8bb8898b03df79bc6112600181f36061835ad8934086001'; var destAddress = (0, _lib.hexStringToECPair)(dest).getAddress(); var btcDest = '3ad9f690cc7694572fe7574526ad260ff2e711d608d3224895efd932b1d47c7201'; var btcDestAddress = (0, _lib.hexStringToECPair)(btcDest).getAddress(); var payer = 'bb68eda988e768132bc6c7ca73a87fb9b0918e9a38d3618b74099be25f7cab7d01'; var secondOwner = '54164693e3803223f7fa9a004997bfbf1475f5c44f65593fa45c6783086dafec01'; var transferDestination = (0, _lib.hexStringToECPair)(secondOwner).getAddress(); var renewalKey = 'bb68eda988e768132bc6c7ca73a87fb9b0918e9a38d3618b74099be25f7cab7d'; var renewalDestination = (0, _lib.hexStringToECPair)(renewalKey).getAddress(); var zfTest = '$ORIGIN aaron.hello\n$TTL 3600\n_http._tcp URI 10 1 ' + ('"https://gaia.blockstacktest.org/hub/' + destAddress + '/0/profile.json"'); var zfTest2 = '$ORIGIN aaron.hello\n$TTL 3600\n_http._tcp URI 10 1 ' + ('"https://gaia.blockstacktest.org/hub/' + destAddress + '/3/profile.json"'); var renewalZF = '$ORIGIN aaron.hello\n$TTL 3600\n_http._tcp URI 10 1 ' + ('"https://gaia.blockstacktest.org/hub/' + destAddress + '/4/profile.json"'); var importZF = '$ORIGIN import.hello\n$TTL 3600\n_http._tcp URI 10 1 ' + ('"https://gaia.blockstacktest.org/hub/' + destAddress + '/0/profile.json"'); initializeBlockstackCore().then(function () { console.log('Blockstack Core initialized.'); console.log('Preorder namespace "hello" to ' + nsRevealAddress); return _lib.transactions.makeNamespacePreorder('hello', nsRevealAddress, nsPay); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('NAMESPACE_PREORDER broadcasted, waiting 30 seconds.'); return nextBlock(); }).then(function () { var ns = new _lib.transactions.BlockstackNamespace('hello'); ns.setVersion(1); ns.setLifetime(52595); ns.setCoeff(4); ns.setBase(4); ns.setBuckets([6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]); ns.setNonalphaDiscount(10); ns.setNoVowelDiscount(10); console.log('Reveal namespace "hello" to ' + nsRevealAddress); return _lib.transactions.makeNamespaceReveal(ns, nsRevealAddress, nsPay); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('NAMESPACE_REVEAL broadcasted, waiting 30 seconds.'); return nextBlock(); }).then(function () { console.log('NAME_IMPORT import.hello'); var zfHash = (0, _utils.hash160)(Buffer.from(importZF)).toString('hex'); return _lib.transactions.makeNameImport('import.hello', renewalDestination, zfHash, nsReveal); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('NAME_IMPORT broadcasted, waiting 30 seconds.'); return nextBlock(); }).then(function () { return myNet.broadcastZoneFile(importZF); }).then(function () { return fetch(myNet.blockstackAPIUrl + '/v1/names/import.hello'); }).then(function (resp) { return resp.json(); }).then(function (nameInfo) { t.equal(myNet.coerceAddress(nameInfo.address), renewalDestination, 'import.hello should be owned by ' + renewalDestination); t.equal(nameInfo.zonefile, importZF, 'zonefile should be properly set for import.hello'); }).then(function () { console.log('Launch namespace "hello"'); return _lib.transactions.makeNamespaceReady('hello', nsReveal); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('NAMESPACE_READY broadcasted, waiting 30 seconds.'); return nextBlock(); }).then(function () { console.log('Namespace initialized. Preordering aaron.hello'); return _lib.transactions.makePreorder('aaron.hello', destAddress, payer); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('PREORDER broadcasted, waiting 30 seconds.'); return nextBlock(); }).then(function () { return _lib.transactions.makeRegister('aaron.hello', destAddress, payer, zfTest); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('REGISTER broadcasted, waiting 30 seconds.'); return nextBlock(); }).then(function () { return myNet.broadcastZoneFile(zfTest); }).then(function () { return fetch(myNet.blockstackAPIUrl + '/v1/names/aaron.hello'); }).then(function (resp) { return resp.json(); }).then(function (nameInfo) { t.equal(myNet.coerceAddress(nameInfo.address), destAddress, 'aaron.hello should be owned by ' + destAddress); t.equal(nameInfo.zonefile, zfTest, 'zonefile should be properly set'); }).then(function () { return _lib.transactions.makeUpdate('aaron.hello', dest, payer, zfTest2); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('UPDATE broadcasted, waiting 30 seconds.'); return nextBlock(); }).then(function () { return myNet.broadcastZoneFile(zfTest2); }).then(function () { return fetch(myNet.blockstackAPIUrl + '/v1/names/aaron.hello'); }).then(function (resp) { return resp.json(); }).then(function (nameInfo) { t.equal(nameInfo.zonefile, zfTest2, 'zonefile should be updated'); }).then(function () { return _lib.transactions.makeTransfer('aaron.hello', transferDestination, dest, payer); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('TRANSFER broadcasted, waiting 30 seconds.'); return nextBlock(); }).then(function () { return fetch(myNet.blockstackAPIUrl + '/v1/names/aaron.hello'); }).then(function (resp) { return resp.json(); }).then(function (nameInfo) { t.equal(myNet.coerceAddress(nameInfo.address), transferDestination, 'aaron.hello should be owned by ' + transferDestination); }).then(function () { return _lib.transactions.makeRenewal('aaron.hello', renewalDestination, secondOwner, payer, renewalZF); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('RENEWAL broadcasted, waiting 30 seconds.'); return nextBlock(); }).then(function () { return myNet.broadcastZoneFile(renewalZF); }).then(function () { return fetch(myNet.blockstackAPIUrl + '/v1/names/aaron.hello'); }).then(function (resp) { return resp.json(); }).then(function (nameInfo) { t.equal(nameInfo.zonefile, renewalZF, 'zonefile should be updated'); t.equal(myNet.coerceAddress(nameInfo.address), renewalDestination, 'aaron.hello should be owned by ' + renewalDestination); }).then(function () { return _lib.transactions.makeRevoke('aaron.hello', renewalKey, payer); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('REVOKE broadcasted, waiting 30 seconds.'); return nextBlock(); }).then(function () { return fetch(myNet.blockstackAPIUrl + '/v1/names/aaron.hello'); }).then(function (resp) { return resp.json(); }).then(function (nameInfo) { t.equal(nameInfo.status, 'revoked', 'Name should be revoked'); }).then(function () { return _lib.transactions.makeBitcoinSpend(btcDestAddress, payer, 500000); }).then(function (rawtx) { return myNet.broadcastTransaction(rawtx); }).then(function () { console.log('broadcasted SPEND, waiting 10 seconds.'); return nextBlock(6); }).then(function () { return myNet.getUTXOs(btcDestAddress); }).then(function (utxos) { t.equal(utxos.length, 1, 'Destination address ' + btcDestAddress + ' should have 1 UTXO'); var satoshis = utxos.reduce(function (agg, utxo) { return agg + utxo.value; }, 0); console.log(btcDestAddress + ' has ' + satoshis + ' satoshis'); }).then(function () { return shutdownBlockstackCore(); }).then(function () { return t.pass('Finished test'); }).catch(function (err) { console.log(err.stack); console.log(err); }); }); }