From 278462b0b36ec29b3ab2153008d56258c44a0d5f Mon Sep 17 00:00:00 2001 From: JhChoy Date: Tue, 8 Jan 2019 17:15:59 +0900 Subject: [PATCH] feat: add choice to add registry #33 --- .../vvisp/scripts/deploy-service/index.js | 11 +-- .../preProcess/compareConfigAndState.js | 3 +- .../deploy-service/preProcess/compileAll.js | 4 +- .../deploy-service/preProcess/index.js | 27 ++++++ .../processes/deployBusinesses.js | 4 + .../processes/deployNonUpgradeables.js | 93 ++++++++++--------- .../deploy-service/processes/deployProxies.js | 4 + .../processes/deployRegistry.js | 9 +- .../deploy-service/processes/reflectState.js | 1 + .../processes/registerFileNames.js | 4 + .../deploy-service/processes/upgradeAll.js | 4 + .../vvisp/test/dummy/noRegistry.service1.json | 38 ++++++++ .../vvisp/test/dummy/noRegistry.service2.json | 69 ++++++++++++++ .../vvisp/test/dummy/noRegistry.state1.json | 22 +++++ .../test/scripts/deploy-service/index.test.js | 42 ++++++++- 15 files changed, 280 insertions(+), 55 deletions(-) create mode 100644 packages/vvisp/test/dummy/noRegistry.service1.json create mode 100644 packages/vvisp/test/dummy/noRegistry.service2.json create mode 100644 packages/vvisp/test/dummy/noRegistry.state1.json diff --git a/packages/vvisp/scripts/deploy-service/index.js b/packages/vvisp/scripts/deploy-service/index.js index 20d78cb..f2009b7 100644 --- a/packages/vvisp/scripts/deploy-service/index.js +++ b/packages/vvisp/scripts/deploy-service/index.js @@ -3,7 +3,7 @@ module.exports = async function(options) { checkEnvExist(); checkConfigExist(); - const { printOrSilent } = require('@haechi-labs/vvisp-utils'); + const { printOrSilent, getWeb3 } = require('@haechi-labs/vvisp-utils'); const { writeState } = require('./utils'); const DeployState = require('./DeployState'); const preProcess = require('./preProcess'); @@ -26,8 +26,10 @@ module.exports = async function(options) { head: chk.bold, error: chk.red.bold, keyWord: chk.blue.bold, - notImportant: chk.gray + notImportant: chk.gray, + warning: chk.yellow }; + global.web3 = getWeb3(); await main(); @@ -40,10 +42,7 @@ module.exports = async function(options) { { name: 'deployRegistry', process: async function() { - const stateClone = deployState.getState(); - if (stateClone.notUpgrading) { - await deployRegistry(deployState, options); - } + await deployRegistry(deployState, options); } }, { diff --git a/packages/vvisp/scripts/deploy-service/preProcess/compareConfigAndState.js b/packages/vvisp/scripts/deploy-service/preProcess/compareConfigAndState.js index d177e48..c883fb3 100644 --- a/packages/vvisp/scripts/deploy-service/preProcess/compareConfigAndState.js +++ b/packages/vvisp/scripts/deploy-service/preProcess/compareConfigAndState.js @@ -65,11 +65,12 @@ module.exports = function(configContracts, stateClone) { // Check if there is no upgradeable contract. // If so, we don't have to compile proxy contract. let noProxy = true; - forIn(targets.contracts, contract => { + forIn(targets, contract => { if (contract.upgradeable === true) { noProxy = false; } }); + stateClone.noProxy = noProxy; return { targets: targets, diff --git a/packages/vvisp/scripts/deploy-service/preProcess/compileAll.js b/packages/vvisp/scripts/deploy-service/preProcess/compileAll.js index 3216e30..fcbc65e 100644 --- a/packages/vvisp/scripts/deploy-service/preProcess/compileAll.js +++ b/packages/vvisp/scripts/deploy-service/preProcess/compileAll.js @@ -7,7 +7,9 @@ module.exports = async function(compileInformation, options) { if (compileInformation.noProxy !== true) { compileFiles.push(PROXY_PATH); } - compileFiles.push(REGISTRY_PATH); + if (compileInformation.noRegistry !== true) { + compileFiles.push(REGISTRY_PATH); + } forIn(compileInformation.targets, contract => { if (contract.path) { diff --git a/packages/vvisp/scripts/deploy-service/preProcess/index.js b/packages/vvisp/scripts/deploy-service/preProcess/index.js index 200c73a..fe98e6e 100644 --- a/packages/vvisp/scripts/deploy-service/preProcess/index.js +++ b/packages/vvisp/scripts/deploy-service/preProcess/index.js @@ -42,6 +42,33 @@ module.exports = async function(deployState, options) { process.exit(); } + // Check whether this process needs Registry + // Event occurs when user sets config.registry false + if (config.registry === false) { + if (compileInformation.noProxy !== true) { + throw new Error( + `No Registry with upgradeable contracts is not allowed, change 'registry' from false to true in 'service.vvisp.json'` + ); + } else { + if (web3.utils.isAddress(stateClone.registry)) { + printOrSilent( + `${chalk.warning('Warning:')} Registry address ${ + stateClone.registry + } will be deleted.` + ); + } + compileInformation.noRegistry = true; + stateClone.registry = 'noRegistry'; + } + } else if (stateClone.registry === 'noRegistry') { + printOrSilent( + `${chalk.warning( + 'Notice:' + )} Sorry. In this version, we do not support adding registry in noRegistry service.\nKeep 'registry' property to false or re-deploy whole service.` + ); + process.exit(); + } + const compileOutput = await require('./compileAll')( compileInformation, options diff --git a/packages/vvisp/scripts/deploy-service/processes/deployBusinesses.js b/packages/vvisp/scripts/deploy-service/processes/deployBusinesses.js index a500296..42ffeb4 100644 --- a/packages/vvisp/scripts/deploy-service/processes/deployBusinesses.js +++ b/packages/vvisp/scripts/deploy-service/processes/deployBusinesses.js @@ -14,6 +14,10 @@ module.exports = async function(deployState, options) { const contracts = deployState.targets; let stateClone = deployState.getState(); + if (stateClone.noProxy === true) { + return; + } + const txCount = await getTxCount(PRIVATE_KEY); if (!stateClone.paused.details) { stateClone.paused.details = {}; diff --git a/packages/vvisp/scripts/deploy-service/processes/deployNonUpgradeables.js b/packages/vvisp/scripts/deploy-service/processes/deployNonUpgradeables.js index a103d0f..1938214 100644 --- a/packages/vvisp/scripts/deploy-service/processes/deployNonUpgradeables.js +++ b/packages/vvisp/scripts/deploy-service/processes/deployNonUpgradeables.js @@ -114,51 +114,58 @@ module.exports = async function(deployState, options) { } } - const registryInstance = pathToInstance(compileOutput, REGISTRY_PATH); - registryInstance.options.address = stateClone.registry; - - const setTargets = Object.keys(stateClone.paused.details); - const _addresses = []; - let _names = ''; - const _nameLength = []; - let _filNames = ''; - const _fileNameLength = []; - for (let i = 0; i < setTargets.length; i++) { - const { address, fileName } = stateClone.contracts[setTargets[i]]; - _addresses.push(address); - _names += setTargets[i]; - _nameLength.push(setTargets[i].length); - _filNames += fileName; - _fileNameLength.push(fileName.length); + if (stateClone.registry !== 'noRegistry') { + await registeringNonUpgradeableInfo(compileOutput, stateClone); } - const txData = registryInstance.methods - .setNonUpgradeables( - _addresses, - _names, - _nameLength, - _filNames, - _fileNameLength - ) - .encodeABI(); - printOrSilent( - chalk.head( - "\tRegister NonUpgradeable Contracts' Information åt Registry..." - ), - options - ); - const receipt = await sendTx(stateClone.registry, 0, PRIVATE_KEY, { - ...options, - ...TX_OPTIONS, - txCount: await getTxCount(PRIVATE_KEY), - data: txData - }); - printOrSilent( - `${chalk.success('Done')} Transaction Hash: ${chalk.tx( - receipt.transactionHash - )}\n`, - options - ); + // @dev Uploading information about nonUpgradeable contracts to registry + async function registeringNonUpgradeableInfo(compileOutput, stateClone) { + printOrSilent( + chalk.head( + "\tRegistering NonUpgradeable Contracts' Information at Registry..." + ), + options + ); + const registryInstance = pathToInstance(compileOutput, REGISTRY_PATH); + registryInstance.options.address = stateClone.registry; + + const setTargets = Object.keys(stateClone.paused.details); + const _addresses = []; + let _names = ''; + const _nameLength = []; + let _filNames = ''; + const _fileNameLength = []; + for (let i = 0; i < setTargets.length; i++) { + const { address, fileName } = stateClone.contracts[setTargets[i]]; + _addresses.push(address); + _names += setTargets[i]; + _nameLength.push(setTargets[i].length); + _filNames += fileName; + _fileNameLength.push(fileName.length); + } + const txData = registryInstance.methods + .setNonUpgradeables( + _addresses, + _names, + _nameLength, + _filNames, + _fileNameLength + ) + .encodeABI(); + + const receipt = await sendTx(stateClone.registry, 0, PRIVATE_KEY, { + ...options, + ...TX_OPTIONS, + txCount: await getTxCount(PRIVATE_KEY), + data: txData + }); + printOrSilent( + `${chalk.success('Done')} Transaction Hash: ${chalk.tx( + receipt.transactionHash + )}\n`, + options + ); + } function injectAddress(_arguments, _path, _index, contractAddress) { const argumentIndex = _path[_index]; diff --git a/packages/vvisp/scripts/deploy-service/processes/deployProxies.js b/packages/vvisp/scripts/deploy-service/processes/deployProxies.js index 8cc9f61..f2902a9 100644 --- a/packages/vvisp/scripts/deploy-service/processes/deployProxies.js +++ b/packages/vvisp/scripts/deploy-service/processes/deployProxies.js @@ -19,6 +19,10 @@ module.exports = async function(deployState, options) { const compileOutput = deployState.compileOutput; let stateClone = deployState.getState(); + if (stateClone.noProxy === true) { + return; + } + const txCount = await getTxCount(PRIVATE_KEY); const registryInstance = pathToInstance(compileOutput, REGISTRY_PATH); registryInstance.options.address = stateClone.registry; diff --git a/packages/vvisp/scripts/deploy-service/processes/deployRegistry.js b/packages/vvisp/scripts/deploy-service/processes/deployRegistry.js index 6a86351..4c22da3 100644 --- a/packages/vvisp/scripts/deploy-service/processes/deployRegistry.js +++ b/packages/vvisp/scripts/deploy-service/processes/deployRegistry.js @@ -6,9 +6,16 @@ module.exports = async function(deployState, options) { printOrSilent } = require('@haechi-labs/vvisp-utils'); + const stateClone = deployState.getState(); + if ( + stateClone.registry === 'noRegistry' || + stateClone.notUpgrading !== true + ) { + return; + } + printOrSilent('Registry Deploying...', options); const compileOutput = deployState.compileOutput; - const stateClone = deployState.getState(); const receipt = await deploy( getCompiledContracts(compileOutput, REGISTRY_PATH), diff --git a/packages/vvisp/scripts/deploy-service/processes/reflectState.js b/packages/vvisp/scripts/deploy-service/processes/reflectState.js index 8c48be2..8d3f574 100644 --- a/packages/vvisp/scripts/deploy-service/processes/reflectState.js +++ b/packages/vvisp/scripts/deploy-service/processes/reflectState.js @@ -14,5 +14,6 @@ module.exports = function(deployState, options) { }); delete stateClone.paused; delete stateClone.notUpgrading; + delete stateClone.noProxy; writeState(stateClone, options); }; diff --git a/packages/vvisp/scripts/deploy-service/processes/registerFileNames.js b/packages/vvisp/scripts/deploy-service/processes/registerFileNames.js index f57564d..b453076 100644 --- a/packages/vvisp/scripts/deploy-service/processes/registerFileNames.js +++ b/packages/vvisp/scripts/deploy-service/processes/registerFileNames.js @@ -16,6 +16,10 @@ module.exports = async function(deployState, options) { const { compileOutput, targets } = deployState; let stateClone = deployState.getState(); + if (stateClone.registry === 'noRegistry' || stateClone.noProxy === true) { + return; + } + const upgradeables = []; forIn(targets, (contract, name) => { if (contract[UPGRADEABLE] === true) { diff --git a/packages/vvisp/scripts/deploy-service/processes/upgradeAll.js b/packages/vvisp/scripts/deploy-service/processes/upgradeAll.js index 0017f42..6f9498a 100644 --- a/packages/vvisp/scripts/deploy-service/processes/upgradeAll.js +++ b/packages/vvisp/scripts/deploy-service/processes/upgradeAll.js @@ -18,6 +18,10 @@ module.exports = async function(deployState, options) { const { compileOutput, targets } = deployState; let stateClone = deployState.getState(); + if (stateClone.noProxy === true) { + return; + } + const upgradeables = []; forIn(targets, (contract, name) => { if (contract[UPGRADEABLE] === true) { diff --git a/packages/vvisp/test/dummy/noRegistry.service1.json b/packages/vvisp/test/dummy/noRegistry.service1.json new file mode 100644 index 0000000..251ac23 --- /dev/null +++ b/packages/vvisp/test/dummy/noRegistry.service1.json @@ -0,0 +1,38 @@ +{ + "serviceName": "Haechi", + "registry": false, + "variables" : { + "owner" : "0xb5F4E40c8177Ad63B19D4D3a254a5758771f57d0", + "value1": 1 + }, + "contracts": { + "DependencyA": { + "path": "contracts/test/DependencyA.sol", + "constructorArguments": [ + "${contracts.DependencyB.address}", + "${contracts.DependencyC.address}", + "${variables.owner}" + ] + }, + "DependencyB": { + "path": "contracts/test/DependencyB.sol", + "constructorArguments": [ + 3, + "${contracts.DependencyD.address}", + "${variables.owner}" + ] + }, + "DependencyC": { + "path": "contracts/test/DependencyC.sol", + "constructorArguments": [ + ] + }, + "DependencyD": { + "path": "contracts/test/DependencyD.sol", + "constructorArguments": [ + ["${variables.value1}",2,3], + "${variables.owner}" + ] + } + } +} diff --git a/packages/vvisp/test/dummy/noRegistry.service2.json b/packages/vvisp/test/dummy/noRegistry.service2.json new file mode 100644 index 0000000..cc8e1a0 --- /dev/null +++ b/packages/vvisp/test/dummy/noRegistry.service2.json @@ -0,0 +1,69 @@ +{ + "serviceName": "Haechi", + "registry": false, + "variables" : { + "owner" : "0xb5F4E40c8177Ad63B19D4D3a254a5758771f57d0", + "value1": 1 + }, + "contracts": { + "DependencyA": { + "path": "contracts/test/DependencyA.sol", + "constructorArguments": [ + "${contracts.DependencyB.address}", + "${contracts.DependencyC.address}", + "${variables.owner}" + ] + }, + "DependencyB": { + "path": "contracts/test/DependencyB.sol", + "constructorArguments": [ + 3, + "${contracts.DependencyD.address}", + "${variables.owner}" + ] + }, + "DependencyC": { + "path": "contracts/test/DependencyC.sol", + "constructorArguments": [ + ] + }, + "DependencyD": { + "path": "contracts/test/DependencyD.sol", + "constructorArguments": [ + ["${variables.value1}",2,3], + "${variables.owner}" + ] + }, + "SecondA": { + "path": "contracts/test/SecondA.sol", + "constructorArguments": [ + "${contracts.SecondC.address}", + "${contracts.DependencyD.address}", + ["${contracts.SecondC.address}", "${variables.owner}"] + ], + "initialize": { + "functionName": "initialize", + "arguments": [ + "${contracts.SecondD.address}", + "${variables.owner}", + ["${contracts.SecondC.address}", "${variables.owner}"] + ] + } + }, + "SecondC": { + "path": "contracts/test/SecondC.sol", + "constructorArguments": [ + "${contracts.SecondD.address}", + "${contracts.DependencyD.address}", + "${contracts.SecondD.address}" + ] + }, + "SecondD": { + "path": "contracts/test/SecondD.sol", + "constructorArguments": [ + "${variables.owner}", + "${variables.owner}" + ] + } + } +} diff --git a/packages/vvisp/test/dummy/noRegistry.state1.json b/packages/vvisp/test/dummy/noRegistry.state1.json new file mode 100644 index 0000000..303f522 --- /dev/null +++ b/packages/vvisp/test/dummy/noRegistry.state1.json @@ -0,0 +1,22 @@ +{ + "contracts": { + "DependencyA": { + "address": "0x0D2657C2136428Ba7bE1CcF0Ee8e2c5c6AACD927", + "fileName": "DependencyA.sol" + }, + "DependencyB": { + "address": "0x8b19C0EB06925f7708214230615228C9F30E49f0", + "fileName": "DependencyB.sol" + }, + "DependencyC": { + "address": "0x46f39068665D6EeDEFa53e5C660168AB9e946cA3", + "fileName": "DependencyC.sol" + }, + "DependencyD": { + "address": "0x074A3218146a98C8651696af9fF2396b5aD5700D", + "fileName": "DependencyD.sol" + } + }, + "serviceName": "Haechi", + "registry": "noRegistry" +} \ No newline at end of file diff --git a/packages/vvisp/test/scripts/deploy-service/index.test.js b/packages/vvisp/test/scripts/deploy-service/index.test.js index 6ab5345..ca75fa2 100644 --- a/packages/vvisp/test/scripts/deploy-service/index.test.js +++ b/packages/vvisp/test/scripts/deploy-service/index.test.js @@ -32,6 +32,9 @@ const NU_STATE1 = path.join('./test/dummy/justNonUpgradeables.state1.json'); const U_SERVICE1 = path.join('./test/dummy/justUpgradeables.service1.json'); const U_SERVICE2 = path.join('./test/dummy/justUpgradeables.service2.json'); const U_STATE1 = path.join('./test/dummy/justUpgradeables.state1.json'); +const N_R_SERVICE1 = path.join('./test/dummy/noRegistry.service1.json'); +const N_R_SERVICE2 = path.join('./test/dummy/noRegistry.service2.json'); +const N_R_STATE1 = path.join('./test/dummy/noRegistry.state1.json'); fs.removeSync(SERVICE_PATH); fs.removeSync(STATE_PATH); @@ -50,22 +53,35 @@ const { deploy: uDeployNum, upgrade: uUpgradeNum } = getTxcount( U_SERVICE2, U_STATE1 ); +const { deploy: nrDeployNum, upgrade: nrUpgradeNum } = getTxcount( + N_R_SERVICE1, + N_R_SERVICE2, + N_R_STATE1 +); describe('# deploy-service process test', function() { this.timeout(50000); + describe('# whole process test', function() { afterEach(function() { checkRightState(); }); + describe('# just nonUpgradeables case', function() { setWholeProcess(NU_SERVICE1, NU_SERVICE2); }); + describe('# just upgradeables case', function() { setWholeProcess(U_SERVICE1, U_SERVICE2); }); + describe('# mixed case', function() { setWholeProcess(SERVICE1, SERVICE2); }); + + describe('# no registry case', function() { + setWholeProcess(N_R_SERVICE1, N_R_SERVICE2); + }); }); describe('# resuming process test', function() { @@ -74,15 +90,22 @@ describe('# deploy-service process test', function() { fs.removeSync(SERVICE_PATH); fs.removeSync(STATE_PATH); }); + describe('# just nonUpgradeables case', function() { setResumingProcess(NU_SERVICE1, NU_SERVICE2, nuDeployNum, nuUpgradeNum); }); + describe('# just upgradeables case', function() { setResumingProcess(U_SERVICE1, U_SERVICE2, uDeployNum, uUpgradeNum); }); + describe('# mixed case', function() { setResumingProcess(SERVICE1, SERVICE2, deployNum, upgradeNum); }); + + describe('# no registry case', function() { + setResumingProcess(N_R_SERVICE1, N_R_SERVICE2, nrDeployNum, nrUpgradeNum); + }); }); }); @@ -92,7 +115,10 @@ function checkRightState() { Object.keys(state).should.have.lengthOf(3); state.serviceName.should.be.equal(service.serviceName); - web3.utils.isAddress(state.registry).should.equal(true); + + ( + web3.utils.isAddress(state.registry) || state.registry === 'noRegistry' + ).should.equal(true); const contracts = state.contracts; forIn(contracts, (contract, name) => { @@ -119,7 +145,11 @@ function getWaitingTxNum() { stateClone.notUpgrading = true; stateClone.contracts = {}; stateClone.serviceName = config.serviceName; - resultNumber++; // register + if (config.registry === false) { + stateClone.registry = 'noRegistry'; + } else { + resultNumber++; // registry + } } else { const file = fs.readJsonSync(STATE_PATH); forIn(file, (object, name) => { @@ -159,7 +189,7 @@ function getWaitingTxNum() { if (upgradeableExists) { resultNumber += 2; // upgradeAll, registerFileNames } - if (nonUpgradeableExists) { + if (nonUpgradeableExists && stateClone.registry !== 'noRegistry') { resultNumber++; // registerNonUpgradeables } return resultNumber; @@ -189,12 +219,14 @@ function setWholeProcess(service1, service2) { fs.copySync(service1, SERVICE_PATH); this.waitingTxNum = getWaitingTxNum(); }); + it('should success deploy process', async function() { const startTxCount = await web3.eth.getTransactionCount(SENDER); await deployService({ silent: true }); const endTxCount = await web3.eth.getTransactionCount(SENDER); (endTxCount - startTxCount).should.equal(this.waitingTxNum); }); + it('should success upgrade process', async function() { fs.copySync(service2, SERVICE_PATH); this.waitingTxNum = getWaitingTxNum(); @@ -203,6 +235,7 @@ function setWholeProcess(service1, service2) { const endTxCount = await web3.eth.getTransactionCount(SENDER); (endTxCount - startTxCount).should.equal(this.waitingTxNum); }); + after(function() { fs.removeSync(SERVICE_PATH); fs.removeSync(STATE_PATH); @@ -225,6 +258,7 @@ function setResumingProcess(service1, service2, deployTxCount, upgradeTxCount) { beforeEach(function() { fs.copySync(service1, SERVICE_PATH); }); + for (let i = 1; i < deployTxCount; i++) { it(`should resume when paused after ${i} txs`, async function() { runTxStopper(i, deployTxCount); @@ -234,12 +268,14 @@ function setResumingProcess(service1, service2, deployTxCount, upgradeTxCount) { }); } }); + describe('# upgrade process', function() { beforeEach(async function() { fs.copySync(service1, SERVICE_PATH); await deployService({ silent: true }); fs.copySync(service2, SERVICE_PATH); }); + for (let i = 1; i < upgradeTxCount; i++) { it(`should resume when paused after ${i} txs`, async function() { runTxStopper(i, deployTxCount);