From d17a4e0e326876dbaaae4f3d2212e90595444ea5 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 30 Jun 2022 20:18:32 +0200 Subject: [PATCH 1/7] fix: adversary test --- docker-compose.adversary.yml | 9 +- docker-compose.host.docker.internal.yml | 7 -- docker-compose.wallet-test.yml | 18 ---- nightfall-optimist/start-optimist.sh | 95 ++++++++++++------- package.json | 3 +- start-nightfall | 27 ------ test/adversary.test.mjs | 36 ++++++- test/adversary/adversary-code/block.mjs | 55 +++++++---- test/adversary/adversary-code/database.mjs | 55 +++++++---- test/adversary/adversary-code/route-block.mjs | 25 +++++ test/adversary/transpile-adversary.mjs | 29 +++++- test/neg-http.mjs | 12 ++- 12 files changed, 241 insertions(+), 130 deletions(-) delete mode 100644 docker-compose.wallet-test.yml create mode 100644 test/adversary/adversary-code/route-block.mjs diff --git a/docker-compose.adversary.yml b/docker-compose.adversary.yml index d29d00c2f..41c73a7c2 100644 --- a/docker-compose.adversary.yml +++ b/docker-compose.adversary.yml @@ -2,6 +2,8 @@ version: '3.5' # Use this script for making an adversary service services: adversary1: + extra_hosts: + - 'host.docker.internal:host-gateway' build: dockerfile: optimist.Dockerfile context: . @@ -32,6 +34,11 @@ services: BLOCKCHAIN_PORT: 8546 HASH_TYPE: mimc LOG_LEVEL: debug - IS_CHALLENGER: 'false' + IS_CHALLENGER: 'true' TRANSACTIONS_PER_BLOCK: ${TRANSACTIONS_PER_BLOCK:-2} + AUTOSTART_RETRIES: 100 + BAD_BLOCK_SEQUENCE: ${BAD_BLOCK_SEQUENCE} + BAD_TX_SEQUENCE: ${BAD_TX_SEQUENCE} command: ['npm', 'run', 'dev'] + + diff --git a/docker-compose.host.docker.internal.yml b/docker-compose.host.docker.internal.yml index a9f604dbe..58756cc80 100644 --- a/docker-compose.host.docker.internal.yml +++ b/docker-compose.host.docker.internal.yml @@ -42,13 +42,6 @@ services: BLOCKCHAIN_WS_HOST: host.docker.internal AUTOSTART_RETRIES: 100 - adversary1: - extra_hosts: - - 'host.docker.internal:host-gateway' - environment: - BLOCKCHAIN_WS_HOST: host.docker.internal - AUTOSTART_RETRIES: 100 - administrator: extra_hosts: - 'host.docker.internal:host-gateway' diff --git a/docker-compose.wallet-test.yml b/docker-compose.wallet-test.yml deleted file mode 100644 index 9b35ee3d9..000000000 --- a/docker-compose.wallet-test.yml +++ /dev/null @@ -1,18 +0,0 @@ -version: '3.5' -services: - wallet-test: - build: - dockerfile: Dockerfile - context: ./wallet - networks: - - nightfall_network - user: apps - ports: - - 5900:5900 - - 3010:3010 - privileged: true - environment: - - VNC_SERVER_PASSWORD=password - - RUN_SELENIUM_TESTS=${RUN_SELENIUM_TESTS} - - ENABLE_VNC_SERVER=${ENABLE_VNC_SERVER} - diff --git a/nightfall-optimist/start-optimist.sh b/nightfall-optimist/start-optimist.sh index 3666cbd28..0610c2c27 100755 --- a/nightfall-optimist/start-optimist.sh +++ b/nightfall-optimist/start-optimist.sh @@ -27,8 +27,8 @@ while [ -n "$1" ]; do -d | --delete_db ) sudo rm -rf ${MONGODB} sudo mkdir -p ${MONGODB} ;; - -e | --environment ) DEPLOYMENT="$1"; - if [ "${DEPLOYMENT}" != "tesnet" ] && [ "${DEPLOYMENT}" != "mainnet" ]; then + -e | --environment ) DEPLOYMENT="$2"; + if [ "${DEPLOYMENT}" != "testnet" ] && [ "${DEPLOYMENT}" != "mainnet" ]; then echo "Incorrect Deployment ${DEPLOYMENT}" usage exit 0 @@ -44,6 +44,9 @@ while [ -n "$1" ]; do shift done +# Stop optimist and mongodb containers if they exist +./stop-optimist.sh + # If deploymeny if [ ! -z "${DEPLOYMENT}" ]; then @@ -74,6 +77,15 @@ if [ ! -z "${DEPLOYMENT}" ]; then cp hash.txt ${VOLUMES}/build/hash.txt fi OPTIMIST_VOLUME_STRING="-v ${VOLUMES}/build:/app/build " + + echo "Launching mongodb container..." + docker run -d \ + -v ${MONGODB}:/data/db \ + -p ${MONGO_PORT}:27017 \ + --name mongodb_1 \ + -e MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD} \ + -e MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME} \ + mongo else # If we use ./start-nightfall script, then assume we are using ganache. Retrieve IP to establish connection OPTIMIST_VOLUME_STRING="--mount source=nightfall_3_build,destination=/app/build" @@ -81,27 +93,29 @@ else BLOCKCHAIN_IP=$(docker network inspect nightfall_3_nightfall_network | jq ".[0].Containers.\"${BLOCKCHAIN_CONTAINER_ID}\"".IPv4Address | tr -d "\"") BLOCKCHAIN_IP=${BLOCKCHAIN_IP::-3} BLOCKCHAIN_URL=ws://${BLOCKCHAIN_IP}:8546 -fi -# Stop optimist and mongodb containers if they exist -./stop-optimist.sh + echo "Launching mongodb container..." + docker run -d \ + -v ${MONGODB}:/data/db \ + -p ${MONGO_PORT}:27017 \ + --name mongodb_1 \ + --network=nightfall_3_nightfall_network \ + -e MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD} \ + -e MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME} \ + mongo +fi -echo "Launching mongodb container..." -docker run -d \ - -v ${MONGODB}:/data/db \ - -p ${MONGO_PORT}:27017 \ - --name mongodb_1 \ - --network=nightfall_3_nightfall_network \ - -e MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD} \ - -e MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME} \ - mongo sleep 5 # retrieve mongodb container IP MONGO_CONTAINER_ID=$(docker ps --no-trunc | grep mongodb_1 | awk '{print $1}') -MONGO_IP=$(docker network inspect nightfall_3_nightfall_network | jq ".[0].Containers.\"${MONGO_CONTAINER_ID}\"".IPv4Address | tr -d "\"") -MONGO_IP=${MONGO_IP::-3} +if [ ! -z "${DEPLOYMENT}" ]; then + MONGO_IP=$(docker inspect ${MONGO_CONTAINER_ID} | jq ".[0].NetworkSettings.Networks.bridge.IPAddress" | tr -d "\"") +else + MONGO_IP=$(docker network inspect nightfall_3_nightfall_network | jq ".[0].Containers.\"${MONGO_CONTAINER_ID}\"".IPv4Address | tr -d "\"") + MONGO_IP=${MONGO_IP::-3} +fi cd .. && sudo docker build \ --build-arg OPTIMIST_PORT=${OPTIMIST_PORT} \ @@ -109,20 +123,37 @@ cd .. && sudo docker build \ -f optimist.standalone.Dockerfile . -t nightfall-optimist:latest -echo "Launching optimist..." -docker run --rm -d \ - --name optimist_1 \ - ${OPTIMIST_VOLUME_STRING} \ - --network=nightfall_3_nightfall_network \ - -p ${OPTIMIST_WS_PORT}:8080 \ - -p ${OPTIMIST_PORT}:80 \ - -e MONGO_CONNECTION_STRING="mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@${MONGO_IP}:27017/" \ - -e MONGO_URL=${MONGO_IP} \ - -e WEBSOCKET_PORT=8080 \ - -e BLOCKCHAIN_URL=${BLOCKCHAIN_URL} \ - -e HASH_TYPE=mimc \ - -e LOG_LEVEL=debug \ - -e TRANSACTIONS_PER_BLOCK=32 \ - -e AUTOSTART_RETRIES=10000 \ - nightfall-optimist:latest +if [ ! -z "${DEPLOYMENT}" ]; then + echo "Launching optimist..." + docker run --rm -d \ + --name optimist_1 \ + ${OPTIMIST_VOLUME_STRING} \ + -p ${OPTIMIST_WS_PORT}:8080 \ + -p ${OPTIMIST_PORT}:80 \ + -e MONGO_CONNECTION_STRING="mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@${MONGO_IP}:27017/" \ + -e MONGO_URL=${MONGO_IP} \ + -e WEBSOCKET_PORT=8080 \ + -e BLOCKCHAIN_URL=${BLOCKCHAIN_URL} \ + -e HASH_TYPE=mimc \ + -e LOG_LEVEL=debug \ + -e TRANSACTIONS_PER_BLOCK=32 \ + -e AUTOSTART_RETRIES=10000 \ + nightfall-optimist:latest +else + docker run --rm -d \ + --name optimist_1 \ + ${OPTIMIST_VOLUME_STRING} \ + --network=nightfall_3_nightfall_network \ + -p ${OPTIMIST_WS_PORT}:8080 \ + -p ${OPTIMIST_PORT}:80 \ + -e MONGO_CONNECTION_STRING="mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@${MONGO_IP}:27017/" \ + -e MONGO_URL=${MONGO_IP} \ + -e WEBSOCKET_PORT=8080 \ + -e BLOCKCHAIN_URL=${BLOCKCHAIN_URL} \ + -e HASH_TYPE=mimc \ + -e LOG_LEVEL=debug \ + -e TRANSACTIONS_PER_BLOCK=32 \ + -e AUTOSTART_RETRIES=10000 \ + nightfall-optimist:latest +fi diff --git a/package.json b/package.json index 909fcafce..7b96ba16c 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "prepare": "husky install", "doc:build:sdk": "jsdoc -c jsdoc.json cli/lib/nf3.mjs", "build-adversary": "node test/adversary/transpile-adversary.mjs", - "adversary-test": "mocha --timeout 0 --bail --exit test/adversary.test.mjs" + "adversary-test": "CHALLENGE_TYPE=${CHALLENGE_TYPE} mocha --timeout 0 --bail --exit test/adversary.test.mjs", + "adversary-test-all": "for CHALLENGE_TYPE in IncorrectTreeRoot IncorrectLeafCount DuplicateTransaction DuplicateNullifier HistoricRootError IncorrectProof; do CHALLENGE_TYPE=${CHALLENGE_TYPE} mocha --timeout 0 --bail --exit test/adversary.test.mjs; sleep 5; done" }, "repository": { "type": "git", diff --git a/start-nightfall b/start-nightfall index 8783559ff..28cb0a791 100755 --- a/start-nightfall +++ b/start-nightfall @@ -7,8 +7,6 @@ usage() { echo "Usage:" echo " -g or --ganache; for a ganache simulator" - echo " -wt or --wallet-testing; to launch wallet unit testing" - echo " -w or --wallet; to deploy wallet" echo " -l or --localhost; to connect to an already running blockchain on ws://localhost:8546" echo " -s or --stubs; runs with circuits stubbed out (faster but no checking of ZKP code) - use with either -g or -l" echo " -h or --help; to print this message" @@ -28,16 +26,6 @@ while [ -n "$1" ]; do case $1 in -g | --ganache ) FILE="-f docker-compose.yml -f docker-compose.ganache.yml"; ;; - -wt | --wallet-testing ) FILE="-f docker-compose.yml -f docker-compose.ganache.yml -f docker-compose.wallet-test.yml" - export ENABLE_VNC_SERVER=0 - export RUN_SELENIUM_TESTS=1 - cd wallet && ./pre-start-script.sh && cd - - ;; - -w | --wallet) FILE="-f docker-compose.yml -f docker-compose.ganache.yml -f docker-compose.wallet-test.yml" - export ENABLE_VNC_SERVER=1 - export RUN_SELENIUM_TESTS=0 - cd wallet && ./pre-start-script.sh && cd - - ;; -l | --localhost ) FILE="-f docker-compose.yml -f docker-compose.host.docker.internal.yml" ;; -r | --ropsten ) FILE="-f docker-compose.yml -f docker-compose.ropsten.yml" @@ -88,11 +76,6 @@ if [[ $(echo $VOLUME_LIST | grep nightfall_3_geth1-chain) ]]; then docker volume rm nightfall_3_geth1-chain fi -if [[ $(echo $VOLUME_LIST | grep nightfall_3_geth2-chain) ]]; then - echo -n 'Removing ' - docker volume rm nightfall_3_geth2-chain -fi - if [[ $(echo $VOLUME_LIST | grep nightfall_3_geth-miner-chain1) ]]; then echo -n 'Removing ' docker volume rm nightfall_3_geth-miner-chain1 @@ -103,16 +86,6 @@ if [[ $(echo $VOLUME_LIST | grep nightfall_3_dag1) ]]; then docker volume rm nightfall_3_dag1 fi -if [[ $(echo $VOLUME_LIST | grep nightfall_3_geth-miner-chain2) ]]; then - echo -n 'Removing ' - docker volume rm nightfall_3_geth-miner-chain2 -fi - -if [[ $(echo $VOLUME_LIST | grep nightfall_3_dag2) ]]; then - echo -n 'Removing ' - docker volume rm nightfall_3_dag2 -fi - DIR=./common-files/node_modules if [[ -d "$DIR" ]]; then rm -dr common-files/node_modules diff --git a/test/adversary.test.mjs b/test/adversary.test.mjs index 8adc8bc01..1cff1cdc0 100644 --- a/test/adversary.test.mjs +++ b/test/adversary.test.mjs @@ -76,7 +76,11 @@ describe('Testing with an adversary', () => { optimistWsUrl: adversarialOptimistWsUrl, }); - nf3Challenger = new Nf3(ethereumSigningKeyChallenger, environment); + nf3Challenger = new Nf3(ethereumSigningKeyChallenger, { + ...others, + optimistApiUrl: adversarialOptimistApiUrl, + optimistWsUrl: adversarialOptimistWsUrl, + }); // Generate a random mnemonic (uses crypto.randomBytes under the hood), defaults to 128-bits of entropy await nf3User.init(mnemonicUser); @@ -112,20 +116,41 @@ describe('Testing with an adversary', () => { await nf3Challenger.registerChallenger(); // Chalenger listening for incoming events nf3Challenger.startChallenger(); + const challengerEmitter = await nf3Challenger.getChallengeEmitter(); + challengerEmitter.on('data', txDataToSign => { + logger.debug(`Challenger emitter with data ${txDataToSign}`); + }); + + // Configure adversary bad block sequence + if (process.env.CHALLENGE_TYPE !== '') { + logger.debug(`Configuring Challenge Type ${process.env.CHALLENGE_TYPE}`); + await chai + .request(adversarialOptimistApiUrl) + .post('/block/gen-block') + .send({ blockType: ['ValidBlock', 'ValidBlock', process.env.CHALLENGE_TYPE] }); + } else { + logger.debug(`Configuring Default Challenge Type`); + } + }); - describe('User creates deposit and transfer transctions', () => { + describe('User creates deposit and transfer transactions', () => { it('User should have the correct balance after a series of rollbacks', async () => { // Because rollbacks removes the only registered proposer, // the proposer is registered again after each remova intervalId = setInterval(() => { registerProposerOnNoProposer(nf3AdversarialProposer); }, 5000); + let nDeposits=0; + let nTransfers=0; // we are creating a block of deposits with high values such that there is // enough balance for a lot of transfers with low value. + console.log('Starting balance :', startBalance); + expectedBalance = startBalance; for (let j = 0; j < TRANSACTIONS_PER_BLOCK; j++) { await nf3User.deposit(ercAddress, tokenType, value2, tokenId, fee); + nDeposits++; expectedBalance += value2; } @@ -140,6 +165,7 @@ describe('Testing with an adversary', () => { tokenId, nf3User.zkpKeys.compressedPkd, ); + nTransfers++; // expectedBalance += value2; } catch (err) { if (err.message.includes('No suitable commitments')) { @@ -159,23 +185,29 @@ describe('Testing with an adversary', () => { tokenId, nf3User.zkpKeys.compressedPkd, ); + nTransfers++; // expectedBalance += value2; // transfer to self, so balance does not increase } } for (let k = 0; k < TRANSACTIONS_PER_BLOCK - 1; k++) { await nf3User.deposit(ercAddress, tokenType, value2, tokenId); + nDeposits++; expectedBalance += value2; } await new Promise(resolve => setTimeout(resolve, TX_WAIT)); // this may need to be longer on a real blockchain console.log(`Completed ${i + 1} pings`); } + // TODO:_ how can i check that queue 2 is empty + await waitForSufficientBalance(nf3User, expectedBalance); // waiting sometime to ensure that all the good transactions from bad // blocks were proposed in other good blocks await new Promise(resolve => setTimeout(resolve, 20 * TX_WAIT)); + await waitForSufficientBalance(nf3User, expectedBalance); const endBalance = await retrieveL2Balance(nf3User); console.log(`Completed startBalance`, startBalance); console.log(`Completed endBalance`, endBalance); + logger.debug(`N deposits: ${nDeposits} - N Transfers: ${nTransfers}`); expect(expectedBalance).to.be.equal(endBalance - startBalance); }); }); diff --git a/test/adversary/adversary-code/block.mjs b/test/adversary/adversary-code/block.mjs index 73ed73fc7..4c2c9c9f1 100644 --- a/test/adversary/adversary-code/block.mjs +++ b/test/adversary/adversary-code/block.mjs @@ -1,23 +1,28 @@ /* ignore unused exports */ import logger from 'common-files/utils/logger.mjs'; -const error = [ - 'ValidBlock', - 'ValidBlock', - 'ValidBlock', - 'IncorrectTreeRoot', // Needs two prior blocks - 'ValidBlock', - 'IncorrectLeafCount', // Needs one prior block - 'ValidBlock', - 'DuplicateTransaction', // needs atleast one transaction in a prior block - 'ValidBlock', - 'DuplicateNullifier', // needs atleast one non deposit transaction in a prior block - 'ValidBlock', - 'HistoricRootError', - 'ValidBlock', - 'IncorrectProof', - 'ValidBlock', -]; +let error = process.env.BAD_BLOCK_SEQUENCE + ? process.env.BAD_BLOCK_SEQUENCE.split(',') + : [ + 'ValidBlock', + 'ValidBlock', + 'ValidBlock', + 'IncorrectTreeRoot', // Needs two prior blocks + 'ValidBlock', + 'IncorrectLeafCount', // Needs one prior block + 'ValidBlock', + 'DuplicateTransaction', // needs atleast one transaction in a prior block + 'ValidBlock', + 'DuplicateNullifier', // needs atleast one non deposit transaction in a prior block + 'ValidBlock', + 'HistoricRootError', + 'ValidBlock', + 'IncorrectProof', + 'ValidBlock', + ]; + +let resetErrorIdx = false; +let indexOffset = 0; // eslint-disable-next-line no-unused-vars const incorrectTransactionHashesRoot = block => { @@ -44,15 +49,27 @@ const incorrectLeafCount = block => { }; }; +export const addBlock = blockType => { + error = blockType; + resetErrorIdx = true; + logger.debug(`Received new block types to generate ${error}`); +}; + // eslint-disable-next-line import/prefer-default-export export const createBadBlock = (block, errorIndex) => { - logger.debug('Creating a block of type', error[errorIndex]); - switch (error[errorIndex]) { + if (resetErrorIdx) { + resetErrorIdx = false; + indexOffset = errorIndex; + } + const badBlockType = error[errorIndex - indexOffset]; + logger.debug(`Creating a block of type ${badBlockType}`); + switch (badBlockType) { case 'IncorrectTreeRoot': return incorrectTreeRoot(block); case 'IncorrectLeafCount': return incorrectLeafCount(block); default: + logger.debug(`Creating a block of type ValidBlock`); return block; } }; diff --git a/test/adversary/adversary-code/database.mjs b/test/adversary/adversary-code/database.mjs index ca9f6a2e7..9b6f43472 100644 --- a/test/adversary/adversary-code/database.mjs +++ b/test/adversary/adversary-code/database.mjs @@ -5,23 +5,28 @@ import mongo from 'common-files/utils/mongo.mjs'; const { MONGO_URL, OPTIMIST_DB, TRANSACTIONS_COLLECTION } = config; -const error = [ - 'ValidTransaction', - 'ValidTransaction', - 'ValidTransaction', - 'IncorrectTreeRoot', - 'ValidTransaction', - 'IncorrectLeafCount', - 'ValidTransaction', - 'DuplicateTransaction', - 'ValidTransaction', - 'DuplicateNullifier', - 'ValidTransaction', - 'HistoricRootError', - 'ValidTransaction', - 'IncorrectProof', - 'ValidTransaction', -]; +let error = process.env.BAD_TX_SEQUENCE + ? process.env.BAD_TX_SEQUENCE.split(',') + : [ + 'ValidTransaction', + 'ValidTransaction', + 'ValidTransaction', + 'IncorrectTreeRoot', + 'ValidTransaction', + 'IncorrectLeafCount', + 'ValidTransaction', + 'DuplicateTransaction', + 'ValidTransaction', + 'DuplicateNullifier', + 'ValidTransaction', + 'HistoricRootError', + 'ValidTransaction', + 'IncorrectProof', + 'ValidTransaction', + ]; + +let resetErrorIdx = false; +let indexOffset = 0; const duplicateNullifier = async number => { logger.debug('Creating Block with Duplicate Nullifier'); @@ -136,14 +141,25 @@ const historicRootError = async number => { return transactions; }; +export const addTx = txType => { + error = txType; + resetErrorIdx = true; + logger.debug(`Received new Tx types to generate ${error}`); +}; + /** Function to return 'number' transactions, ordered by the highest fee. If there are fewer than 'number' transactions, all are returned. */ // eslint-disable-next-line import/prefer-default-export export async function getMostProfitableTransactions(number, errorIndex) { - logger.debug('Creating a transaction of type', error[errorIndex]); - switch (error[errorIndex]) { + if (resetErrorIdx) { + resetErrorIdx = false; + indexOffset = errorIndex; + } + const badTxType = error[errorIndex - indexOffset]; + logger.debug(`Creating a transaction of type ${badTxType}`); + switch (badTxType) { case 'DuplicateTransaction': return duplicateTransaction(number); case 'DuplicateNullifier': @@ -153,6 +169,7 @@ export async function getMostProfitableTransactions(number, errorIndex) { case 'HistoricRootError': return historicRootError(number); default: { + logger.debug(`Creating a transaction of type ValidBlock`); const connection = await mongo.connection(MONGO_URL); const db = connection.db(OPTIMIST_DB); return db diff --git a/test/adversary/adversary-code/route-block.mjs b/test/adversary/adversary-code/route-block.mjs new file mode 100644 index 000000000..a3b0ae809 --- /dev/null +++ b/test/adversary/adversary-code/route-block.mjs @@ -0,0 +1,25 @@ + +router.get('/reset-localblock', async (req, res, next) => { + logger.debug('block endpoint received get'); + try { + await Block.rollback(); + res.json({ resetstatus: true }); + } catch (err) { + next(err); + } + }); + + +router.post('/gen-block', async (req, res, next) => { + logger.debug('gen-block endpoint received POST'); + try { + const { blockType } = req.body; + await addBlock(blockType); + await addTx(blockType); + res.json({ status: 'OK' }); + } catch (err) { + next(err); + } + }); + +export default router; \ No newline at end of file diff --git a/test/adversary/transpile-adversary.mjs b/test/adversary/transpile-adversary.mjs index cc2584372..1a8d48d9c 100644 --- a/test/adversary/transpile-adversary.mjs +++ b/test/adversary/transpile-adversary.mjs @@ -49,8 +49,8 @@ const transpileBlockBuilder = (_pathToSrc, _pathToInject) => { const [srcPre] = srcFile.match(srcImportPreamble); const [srcPost] = srcFile.match(srcimportPostamble); - const targetImportPreamble = /import(\n|.)*(?=\nconst error)/g; - const targetImportPostamble = /const error(\n|.)*/g; + const targetImportPreamble = /import(\n|.)*(?=\nlet error)/g; + const targetImportPostamble = /let error(\n|.)*/g; const [tgtPre] = injectFile.match(targetImportPreamble); const [tgtPost] = injectFile.match(targetImportPostamble); @@ -111,7 +111,7 @@ const transpileTransactionLookup = (_pathToSrc, _pathToInject) => { let srcFile = fs.readFileSync(_pathToSrc, 'utf-8'); const injectFile = fs.readFileSync(_pathToInject, 'utf-8'); - const regexInjectFileNoPreamble = /const error(\n|.)*/g; + const regexInjectFileNoPreamble = /let error(\n|.)*/g; const [postAmble] = injectFile.match(regexInjectFileNoPreamble); const regexReplaceCall = @@ -124,6 +124,25 @@ const transpileTransactionLookup = (_pathToSrc, _pathToInject) => { fs.writeFileSync(_pathToSrc, srcFile); }; +// Transpile Block API code +const transpileBlockApi = (_pathToSrc, _pathToInject) => { + let srcFile = fs.readFileSync(_pathToSrc, 'utf-8'); + const injectFile = fs.readFileSync(_pathToInject, 'utf-8'); + + const srcImportPreamble = /(\n|.)*\*\/\n(?=import)/g; + const [srcPre] = srcFile.match(srcImportPreamble); + + srcFile = `/* THIS FILE CONTAINS CODE THAT HAS BEEN AUTOGENERATED DO NOT MODIFY MANUALLY */\n${srcPre} import { addBlock } from '../classes/block.mjs';\nimport { addTx } from '../services/database.mjs';\n ${srcFile}`; + + const regexInjectFileNoPreamble = /(.*reset-localblock.*)(\n|.)*/g; + const [postAmble] = injectFile.match(regexInjectFileNoPreamble); + + const regexReplaceCall = /(.*reset-localblock.*)(\n|.)*/g; + + srcFile = `\n${srcFile.replace(regexReplaceCall, postAmble)}`; + fs.writeFileSync(_pathToSrc, srcFile); +}; + copyDir('./nightfall-optimist/', './test/adversary/nightfall-adversary/').then(() => { console.log('done copy'); transpileBlockAssembler( @@ -138,5 +157,9 @@ copyDir('./nightfall-optimist/', './test/adversary/nightfall-adversary/').then(( './test/adversary/nightfall-adversary/src/services/database.mjs', './test/adversary/adversary-code/database.mjs', ); + transpileBlockApi( + './test/adversary/nightfall-adversary/src/routes/block.mjs', + './test/adversary/adversary-code/route-block.mjs', + ); console.log(`transpile assembler done'`); }); diff --git a/test/neg-http.mjs b/test/neg-http.mjs index a99904e9d..de74c5fc9 100644 --- a/test/neg-http.mjs +++ b/test/neg-http.mjs @@ -114,7 +114,7 @@ describe('Testing the challenge http API', () => { stateAddress = res.body.address; // should get the address of the test ERC contract stub - res = await chai.request(url).get('/contract-address/ERCStub'); + res = await chai.request(url).get('/contract-address/ERC20Mock'); ercAddress = res.body.address; // set the current nonce before we start the test web3Client.setNonce( @@ -314,18 +314,28 @@ describe('Testing the challenge http API', () => { ).map(res => res.body); depositTransactions.forEach(({ txDataToSign }) => expect(txDataToSign).to.be.a('string')); + console.log("1") const receiptArrays = []; txQueue.push(async () => { await holdupTxQueue('txSubmitted', logs.txSubmitted.length + depositTransactions.length); }); + console.log("2") for (let i = 0; i < depositTransactions.length; i++) { const { txDataToSign } = depositTransactions[i]; const count = logs.txSubmitted.length; + console.log("3") + //const a = await web3Client.submitTransaction(txDataToSign, privateKey, shieldAddress, gas, fee); + //console.log(a); + try { receiptArrays.push( await web3Client.submitTransaction(txDataToSign, privateKey, shieldAddress, gas, fee), ); + } catch (err) { + console.log("ERROR", err) + } + console.log("XXX") await waitForTxExecution(count, 'txSubmitted'); } receiptArrays.forEach(receipt => { From ad775d498a0335f9218329f9b6e048ba01ecd493 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 30 Jun 2022 20:22:02 +0200 Subject: [PATCH 2/7] fix: eslint --- test/adversary.test.mjs | 5 +-- test/adversary/adversary-code/route-block.mjs | 41 +++++++++---------- test/neg-http.mjs | 10 ----- 3 files changed, 22 insertions(+), 34 deletions(-) diff --git a/test/adversary.test.mjs b/test/adversary.test.mjs index 1cff1cdc0..07fbe6a27 100644 --- a/test/adversary.test.mjs +++ b/test/adversary.test.mjs @@ -131,7 +131,6 @@ describe('Testing with an adversary', () => { } else { logger.debug(`Configuring Default Challenge Type`); } - }); describe('User creates deposit and transfer transactions', () => { @@ -141,8 +140,8 @@ describe('Testing with an adversary', () => { intervalId = setInterval(() => { registerProposerOnNoProposer(nf3AdversarialProposer); }, 5000); - let nDeposits=0; - let nTransfers=0; + let nDeposits = 0; + let nTransfers = 0; // we are creating a block of deposits with high values such that there is // enough balance for a lot of transfers with low value. diff --git a/test/adversary/adversary-code/route-block.mjs b/test/adversary/adversary-code/route-block.mjs index a3b0ae809..da9157f42 100644 --- a/test/adversary/adversary-code/route-block.mjs +++ b/test/adversary/adversary-code/route-block.mjs @@ -1,25 +1,24 @@ - +/* eslint-disable no-undef */ router.get('/reset-localblock', async (req, res, next) => { - logger.debug('block endpoint received get'); - try { - await Block.rollback(); - res.json({ resetstatus: true }); - } catch (err) { - next(err); - } - }); - + logger.debug('block endpoint received get'); + try { + await Block.rollback(); + res.json({ resetstatus: true }); + } catch (err) { + next(err); + } +}); router.post('/gen-block', async (req, res, next) => { - logger.debug('gen-block endpoint received POST'); - try { - const { blockType } = req.body; - await addBlock(blockType); - await addTx(blockType); - res.json({ status: 'OK' }); - } catch (err) { - next(err); - } - }); + logger.debug('gen-block endpoint received POST'); + try { + const { blockType } = req.body; + await addBlock(blockType); + await addTx(blockType); + res.json({ status: 'OK' }); + } catch (err) { + next(err); + } +}); -export default router; \ No newline at end of file +export default router; diff --git a/test/neg-http.mjs b/test/neg-http.mjs index de74c5fc9..1acce1a6f 100644 --- a/test/neg-http.mjs +++ b/test/neg-http.mjs @@ -314,28 +314,18 @@ describe('Testing the challenge http API', () => { ).map(res => res.body); depositTransactions.forEach(({ txDataToSign }) => expect(txDataToSign).to.be.a('string')); - console.log("1") const receiptArrays = []; txQueue.push(async () => { await holdupTxQueue('txSubmitted', logs.txSubmitted.length + depositTransactions.length); }); - console.log("2") for (let i = 0; i < depositTransactions.length; i++) { const { txDataToSign } = depositTransactions[i]; const count = logs.txSubmitted.length; - console.log("3") - //const a = await web3Client.submitTransaction(txDataToSign, privateKey, shieldAddress, gas, fee); - //console.log(a); - try { receiptArrays.push( await web3Client.submitTransaction(txDataToSign, privateKey, shieldAddress, gas, fee), ); - } catch (err) { - console.log("ERROR", err) - } - console.log("XXX") await waitForTxExecution(count, 'txSubmitted'); } receiptArrays.forEach(receipt => { From dcbd9e5b43a62895d568950062e4043bc7313473 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 30 Jun 2022 20:23:48 +0200 Subject: [PATCH 3/7] fix: eslint --- test/adversary/adversary-code/route-block.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/test/adversary/adversary-code/route-block.mjs b/test/adversary/adversary-code/route-block.mjs index da9157f42..695f82583 100644 --- a/test/adversary/adversary-code/route-block.mjs +++ b/test/adversary/adversary-code/route-block.mjs @@ -1,4 +1,5 @@ /* eslint-disable no-undef */ +/* ignore unused exports */ router.get('/reset-localblock', async (req, res, next) => { logger.debug('block endpoint received get'); try { From c98a93374cf1acc7846e33c748b0648b4a75ef37 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 30 Jun 2022 21:01:16 +0200 Subject: [PATCH 4/7] fix: only adversary is challenger --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 01734eec8..2653ba462 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -139,7 +139,7 @@ services: BLOCKCHAIN_PORT: 8546 HASH_TYPE: mimc LOG_LEVEL: debug - IS_CHALLENGER: 'true' + IS_CHALLENGER: 'false' TRANSACTIONS_PER_BLOCK: ${TRANSACTIONS_PER_BLOCK:-2} command: [ 'npm', 'run', 'dev' ] @@ -163,7 +163,7 @@ services: BLOCKCHAIN_PORT: 8546 HASH_TYPE: mimc LOG_LEVEL: error - IS_CHALLENGER: 'true' + IS_CHALLENGER: 'false' TRANSACTIONS_PER_BLOCK: ${TRANSACTIONS_PER_BLOCK:-2} command: [ 'npm', 'run', 'dev' ] From 38b9cabe88667c0bb857779b790c1d89ef5ec9e3 Mon Sep 17 00:00:00 2001 From: druiz0992 <46495002+druiz0992@users.noreply.github.com> Date: Fri, 1 Jul 2022 16:13:23 +0200 Subject: [PATCH 5/7] Update adversary.test.mjs --- test/adversary.test.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/adversary.test.mjs b/test/adversary.test.mjs index 763dc19bd..2a1ae4345 100644 --- a/test/adversary.test.mjs +++ b/test/adversary.test.mjs @@ -138,7 +138,7 @@ describe('Testing with an adversary', () => { } else { logger.debug(`Configuring Default Challenge Type`); } - + console.log('Pausing challenger queue...'); // we pause the challenger queue and don't process challenger until unpauseQueueChallenger nf3Challenger.pauseQueueChallenger(); From a1fe407f4908b004af7602d08a3a8e1a2e9f33fe Mon Sep 17 00:00:00 2001 From: David Date: Fri, 1 Jul 2022 18:15:25 +0200 Subject: [PATCH 6/7] fix: remove unnecesary changes for pr --- docker-compose.wallet-test.yml | 18 ++++++ nightfall-optimist/start-optimist.sh | 95 ++++++++++------------------ start-nightfall | 27 ++++++++ 3 files changed, 77 insertions(+), 63 deletions(-) create mode 100644 docker-compose.wallet-test.yml diff --git a/docker-compose.wallet-test.yml b/docker-compose.wallet-test.yml new file mode 100644 index 000000000..9b35ee3d9 --- /dev/null +++ b/docker-compose.wallet-test.yml @@ -0,0 +1,18 @@ +version: '3.5' +services: + wallet-test: + build: + dockerfile: Dockerfile + context: ./wallet + networks: + - nightfall_network + user: apps + ports: + - 5900:5900 + - 3010:3010 + privileged: true + environment: + - VNC_SERVER_PASSWORD=password + - RUN_SELENIUM_TESTS=${RUN_SELENIUM_TESTS} + - ENABLE_VNC_SERVER=${ENABLE_VNC_SERVER} + diff --git a/nightfall-optimist/start-optimist.sh b/nightfall-optimist/start-optimist.sh index 0610c2c27..3666cbd28 100755 --- a/nightfall-optimist/start-optimist.sh +++ b/nightfall-optimist/start-optimist.sh @@ -27,8 +27,8 @@ while [ -n "$1" ]; do -d | --delete_db ) sudo rm -rf ${MONGODB} sudo mkdir -p ${MONGODB} ;; - -e | --environment ) DEPLOYMENT="$2"; - if [ "${DEPLOYMENT}" != "testnet" ] && [ "${DEPLOYMENT}" != "mainnet" ]; then + -e | --environment ) DEPLOYMENT="$1"; + if [ "${DEPLOYMENT}" != "tesnet" ] && [ "${DEPLOYMENT}" != "mainnet" ]; then echo "Incorrect Deployment ${DEPLOYMENT}" usage exit 0 @@ -44,9 +44,6 @@ while [ -n "$1" ]; do shift done -# Stop optimist and mongodb containers if they exist -./stop-optimist.sh - # If deploymeny if [ ! -z "${DEPLOYMENT}" ]; then @@ -77,15 +74,6 @@ if [ ! -z "${DEPLOYMENT}" ]; then cp hash.txt ${VOLUMES}/build/hash.txt fi OPTIMIST_VOLUME_STRING="-v ${VOLUMES}/build:/app/build " - - echo "Launching mongodb container..." - docker run -d \ - -v ${MONGODB}:/data/db \ - -p ${MONGO_PORT}:27017 \ - --name mongodb_1 \ - -e MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD} \ - -e MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME} \ - mongo else # If we use ./start-nightfall script, then assume we are using ganache. Retrieve IP to establish connection OPTIMIST_VOLUME_STRING="--mount source=nightfall_3_build,destination=/app/build" @@ -93,29 +81,27 @@ else BLOCKCHAIN_IP=$(docker network inspect nightfall_3_nightfall_network | jq ".[0].Containers.\"${BLOCKCHAIN_CONTAINER_ID}\"".IPv4Address | tr -d "\"") BLOCKCHAIN_IP=${BLOCKCHAIN_IP::-3} BLOCKCHAIN_URL=ws://${BLOCKCHAIN_IP}:8546 - - echo "Launching mongodb container..." - docker run -d \ - -v ${MONGODB}:/data/db \ - -p ${MONGO_PORT}:27017 \ - --name mongodb_1 \ - --network=nightfall_3_nightfall_network \ - -e MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD} \ - -e MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME} \ - mongo fi +# Stop optimist and mongodb containers if they exist +./stop-optimist.sh + +echo "Launching mongodb container..." +docker run -d \ + -v ${MONGODB}:/data/db \ + -p ${MONGO_PORT}:27017 \ + --name mongodb_1 \ + --network=nightfall_3_nightfall_network \ + -e MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD} \ + -e MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME} \ + mongo sleep 5 # retrieve mongodb container IP MONGO_CONTAINER_ID=$(docker ps --no-trunc | grep mongodb_1 | awk '{print $1}') -if [ ! -z "${DEPLOYMENT}" ]; then - MONGO_IP=$(docker inspect ${MONGO_CONTAINER_ID} | jq ".[0].NetworkSettings.Networks.bridge.IPAddress" | tr -d "\"") -else - MONGO_IP=$(docker network inspect nightfall_3_nightfall_network | jq ".[0].Containers.\"${MONGO_CONTAINER_ID}\"".IPv4Address | tr -d "\"") - MONGO_IP=${MONGO_IP::-3} -fi +MONGO_IP=$(docker network inspect nightfall_3_nightfall_network | jq ".[0].Containers.\"${MONGO_CONTAINER_ID}\"".IPv4Address | tr -d "\"") +MONGO_IP=${MONGO_IP::-3} cd .. && sudo docker build \ --build-arg OPTIMIST_PORT=${OPTIMIST_PORT} \ @@ -123,37 +109,20 @@ cd .. && sudo docker build \ -f optimist.standalone.Dockerfile . -t nightfall-optimist:latest -if [ ! -z "${DEPLOYMENT}" ]; then - echo "Launching optimist..." - docker run --rm -d \ - --name optimist_1 \ - ${OPTIMIST_VOLUME_STRING} \ - -p ${OPTIMIST_WS_PORT}:8080 \ - -p ${OPTIMIST_PORT}:80 \ - -e MONGO_CONNECTION_STRING="mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@${MONGO_IP}:27017/" \ - -e MONGO_URL=${MONGO_IP} \ - -e WEBSOCKET_PORT=8080 \ - -e BLOCKCHAIN_URL=${BLOCKCHAIN_URL} \ - -e HASH_TYPE=mimc \ - -e LOG_LEVEL=debug \ - -e TRANSACTIONS_PER_BLOCK=32 \ - -e AUTOSTART_RETRIES=10000 \ - nightfall-optimist:latest -else - docker run --rm -d \ - --name optimist_1 \ - ${OPTIMIST_VOLUME_STRING} \ - --network=nightfall_3_nightfall_network \ - -p ${OPTIMIST_WS_PORT}:8080 \ - -p ${OPTIMIST_PORT}:80 \ - -e MONGO_CONNECTION_STRING="mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@${MONGO_IP}:27017/" \ - -e MONGO_URL=${MONGO_IP} \ - -e WEBSOCKET_PORT=8080 \ - -e BLOCKCHAIN_URL=${BLOCKCHAIN_URL} \ - -e HASH_TYPE=mimc \ - -e LOG_LEVEL=debug \ - -e TRANSACTIONS_PER_BLOCK=32 \ - -e AUTOSTART_RETRIES=10000 \ - nightfall-optimist:latest -fi +echo "Launching optimist..." +docker run --rm -d \ + --name optimist_1 \ + ${OPTIMIST_VOLUME_STRING} \ + --network=nightfall_3_nightfall_network \ + -p ${OPTIMIST_WS_PORT}:8080 \ + -p ${OPTIMIST_PORT}:80 \ + -e MONGO_CONNECTION_STRING="mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@${MONGO_IP}:27017/" \ + -e MONGO_URL=${MONGO_IP} \ + -e WEBSOCKET_PORT=8080 \ + -e BLOCKCHAIN_URL=${BLOCKCHAIN_URL} \ + -e HASH_TYPE=mimc \ + -e LOG_LEVEL=debug \ + -e TRANSACTIONS_PER_BLOCK=32 \ + -e AUTOSTART_RETRIES=10000 \ + nightfall-optimist:latest diff --git a/start-nightfall b/start-nightfall index 28cb0a791..8783559ff 100755 --- a/start-nightfall +++ b/start-nightfall @@ -7,6 +7,8 @@ usage() { echo "Usage:" echo " -g or --ganache; for a ganache simulator" + echo " -wt or --wallet-testing; to launch wallet unit testing" + echo " -w or --wallet; to deploy wallet" echo " -l or --localhost; to connect to an already running blockchain on ws://localhost:8546" echo " -s or --stubs; runs with circuits stubbed out (faster but no checking of ZKP code) - use with either -g or -l" echo " -h or --help; to print this message" @@ -26,6 +28,16 @@ while [ -n "$1" ]; do case $1 in -g | --ganache ) FILE="-f docker-compose.yml -f docker-compose.ganache.yml"; ;; + -wt | --wallet-testing ) FILE="-f docker-compose.yml -f docker-compose.ganache.yml -f docker-compose.wallet-test.yml" + export ENABLE_VNC_SERVER=0 + export RUN_SELENIUM_TESTS=1 + cd wallet && ./pre-start-script.sh && cd - + ;; + -w | --wallet) FILE="-f docker-compose.yml -f docker-compose.ganache.yml -f docker-compose.wallet-test.yml" + export ENABLE_VNC_SERVER=1 + export RUN_SELENIUM_TESTS=0 + cd wallet && ./pre-start-script.sh && cd - + ;; -l | --localhost ) FILE="-f docker-compose.yml -f docker-compose.host.docker.internal.yml" ;; -r | --ropsten ) FILE="-f docker-compose.yml -f docker-compose.ropsten.yml" @@ -76,6 +88,11 @@ if [[ $(echo $VOLUME_LIST | grep nightfall_3_geth1-chain) ]]; then docker volume rm nightfall_3_geth1-chain fi +if [[ $(echo $VOLUME_LIST | grep nightfall_3_geth2-chain) ]]; then + echo -n 'Removing ' + docker volume rm nightfall_3_geth2-chain +fi + if [[ $(echo $VOLUME_LIST | grep nightfall_3_geth-miner-chain1) ]]; then echo -n 'Removing ' docker volume rm nightfall_3_geth-miner-chain1 @@ -86,6 +103,16 @@ if [[ $(echo $VOLUME_LIST | grep nightfall_3_dag1) ]]; then docker volume rm nightfall_3_dag1 fi +if [[ $(echo $VOLUME_LIST | grep nightfall_3_geth-miner-chain2) ]]; then + echo -n 'Removing ' + docker volume rm nightfall_3_geth-miner-chain2 +fi + +if [[ $(echo $VOLUME_LIST | grep nightfall_3_dag2) ]]; then + echo -n 'Removing ' + docker volume rm nightfall_3_dag2 +fi + DIR=./common-files/node_modules if [[ -d "$DIR" ]]; then rm -dr common-files/node_modules From 0957e1d6eda71b0b7fee2968f64084388775c61e Mon Sep 17 00:00:00 2001 From: David Date: Tue, 5 Jul 2022 10:18:07 +0200 Subject: [PATCH 7/7] fix: eslint --- test/adversary.test.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/test/adversary.test.mjs b/test/adversary.test.mjs index f0fcf1898..f6f6d6cf0 100644 --- a/test/adversary.test.mjs +++ b/test/adversary.test.mjs @@ -14,6 +14,7 @@ import { waitForSufficientBalance, registerProposerOnNoProposer, retrieveL2Balance, + // eslint-disable-next-line no-unused-vars waitForNoPendingCommitments, } from './utils.mjs'; import logger from '../common-files/utils/logger.mjs';