Skip to content

Commit

Permalink
fix: tx-gas test using sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
daveroga committed Nov 24, 2021
1 parent ce2344e commit b756504
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 108 deletions.
19 changes: 19 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test/e2e/nightfall-sdk.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ describe('Testing the Nightfall SDK', () => {
before(async () => {
// to enable getBalance with web3 we should connect first
web3 = await connectWeb3();
stateAddress = await nf3User1.getContractAddress('State');
stateAddress = await nf3User1.stateContractAddress;

await nf3User1.init(mnemonicUser1);
await nf3User2.init(mnemonicUser2); // 2nd client to do transfer tests and checks
Expand Down
169 changes: 62 additions & 107 deletions test/tx-gas.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,85 +5,73 @@ import chai from 'chai';
import chaiHttp from 'chai-http';
import chaiAsPromised from 'chai-as-promised';
import WebSocket from 'ws';
import { generateMnemonic } from 'bip39';
import {
ethereumSigningKeyUser1,
ethereumSigningKeyProposer1,
mnemonicUser1,
mnemonicProposer,
BLOCK_STAKE,
bond,
gasCosts,
gas,
tokenType,
value,
tokenId,
fee,
} from './constants.mjs';
import Nf3 from '../cli/lib/nf3.mjs';
import {
closeWeb3Connection,
submitTransaction,
connectWeb3,
getAccounts,
getBalance,
setNonce,
getCurrentEnvironment,
expectTransaction,
getNonce,
} from './utils.mjs';

const { expect } = chai;
chai.use(chaiHttp);
chai.use(chaiAsPromised);
const environment = getCurrentEnvironment();
const { web3WsUrl } = process.env;

describe('Testing the http API', () => {
let shieldAddress;
let challengeAddress;
let proposersAddress;
let stateAddress;
// let stateAddress;
let ercAddress;
let connection; // WS connection
let blockSubmissionFunction;
let web3;
let nsk1;
let ivk1;
let pkd1;

const url = 'http://localhost:8080';
const optimistUrl = 'http://localhost:8081';
const optimistWsUrl = 'ws:localhost:8082';
const tokenId = '0x00';
const tokenType = 'ERC20'; // it can be 'ERC721' or 'ERC1155'
const value = 10;

console.log('ENVIRONMENT: ', environment);
const nf3User1 = new Nf3(web3WsUrl, ethereumSigningKeyUser1, environment);
const nf3Proposer1 = new Nf3(web3WsUrl, ethereumSigningKeyProposer1, environment);

// this is the etherum private key for accounts[0]
const privateKey = '0x4775af73d6dc84a0ae76f8726bda4b9ecf187c377229cb39e1afa7a18236a69e';
const gas = 10000000;
const privateKey = ethereumSigningKeyUser1;
// this is the openethereum test account (but could be anything)
// this is what we pay the proposer for incorporating a transaction
const fee = 1;
const BLOCK_STAKE = 1; // 1 wei
const TRANSACTIONS_PER_BLOCK = 32;

before(async () => {
web3 = await connectWeb3();

let res = await chai.request(url).get('/contract-address/Shield');
shieldAddress = res.body.address;

res = await chai.request(url).get('/contract-address/Challenges');
challengeAddress = res.body.address;
await connectWeb3();

res = await chai.request(url).get('/contract-address/Proposers');
proposersAddress = res.body.address;
await nf3User1.init(mnemonicUser1);
await nf3Proposer1.init(mnemonicProposer);

res = await chai.request(url).get('/contract-address/State');
stateAddress = res.body.address;
const stateAddress = nf3User1.stateContractAddress;

// Generate a random mnemonic (uses crypto.randomBytes under the hood), defaults to 128-bits of entropy
const mnemonic = generateMnemonic();
setNonce(nf3User1.nonce);

({
nsk: nsk1,
ivk: ivk1,
pkd: pkd1,
} = (
await chai.request(url).post('/generate-keys').send({ mnemonic, path: `m/44'/60'/0'/0` })
).body);

setNonce(await web3.eth.getTransactionCount((await getAccounts())[0]));

connection = new WebSocket(optimistWsUrl);
connection = new WebSocket(environment.optimistWsUrl);
connection.onopen = () => {
connection.send('challenge');
connection.send('blocks');
};
connection.onmessage = async message => {
const msg = JSON.parse(message.data);
const { type, txDataToSign } = msg;
if (type === 'block') {
nf3User1.nonce += 1; // in order to manage the nonce between nf3 and utils module
const receipt = await blockSubmissionFunction(
txDataToSign,
privateKey,
Expand All @@ -96,109 +84,76 @@ describe('Testing the http API', () => {
receipt.gasUsed / TRANSACTIONS_PER_BLOCK
}`,
);
} else {
await submitTransaction(txDataToSign, privateKey, challengeAddress, gas);
// console.log('tx hash is', txReceipt.transactionHash);
}
};
});

describe('Miscellaneous tests', () => {
it('should respond with status 200 to the health check', async () => {
const res = await chai.request(url).get('/healthcheck');
expect(res.status).to.equal(200);
it('should respond with "true" to the health check', async () => {
const res = await nf3User1.healthcheck('client');
expect(res).to.be.equal(true);
});

it('should get the address of the shield contract', async () => {
const res = await chai.request(url).get('/contract-address/Shield');
expect(res.body.address).to.be.a('string');
const res = await nf3User1.getContractAddress('Shield');
expect(res).to.be.a('string').and.to.include('0x');
// subscribeToGasUsed(shieldAddress);
});

it('should get the address of the test ERC contract stub', async () => {
const res = await chai.request(url).get('/contract-address/ERCStub');
ercAddress = res.body.address;
expect(ercAddress).to.be.a('string');
ercAddress = await nf3User1.getContractAddress('ERCStub');
expect(ercAddress).to.be.a('string').and.to.include('0x');
});

it('should subscribe to block proposed event with the provided incoming viewing key for optimist1', async function () {
const res = await chai
.request(url)
.post('/incoming-viewing-key')
.send({
ivks: [ivk1],
nsks: [nsk1],
});
expect(res.body.status).to.be.a('string');
expect(res.body.status).to.equal('success');
const res = await nf3User1.subscribeToIncomingViewingKeys();
expect(res.data.status).to.be.a('string');
expect(res.data.status).to.be.equal('success');
});
});

describe('Basic Proposer tests', () => {
let txDataToSign;
it('should register a proposer', async () => {
const myAddress = (await getAccounts())[0];
const res = await chai
.request(optimistUrl)
.post('/proposer/register')
.send({ address: myAddress });
txDataToSign = res.body.txDataToSign;
expect(txDataToSign).to.be.a('string');
let proposers;
({ proposers } = await nf3Proposer1.getProposers());
// we have to pay 10 ETH to be registered
const bond = 10;
const gasCosts = 5000000000000000;
const startBalance = await getBalance(myAddress);
// now we need to sign the transaction and send it to the blockchain
const receipt = await submitTransaction(
txDataToSign,
privateKey,
proposersAddress,
gas,
bond,
);
const endBalance = await getBalance(myAddress);
expect(receipt).to.have.property('transactionHash');
expect(receipt).to.have.property('blockHash');
const startBalance = await getBalance(nf3Proposer1.ethereumAddress);
const res = await nf3Proposer1.registerProposer();
expectTransaction(res);
({ proposers } = await nf3Proposer1.getProposers());
const endBalance = await getBalance(nf3Proposer1.ethereumAddress);
expect(endBalance - startBalance).to.closeTo(-bond, gasCosts);
const thisProposer = proposers.filter(p => p.thisAddress === nf3Proposer1.ethereumAddress);
expect(thisProposer.length).to.be.equal(1);
});
});

describe('Deposit tests', () => {
console.warn(
'WARNING, THE TRANSACTIONS_PER_BLOCK CONSTANT MUST HAVE THE SAME VALUE AS IN NIGHTFALL_OPTIMIST CONFIG OR THIS TEST WILL NOT REPORT CORRECTLY',
);
let txDataToSign;
// blocks should be directly submitted to the blockchain, not queued
blockSubmissionFunction = (a, b, c, d, e) => submitTransaction(a, b, c, d, e);
it('should deposit some crypto into a ZKP commitment', async () => {
for (let i = 0; i < TRANSACTIONS_PER_BLOCK; i++) {
// eslint-disable-next-line no-await-in-loop
const res = await chai.request(url).post('/deposit').send({
ercAddress,
tokenId,
tokenType,
value,
pkd: pkd1,
nsk: nsk1,
fee,
});
txDataToSign = res.body.txDataToSign;
expect(txDataToSign).to.be.a('string');
// now we need to sign the transaction and send it to the blockchain
// eslint-disable-next-line no-await-in-loop
const receipt = await submitTransaction(txDataToSign, privateKey, shieldAddress, gas, fee);
expect(receipt).to.have.property('transactionHash');
expect(receipt).to.have.property('blockHash');
console.log(`Gas used was ${Number(receipt.gasUsed)}`);
const res = await nf3User1.deposit(ercAddress, tokenType, value, tokenId, fee);
setNonce(privateKey, nf3User1.nonce);
expectTransaction(res);
console.log(`Gas used was ${Number(res.gasUsed)}`);

// give Timber time to respond to the blockchain event
await new Promise(resolve => setTimeout(resolve, 3000)); // eslint-disable-line no-await-in-loop
// eslint-disable-next-line no-await-in-loop
await new Promise(resolve => setTimeout(resolve, 3000));
}
});
});

after(() => {
// console.log('end');
closeWeb3Connection();
nf3User1.close();
nf3Proposer1.close();
connection.close();
});
});
4 changes: 4 additions & 0 deletions test/utils.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ export function setNonce(privateKey, _nonce) {
nonceDict[privateKey] = _nonce;
}

export function getNonce(privateKey) {
return nonceDict[privateKey];
}

export async function getAccounts() {
if (process.env.FROM_ADDRESS) return [process.env.FROM_ADDRESS];
const accounts = web3.eth.getAccounts();
Expand Down

0 comments on commit b756504

Please sign in to comment.