chore: fix flaky BNS tests #723

This commit is contained in:
M Hassan Tariq
2021-11-02 17:08:32 +05:00
committed by GitHub
parent 7edc7b54a6
commit 2053d40afd
3 changed files with 350 additions and 398 deletions

View File

@@ -55,6 +55,14 @@ export const testnetKeys: { secretKey: string; stacksAddress: string }[] = [
secretKey: 'e75dcb66f84287eaf347955e94fa04337298dbd95aa0dbb985771104ef1913db01',
stacksAddress: 'STRYYQQ9M8KAF4NS7WNZQYY59X93XEKR31JP64CP',
},
{
secretKey: 'ce109fee08860bb16337c76647dcbc02df0c06b455dd69bcf30af74d4eedd19301',
stacksAddress: 'STF9B75ADQAVXQHNEQ6KGHXTG7JP305J2GRWF3A2',
},
{
secretKey: '08c14a1eada0dd42b667b40f59f7c8dedb12113613448dc04980aea20b268ddb01',
stacksAddress: 'ST18MDW2PDTBSCR1ACXYRJP2JX70FWNM6YY2VX4SS',
},
];
export const testnetKeyMap: Record<

View File

@@ -1,3 +1,6 @@
import { PgDataStore, cycleMigrations, runMigrations } from '../datastore/postgres-store';
import { PoolClient } from 'pg';
import { ApiServer, startApiServer } from '../api/init';
@@ -5,10 +8,9 @@ import * as supertest from 'supertest';
import { startEventServer } from '../event-stream/event-server';
import { Server } from 'net';
import { createHash } from 'crypto';
import { DbTx, DbTxStatus } from '../datastore/common';
import { DbMempoolTx, DbTx, DbTxStatus } from '../datastore/common';
import { AnchorMode, ChainID, PostConditionMode, someCV } from '@stacks/transactions';
import { StacksMocknet } from '@stacks/network';
import * as assert from 'assert';
import {
broadcastTransaction,
@@ -25,6 +27,7 @@ import BigNum = require('bn.js');
import { logger } from '../helpers';
import { testnetKeys } from '../api/routes/debug';
import { importV1BnsData } from '../import-v1';
import * as assert from 'assert';
function hash160(bfr: Buffer): Buffer {
const hash160 = createHash('ripemd160')
@@ -37,22 +40,12 @@ const network = new StacksMocknet();
const deployedTo = 'ST000000000000000000002AMW42H';
const deployedName = 'bns';
const pkey = testnetKeys[0].secretKey;
const address = testnetKeys[0].stacksAddress;
const pkey1 = testnetKeys[1].secretKey;
const address1 = testnetKeys[1].stacksAddress;
const pkey2 = testnetKeys[2].secretKey;
const address2 = testnetKeys[2].stacksAddress;
const salt = Buffer.from('60104ad42ed976f5b8cfd6341496476aa72d1101', 'hex'); // salt and pepper
const namespace = 'foo';
const namespaceHash = hash160(Buffer.concat([Buffer.from(namespace), salt]));
const name = 'alice';
const name1 = 'bob';
const postConditions = [
makeStandardSTXPostCondition(address, FungibleConditionCode.GreaterEqual, new BigNum(1)),
];
type TestnetKey = {
pkey: string;
address: string;
}
describe('BNS integration tests', () => {
let db: PgDataStore;
@@ -96,105 +89,12 @@ describe('BNS integration tests', () => {
return broadcastTx;
}
beforeAll(async () => {
process.env.PG_DATABASE = 'postgres';
await cycleMigrations();
db = await PgDataStore.connect();
client = await db.pool.connect();
eventServer = await startEventServer({ datastore: db, chainId: ChainID.Testnet, httpLogLevel: 'silly' });
api = await startApiServer({ datastore: db, chainId: ChainID.Testnet, httpLogLevel: 'silly' });
//preorder and reveal namespace to the bns network
while (true) {
try {
const txOptions: SignedContractCallOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'namespace-preorder',
functionArgs: [bufferCV(namespaceHash), uintCV(64000000000)],
senderKey: pkey,
validateWithAbi: true,
postConditions: postConditions,
network,
anchorMode: AnchorMode.Any,
};
const transaction = await makeContractCall(txOptions);
const submitResult = await broadcastTransaction(transaction, network);
const preorder = await standByForTx('0x' + transaction.txid());
if (preorder.status != 1) logger.error('Namespace preorder error');
const revealTxOptions: SignedContractCallOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'namespace-reveal',
functionArgs: [
bufferCV(Buffer.from(namespace)),
bufferCV(salt),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(20), //this number is set to expire the name before calling name-revewal
standardPrincipalCV(address),
],
senderKey: pkey,
validateWithAbi: true,
network,
anchorMode: AnchorMode.Any,
};
const revealTransaction = await makeContractCall(revealTxOptions);
await broadcastTransaction(revealTransaction, network);
const reveal = await standByForTx('0x' + revealTransaction.txid());
if (reveal.status != 1) logger.error('Namespace Reveal Error');
break;
} catch (e) {
console.log('error connection', e);
}
}
});
test('name-import contract call', async () => {
const zonefile = `$ORIGIN ${name}.${namespace}\n$TTL 3600\n_http._tcp IN URI 10 1 "https://blockstack.s3.amazonaws.com/${name}.${namespace}"\n`;
const txOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'name-import',
functionArgs: [
bufferCV(Buffer.from(namespace)),
bufferCV(Buffer.from(name)),
standardPrincipalCV(address),
bufferCV(hash160(Buffer.from(zonefile))),
],
senderKey: pkey,
validateWithAbi: true,
network,
anchorMode: AnchorMode.Any,
};
async function getContractTransaction(txOptions: SignedContractCallOptions, zonefile?: string) {
const transaction = await makeContractCall(txOptions);
const body = {
attachment: Buffer.from(zonefile).toString('hex'),
const body: {tx: string, attachment?: string} = {
tx: transaction.serialize().toString('hex'),
};
if(zonefile) body.attachment = Buffer.from(zonefile).toString('hex');
const apiResult = await fetch(network.getBroadcastApiUrl(), {
method: 'post',
body: JSON.stringify(body),
@@ -205,17 +105,84 @@ describe('BNS integration tests', () => {
const result = await standByForTx(expectedTxId);
if (result.status != 1) logger.error('name-import error');
await standbyBnsName(expectedTxId);
const query = await db.getName({ name: `${name}.${namespace}`, includeUnanchored: false });
const query1 = await supertest(api.server).get(`/v1/names/${name}.${namespace}`);
expect(query1.status).toBe(200);
expect(query1.type).toBe('application/json');
expect(query.found).toBe(true);
if (query.found) {
expect(query.result.zonefile).toBe(zonefile);
}
});
return transaction;
}
async function namespacePreorder(namespaceHash: Buffer, testnetKey: TestnetKey) {
const txOptions: SignedContractCallOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'namespace-preorder',
functionArgs: [bufferCV(namespaceHash), uintCV(64000000000)],
senderKey: testnetKey.pkey,
validateWithAbi: true,
postConditions: [makeStandardSTXPostCondition(testnetKey.address, FungibleConditionCode.GreaterEqual, new BigNum(1))],
network,
anchorMode: AnchorMode.Any
};
test('namespace-ready contract call', async () => {
const transaction = await makeContractCall(txOptions);
await broadcastTransaction(transaction, network);
const preorder = await standByForTx('0x' + transaction.txid());
if (preorder.status != 1) logger.error('Namespace preorder error');
return transaction;
}
async function namespaceReveal(namespace: string, salt: Buffer, testnetKey: TestnetKey, expiration: number) {
const revealTxOptions: SignedContractCallOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'namespace-reveal',
functionArgs: [
bufferCV(Buffer.from(namespace)),
bufferCV(salt),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(1),
uintCV(expiration), //this number is set to expire the name before calling name-revewal
standardPrincipalCV(testnetKey.address),
],
senderKey: testnetKey.pkey,
validateWithAbi: true,
network,
anchorMode: AnchorMode.Any
};
const revealTransaction = await makeContractCall(revealTxOptions);
await broadcastTransaction(revealTransaction, network);
const reveal = await standByForTx('0x' + revealTransaction.txid());
if (reveal.status != 1) logger.error('Namespace Reveal Error');
return revealTransaction;
}
async function initiateNamespaceNetwork(namespace: string, salt: Buffer, namespaceHash: Buffer, testnetKey: TestnetKey, expiration: number){
while (true) {
try {
const preorderTransaction = await namespacePreorder(namespaceHash, testnetKey);
const revealTransaction = await namespaceReveal(namespace, salt, testnetKey, expiration);
break;
} catch (e) {
console.log('error connection', e);
}
}
}
async function namespaceReady(namespace: string, pkey: string) {
const txOptions = {
contractAddress: deployedTo,
contractName: deployedName,
@@ -224,24 +191,36 @@ describe('BNS integration tests', () => {
senderKey: pkey,
validateWithAbi: true,
network,
anchorMode: AnchorMode.Any,
anchorMode: AnchorMode.Any
};
const transaction = await makeContractCall(txOptions);
const submitResult = await broadcastTransaction(transaction, network);
await broadcastTransaction(transaction, network);
const readyResult = await standByForTx('0x' + transaction.txid());
if (readyResult.status != 1) logger.error('namespace-ready error');
const query1 = await supertest(api.server).get('/v1/namespaces');
const result = JSON.parse(query1.text);
expect(result.namespaces.includes(namespace)).toBe(true);
});
test('name-update contract call', async () => {
const zonefile = `$TTL 3600
1yeardaily TXT "owner=1MwPD6dH4fE3gQ9mCov81L1DEQWT7E85qH" "seqn=0" "parts=1" "zf0=JE9SSUdJTiAxeWVhcmRhaWx5CiRUVEwgMzYwMApfaHR0cC5fdGNwIFVSSSAxMCAxICJodHRwczovL3BoLmRvdHBvZGNhc3QuY28vMXllYXJkYWlseS9oZWFkLmpzb24iCg=="
_http._tcp URI 10 1 "https://dotpodcast.co/"`;
return transaction;
}
async function nameImport(namespace: string, zonefile: string, name: string, testnetKey: TestnetKey) {
const txOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'name-import',
functionArgs: [
bufferCV(Buffer.from(namespace)),
bufferCV(Buffer.from(name)),
standardPrincipalCV(testnetKey.address),
bufferCV(hash160(Buffer.from(zonefile))),
],
senderKey: testnetKey.pkey,
validateWithAbi: true,
network,
anchorMode: AnchorMode.Any
};
return await getContractTransaction(txOptions, zonefile);
}
async function nameUpdate(namespace: string, zonefile: string, name: string, pkey: string) {
const txOptions = {
contractAddress: deployedTo,
contractName: deployedName,
@@ -254,33 +233,175 @@ describe('BNS integration tests', () => {
senderKey: pkey,
validateWithAbi: true,
network,
anchorMode: AnchorMode.Any,
anchorMode: AnchorMode.Any
};
const transaction = await makeContractCall(txOptions);
const body = {
attachment: Buffer.from(zonefile).toString('hex'),
tx: transaction.serialize().toString('hex'),
return await getContractTransaction(txOptions, zonefile);
}
async function namePreorder(namespace: string, saltName: string, testnetKey: TestnetKey, name: string) {
const postConditions = [
makeStandardSTXPostCondition(testnetKey.address, FungibleConditionCode.GreaterEqual, new BigNum(1)),
];
const fqn = `${name}.${namespace}${saltName}`;
const nameSaltedHash = hash160(Buffer.from(fqn));
const preOrderTxOptions: SignedContractCallOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'name-preorder',
functionArgs: [bufferCV(nameSaltedHash), uintCV(64000000000)],
senderKey: testnetKey.pkey,
validateWithAbi: true,
postConditions: postConditions,
network,
anchorMode: AnchorMode.Any
};
const preOrderTransaction = await makeContractCall(preOrderTxOptions);
await broadcastTransaction(preOrderTransaction, network);
const preorderResult = await standByForTx('0x' + preOrderTransaction.txid());
return preOrderTransaction;
}
async function nameRegister(namespace: string, saltName: string, zonefile: string, testnetKey: TestnetKey, name: string) {
await namePreorder(namespace, saltName, testnetKey, name);
const txOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'name-register',
functionArgs: [
bufferCV(Buffer.from(namespace)),
bufferCV(Buffer.from(name)),
bufferCV(Buffer.from(saltName)),
bufferCV(hash160(Buffer.from(zonefile))),
],
senderKey: testnetKey.pkey,
validateWithAbi: true,
network,
anchorMode: AnchorMode.Any
};
return await getContractTransaction(txOptions, zonefile);
}
async function nameTransfer(namespace: string, name: string, testnetKey: TestnetKey) {
const txOptions: SignedContractCallOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'name-transfer',
functionArgs: [
bufferCV(Buffer.from(namespace)),
bufferCV(Buffer.from(name)),
standardPrincipalCV(testnetKey.address),
noneCV(),
],
senderKey: testnetKey.pkey,
validateWithAbi: true,
postConditionMode: PostConditionMode.Allow,
anchorMode: AnchorMode.Any,
network,
};
return await getContractTransaction(txOptions);
}
async function nameRevoke(namespace: string, name: string, pkey: string) {
const txOptions: SignedContractCallOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'name-revoke',
functionArgs: [bufferCV(Buffer.from(namespace)), bufferCV(Buffer.from(name))],
senderKey: pkey,
validateWithAbi: true,
network,
anchorMode: AnchorMode.Any
};
return await getContractTransaction(txOptions);
}
async function nameRenewal(namespace: string, zonefile: string, pkey: string, name: string) {
const txOptions: SignedContractCallOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'name-renewal',
functionArgs: [
bufferCV(Buffer.from(namespace)),
bufferCV(Buffer.from(name)),
uintCV(2560000),
noneCV(),
someCV(bufferCV(hash160(Buffer.from(zonefile)))),
],
senderKey: pkey,
validateWithAbi: true,
network,
anchorMode: AnchorMode.Any
};
return await getContractTransaction(txOptions);
}
beforeAll(async () => {
process.env.PG_DATABASE = 'postgres';
await cycleMigrations();
db = await PgDataStore.connect();
client = await db.pool.connect();
eventServer = await startEventServer({ datastore: db, chainId: ChainID.Testnet, httpLogLevel: 'silly' });
api = await startApiServer({ datastore: db, chainId: ChainID.Testnet, httpLogLevel: 'silly' });
});
test('name-import/ready/update contract call', async () => {
const namespace = 'name-import';
const name = 'alice';
const importZonefile = `$ORIGIN ${name}.${namespace}\n$TTL 3600\n_http._tcp IN URI 10 1 "https://blockstack.s3.amazonaws.com/${name}.${namespace}"\n`;
const namespaceHash = hash160(Buffer.concat([Buffer.from(namespace), salt]));
const testnetKey = { pkey: testnetKeys[0].secretKey, address: testnetKeys[0].stacksAddress};
// initalizing namespace network - preorder and reveal
await initiateNamespaceNetwork(namespace, salt, namespaceHash, testnetKey, 12);
// testing name import
await nameImport(namespace, importZonefile, name, testnetKey);
const importQuery = await db.getName({ name: `${name}.${namespace}`, includeUnanchored: false });
const importQuery1 = await supertest(api.server).get(`/v1/names/${name}.${namespace}`);
expect(importQuery1.status).toBe(200);
expect(importQuery1.type).toBe('application/json');
expect(importQuery.found).toBe(true);
if (importQuery.found) {
expect(importQuery.result.zonefile).toBe(importZonefile);
}
// testing namespace ready
await namespaceReady(namespace, testnetKey.pkey);
const readyQuery1 = await supertest(api.server).get('/v1/namespaces');
const readyResult = JSON.parse(readyQuery1.text);
expect(readyResult.namespaces.includes(namespace)).toBe(true);
});
test('name-update contract call', async () => {
const namespace = 'name-update';
const name = 'update';
const importZonefile = `$ORIGIN ${name}.${namespace}\n$TTL 3600\n_http._tcp IN URI 10 1 "https://blockstack.s3.amazonaws.com/${name}.${namespace}"\n`;
const namespaceHash = hash160(Buffer.concat([Buffer.from(namespace), salt]));
const testnetKey = { pkey: testnetKeys[1].secretKey, address: testnetKeys[1].stacksAddress};
// initalizing namespace network - preorder and reveal
await initiateNamespaceNetwork(namespace, salt, namespaceHash, testnetKey, 12);
// testing name import
await nameImport(namespace, importZonefile, name, testnetKey);
await namespaceReady(namespace, testnetKey.pkey);
// testing name update 1
let zonefile = `$TTL 3600
1yeardaily TXT "owner=1MwPD6dH4fE3gQ9mCov81L1DEQWT7E85qH" "seqn=0" "parts=1" "zf0=JE9SSUdJTiAxeWVhcmRhaWx5CiRUVEwgMzYwMApfaHR0cC5fdGNwIFVSSSAxMCAxICJodHRwczovL3BoLmRvdHBvZGNhc3QuY28vMXllYXJkYWlseS9oZWFkLmpzb24iCg=="
_http._tcp URI 10 1 "https://dotpodcast.co/"`;
try {
const apiResult = await fetch(network.getBroadcastApiUrl(), {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
});
const submitResult = await apiResult.json();
const expectedTxId = '0x' + transaction.txid();
const result = await standByForTx(expectedTxId);
await standbyBnsName(expectedTxId);
if (result.status != 1) logger.error('name-update error');
// testing name update
await nameUpdate(namespace, zonefile, name, testnetKey.pkey);
const query1 = await supertest(api.server).get(`/v1/names/1yeardaily.${name}.${namespace}`);
expect(query1.status).toBe(200);
expect(query1.type).toBe('application/json');
const query2 = await db.getSubdomain({ subdomain: `1yeardaily.${name}.${namespace}`, includeUnanchored: false });
assert(query2.found);
expect(query2.result.resolver).toBe('');
expect(query2.found).toBe(true);
if(query2.result)
expect(query2.result.resolver).toBe('');
const query3 = await supertest(api.server).get(`/v1/names/${name}.${namespace}`);
expect(query3.status).toBe(200);
@@ -289,10 +410,8 @@ describe('BNS integration tests', () => {
} catch (err: any) {
throw new Error('Error post transaction: ' + err.message);
}
});
test('name-update contract call 1', async () => {
const zonefile = `$TTL 3600
// testing name update 2
zonefile = `$TTL 3600
1yeardaily TXT "owner=1MwPD6dH4fE3gQ9mCov81L1DEQWT7E85qH" "seqn=0" "parts=1" "zf0=JE9SSUdJTiAxeWVhcmRhaWx5CiRUVEwgMzYwMApfaHR0cC5fdGNwIFVSSSAxMCAxICJodHRwczovL3BoLmRvdHBvZGNhc3QuY28vMXllYXJkYWlseS9oZWFkLmpzb24iCg=="Í
2dopequeens TXT "owner=1MwPD6dH4fE3gQ9mCov81L1DEQWT7E85qH" "seqn=0" "parts=1" "zf0=JE9SSUdJTiAyZG9wZXF1ZWVucwokVFRMIDM2MDAKX2h0dHAuX3RjcCBVUkkgMTAgMSAiaHR0cHM6Ly9waC5kb3Rwb2RjYXN0LmNvLzJkb3BlcXVlZW5zL2hlYWQuanNvbiIK"
10happier TXT "owner=1MwPD6dH4fE3gQ9mCov81L1DEQWT7E85qH" "seqn=0" "parts=1" "zf0=JE9SSUdJTiAxMGhhcHBpZXIKJFRUTCAzNjAwCl9odHRwLl90Y3AgVVJJIDEwIDEgImh0dHBzOi8vcGguZG90cG9kY2FzdC5jby8xMGhhcHBpZXIvaGVhZC5qc29uIgo="
@@ -303,38 +422,7 @@ describe('BNS integration tests', () => {
10minuteteacher TXT "owner=1MwPD6dH4fE3gQ9mCov81L1DEQWT7E85qH" "seqn=0" "parts=1" "zf0=JE9SSUdJTiAxMG1pbnV0ZXRlYWNoZXIKJFRUTCAzNjAwCl9odHRwLl90Y3AgVVJJIDEwIDEgImh0dHBzOi8vcGguZG90cG9kY2FzdC5jby8xMG1pbnV0ZXRlYWNoZXIvaGVhZC5qc29uIgo="
36questionsthepodcastmusical TXT "owner=1MwPD6dH4fE3gQ9mCov81L1DEQWT7E85qH" "seqn=0" "parts=1" "zf0=JE9SSUdJTiAzNnF1ZXN0aW9uc3RoZXBvZGNhc3RtdXNpY2FsCiRUVEwgMzYwMApfaHR0cC5fdGNwIFVSSSAxMCAxICJodHRwczovL3BoLmRvdHBvZGNhc3QuY28vMzZxdWVzdGlvbnN0aGVwb2RjYXN0bXVzaWNhbC9oZWFkLmpzb24iCg=="
_http._tcp URI 10 1 "https://dotpodcast.co/"`;
const txOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'name-update',
functionArgs: [
bufferCV(Buffer.from(namespace)),
bufferCV(Buffer.from(name)),
bufferCV(hash160(Buffer.from(zonefile))),
],
senderKey: pkey,
validateWithAbi: true,
network,
anchorMode: AnchorMode.Any,
};
const transaction = await makeContractCall(txOptions);
const body = {
attachment: Buffer.from(zonefile).toString('hex'),
tx: transaction.serialize().toString('hex'),
};
const apiResult = await fetch(network.getBroadcastApiUrl(), {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
});
const submitResult = await apiResult.json();
const expectedTxId = '0x' + transaction.txid();
const result = await standByForTx(expectedTxId);
await standbyBnsName(expectedTxId);
if (result.status != 1) logger.error('name-update error');
await nameUpdate(namespace, zonefile, name, testnetKey.pkey);
const query1 = await supertest(api.server).get(`/v1/names/2dopequeens.${name}.${namespace}`);
expect(query1.status).toBe(200);
expect(query1.type).toBe('application/json');
@@ -358,176 +446,59 @@ describe('BNS integration tests', () => {
const query5 = await supertest(api.server).get(`/v1/names/excluded.${name}.${namespace}`);
expect(query5.status).toBe(404);
expect(query5.type).toBe('application/json');
});
test('name-update contract call 2', async () => {
const zonefile = `$TTL 3600
// testing nameupdate 3
zonefile = `$TTL 3600
_http._tcp URI 10 1 "https://dotpodcast.co/"`;
const txOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'name-update',
functionArgs: [
bufferCV(Buffer.from(namespace)),
bufferCV(Buffer.from(name)),
bufferCV(hash160(Buffer.from(zonefile))),
],
senderKey: pkey,
validateWithAbi: true,
network,
anchorMode: AnchorMode.Any,
};
const transaction = await makeContractCall(txOptions);
const body = {
attachment: Buffer.from(zonefile).toString('hex'),
tx: transaction.serialize().toString('hex'),
};
await nameUpdate(namespace, zonefile, name, testnetKey.pkey);
try {
const apiResult = await fetch(network.getBroadcastApiUrl(), {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
});
const submitResult = await apiResult.json();
const expectedTxId = '0x' + transaction.txid();
const result = await standByForTx(expectedTxId);
await standbyBnsName(expectedTxId);
if (result.status != 1) logger.error('name-update error');
const query1 = await supertest(api.server).get(`/v1/names/2dopequeens.${name}.${namespace}`); //check if previous sobdomains are still there
expect(query1.status).toBe(200);
expect(query1.type).toBe('application/json');
const query2 = await db.getSubdomainsList({ page: 0, includeUnanchored: false });
expect(query2.results).toContain(`1yeardaily.${name}.${namespace}`);
const query3 = await supertest(api.server).get(`/v1/names/${name}.${namespace}`);
expect(query3.status).toBe(200);
expect(query3.type).toBe('application/json');
expect(query3.body.zonefile).toBe(zonefile);
const query6 = await supertest(api.server).get(`/v1/names/2dopequeens.${name}.${namespace}`); //check if previous sobdomains are still there
expect(query6.status).toBe(200);
expect(query6.type).toBe('application/json');
const query7 = await db.getSubdomainsList({ page: 0, includeUnanchored: false });
expect(query7.results).toContain(`1yeardaily.${name}.${namespace}`);
const query8 = await supertest(api.server).get(`/v1/names/${name}.${namespace}`);
expect(query8.status).toBe(200);
expect(query8.type).toBe('application/json');
expect(query8.body.zonefile).toBe(zonefile);
} catch (err: any) {
throw new Error('Error post transaction: ' + err.message);
}
});
test('name-register contract call', async () => {
const postConditions = [
makeStandardSTXPostCondition(address1, FungibleConditionCode.GreaterEqual, new BigNum(1)),
];
//name pre-order
test('name-register/transfer contract call', async () => {
const saltName = '0000';
const fqn = `${name1}.${namespace}${saltName}`;
const nameSaltedHash = hash160(Buffer.from(fqn));
const preOrderTxOptions: SignedContractCallOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'name-preorder',
functionArgs: [bufferCV(nameSaltedHash), uintCV(64000000000)],
senderKey: pkey1,
validateWithAbi: true,
postConditions: postConditions,
network,
anchorMode: AnchorMode.Any,
};
const name = 'bob';
const namespace = 'name-register';
const namespaceHash = hash160(Buffer.concat([Buffer.from(namespace), salt]));
const zonefile = `$ORIGIN ${name}.${namespace}\n$TTL 3600\n_http._tcp IN URI 10 1 "https://blockstack.s3.amazonaws.com/${name}.${namespace}"\n`;
const importZonefile = `$ORIGIN ${name}.${namespace}\n$TTL 3600\n_http._tcp IN URI 10 1 "https://blockstack.s3.amazonaws.com/${name}.${namespace}"\n`;
const testnetKey = { pkey: testnetKeys[2].secretKey, address: testnetKeys[2].stacksAddress};
// initializing namespace network
await initiateNamespaceNetwork(namespace, salt, namespaceHash, testnetKey, 12);
await namespaceReady(namespace, testnetKey.pkey);
const preOrderTransaction = await makeContractCall(preOrderTxOptions);
const broadcastTxResult = await broadcastTransaction(preOrderTransaction, network);
const preorderResult = await standByForTx('0x' + preOrderTransaction.txid());
//name register
const zonefile = `$ORIGIN ${name1}.${namespace}\n$TTL 3600\n_http._tcp IN URI 10 1 "https://blockstack.s3.amazonaws.com/${name1}.${namespace}"\n`;
const txOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'name-register',
functionArgs: [
bufferCV(Buffer.from(namespace)),
bufferCV(Buffer.from(name1)),
bufferCV(Buffer.from(saltName)),
bufferCV(hash160(Buffer.from(zonefile))),
],
senderKey: pkey1,
validateWithAbi: true,
network,
anchorMode: AnchorMode.Any,
};
const transaction = await makeContractCall(txOptions);
const body = {
attachment: Buffer.from(zonefile).toString('hex'),
tx: transaction.serialize().toString('hex'),
};
const apiResult = await fetch(network.getBroadcastApiUrl(), {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
});
const submitResult = await apiResult.json();
const expectedTxId = '0x' + transaction.txid();
const result = await standByForTx(expectedTxId);
await standbyBnsName(expectedTxId);
if (result.status != 1) logger.error('name-register error');
const query1 = await supertest(api.server).get(`/v1/names/${name1}.${namespace}`);
// testing name register
await nameRegister(namespace, saltName, zonefile, testnetKey, name);
const query1 = await supertest(api.server).get(`/v1/names/${name}.${namespace}`);
expect(query1.status).toBe(200);
expect(query1.type).toBe('application/json');
const query = await db.getName({ name: `${name1}.${namespace}`, includeUnanchored: false });
const query = await db.getName({ name: `${name}.${namespace}`, includeUnanchored: false });
expect(query.found).toBe(true);
if (query.found) {
expect(query.result.zonefile).toBe(zonefile);
}
});
test('name-transfer contract call', async () => {
//name owned by address before calling name-transfer
const query1 = await supertest(api.server).get(`/v1/names/${name}.${namespace}`);
expect(query1.status).toBe(200);
expect(query1.type).toBe('application/json');
expect(query1.body.address).toBe(address);
//name transfer
const txOptions: SignedContractCallOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'name-transfer',
functionArgs: [
bufferCV(Buffer.from(namespace)),
bufferCV(Buffer.from(name)),
standardPrincipalCV(address2),
noneCV(),
],
senderKey: pkey,
validateWithAbi: true,
postConditionMode: PostConditionMode.Allow,
anchorMode: AnchorMode.Any,
network,
};
const transaction = await makeContractCall(txOptions);
const body = {
tx: transaction.serialize().toString('hex'),
};
// testing name transfer
const transferTestnetKey = { pkey: testnetKeys[2].secretKey, address: testnetKeys[3].stacksAddress};
await nameTransfer(namespace, name, transferTestnetKey);
try {
const apiResult = await fetch(network.getBroadcastApiUrl(), {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
});
const submitResult = await apiResult.json();
const expectedTxId = '0x' + transaction.txid();
const result = await standByForTx(expectedTxId);
await standbyBnsName(expectedTxId);
if (result.status != 1) logger.error('name-transfer error');
const query1 = await supertest(api.server).get(`/v1/names/${name}.${namespace}`);
expect(query1.status).toBe(200);
expect(query1.type).toBe('application/json');
expect(query1.body.zonefile).toBe('');
expect(query1.body.status).toBe('name-transfer');
expect(query1.body.address).toBe(address2);
} catch (err: any) {
throw new Error('Error post transaction: ' + err.message);
}
@@ -535,35 +506,19 @@ describe('BNS integration tests', () => {
test('name-revoke contract call', async () => {
//name revoke
const txOptions: SignedContractCallOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'name-revoke',
functionArgs: [bufferCV(Buffer.from(namespace)), bufferCV(Buffer.from(name))],
senderKey: pkey2,
validateWithAbi: true,
network,
anchorMode: AnchorMode.Any,
};
const namespace = 'name-revoke';
const name = 'foo';
const namespaceHash = hash160(Buffer.concat([Buffer.from(namespace), salt]));
const testnetKey = { pkey: testnetKeys[4].secretKey, address: testnetKeys[4].stacksAddress};
const zonefile = `$ORIGIN ${name}.${namespace}\n$TTL 3600\n_http._tcp IN URI 10 1 "https://blockstack.s3.amazonaws.com/${name}.${namespace}"\n`;
// initializing namespace network
await initiateNamespaceNetwork(namespace, salt, namespaceHash, testnetKey, 12);
await nameImport(namespace, zonefile, name, testnetKey);
await namespaceReady(namespace, testnetKey.pkey);
const transaction = await makeContractCall(txOptions);
const body = {
tx: transaction.serialize().toString('hex'),
};
const apiResult = await fetch(network.getBroadcastApiUrl(), {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
});
const submitResult = await apiResult.json();
const expectedTxId = '0x' + transaction.txid();
const result = await standByForTx(expectedTxId);
await standbyBnsName(expectedTxId);
if (result.status !== 1) {
throw new Error('name-revoke error');
}
// testing name revoke
const transaction = await nameRevoke(namespace, name, testnetKey.pkey);
const query1 = await supertest(api.server).get(`/v1/names/${name}.${namespace}`);
expect(query1.status).toBe(200);
expect(query1.type).toBe('application/json');
@@ -572,43 +527,20 @@ describe('BNS integration tests', () => {
test('name-renewal contract call', async () => {
const zonefile = `new zone file`;
const namespace = 'name-renewal';
const name = 'renewal';
const namespaceHash = hash160(Buffer.concat([Buffer.from(namespace), salt]));
const testnetKey = { pkey: testnetKeys[5].secretKey, address: testnetKeys[5].stacksAddress};
// initializing namespace network
await initiateNamespaceNetwork(namespace, salt, namespaceHash, testnetKey, 1);
await nameImport(namespace, zonefile, name, testnetKey);
await namespaceReady(namespace, testnetKey.pkey);
//name renewal
const txOptions: SignedContractCallOptions = {
contractAddress: deployedTo,
contractName: deployedName,
functionName: 'name-renewal',
functionArgs: [
bufferCV(Buffer.from(namespace)),
bufferCV(Buffer.from(name1)),
uintCV(2560000),
noneCV(),
someCV(bufferCV(hash160(Buffer.from(zonefile)))),
],
senderKey: pkey1,
validateWithAbi: true,
network,
anchorMode: AnchorMode.Any,
};
const transaction = await makeContractCall(txOptions);
const body = {
attachment: Buffer.from(zonefile).toString('hex'),
tx: transaction.serialize().toString('hex'),
};
await nameRenewal(namespace, zonefile, testnetKey.pkey, name);
try {
const apiResult = await fetch(network.getBroadcastApiUrl(), {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
});
const submitResult = await apiResult.json();
const expectedTxId = '0x' + transaction.txid();
const result = await standByForTx(expectedTxId);
await standbyBnsName(expectedTxId);
if (result.status != 1) logger.error('name-renewal: error');
const query1 = await supertest(api.server).get(`/v1/names/${name1}.${namespace}`);
const query1 = await supertest(api.server).get(`/v1/names/${name}.${namespace}`);
expect(query1.status).toBe(200);
expect(query1.type).toBe('application/json');
expect(query1.body.zonefile).toBe(zonefile);
@@ -653,7 +585,8 @@ describe('BNS integration tests', () => {
const dbquery = await db.getSubdomain({ subdomain: `flushreset.id.blockstack`, includeUnanchored: false });
assert(dbquery.found)
expect(dbquery.result.name).toBe('id.blockstack');
if (dbquery.result){
expect(dbquery.result.name).toBe('id.blockstack');}
});
afterAll(async () => {
@@ -664,3 +597,4 @@ describe('BNS integration tests', () => {
await runMigrations(undefined, 'down');
});
});

View File

@@ -27,3 +27,13 @@ amount = 10000000000000000
address = "STRYYQQ9M8KAF4NS7WNZQYY59X93XEKR31JP64CP"
amount = 10000000000000000
# secretKey = "e75dcb66f84287eaf347955e94fa04337298dbd95aa0dbb985771104ef1913db01"
[[mstx_balance]]
address = "STF9B75ADQAVXQHNEQ6KGHXTG7JP305J2GRWF3A2"
amount = 10000000000000000
# secretKey = "ce109fee08860bb16337c76647dcbc02df0c06b455dd69bcf30af74d4eedd19301"
[[mstx_balance]]
address = "ST18MDW2PDTBSCR1ACXYRJP2JX70FWNM6YY2VX4SS"
amount = 10000000000000000
# secretKey = "08c14a1eada0dd42b667b40f59f7c8dedb12113613448dc04980aea20b268ddb01"