blockstack
Version:
The Blockstack Javascript library for authentication, identity, and storage.
392 lines (358 loc) • 17 kB
JavaScript
;
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);
});
});
}