From b68b936fe744886cefa8f97abf41bdeed7fa3423 Mon Sep 17 00:00:00 2001 From: filip mertens Date: Mon, 7 Jun 2021 12:36:07 +0200 Subject: [PATCH 01/51] fix logger bug --- apps/remix-ide/src/app/ui/txLogger.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/apps/remix-ide/src/app/ui/txLogger.js b/apps/remix-ide/src/app/ui/txLogger.js index 9a945a805d..632b30c778 100644 --- a/apps/remix-ide/src/app/ui/txLogger.js +++ b/apps/remix-ide/src/app/ui/txLogger.js @@ -354,6 +354,17 @@ module.exports = TxLogger // helpers +function isDescendant (parent, child) { + var node = child.parentNode + while (node != null) { + if (node === parent) { + return true + } + node = node.parentNode + } + return false +} + function txDetails (e, tx, data, obj) { const from = obj.from const to = obj.to @@ -368,9 +379,13 @@ function txDetails (e, tx, data, obj) { } else break } - let table = blockElement.querySelector(`#${tx.id} [class^="txTable"]`) - const log = blockElement.querySelector(`#${tx.id} [class^='log']`) - const arrow = blockElement.querySelector(`#${tx.id} [class^='arrow']`) + const tables = blockElement.querySelectorAll(`#${tx.id} [class^="txTable"]`) + const logs = blockElement.querySelectorAll(`#${tx.id} [class^='log']`) + const arrows = blockElement.querySelectorAll(`#${tx.id} [class^='arrow']`) + + let table = [...tables].filter((t) => isDescendant(tx, t))[0] + const log = [...logs].filter((t) => isDescendant(tx, t))[0] + const arrow = [...arrows].filter((t) => isDescendant(tx, t))[0] if (table && table.parentNode) { tx.removeChild(table) From 14428ce56c7e0a647c8e13614880da0991f769d1 Mon Sep 17 00:00:00 2001 From: Rob Stupay Date: Mon, 28 Jun 2021 21:53:59 -0400 Subject: [PATCH 02/51] new text for landing page --- apps/remix-ide/src/app/ui/landing-page/landing-page.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/ui/landing-page/landing-page.js b/apps/remix-ide/src/app/ui/landing-page/landing-page.js index 9719d0985c..1fa8b0dba2 100644 --- a/apps/remix-ide/src/app/ui/landing-page/landing-page.js +++ b/apps/remix-ide/src/app/ui/landing-page/landing-page.js @@ -534,7 +534,7 @@ export class LandingPage extends ViewPlugin { connectToLocalhost()}>Connect to Localhost

-

+

From be8fedb647c425e0f629fb6cc271b80eca7bd573 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 29 Jun 2021 10:10:34 +0200 Subject: [PATCH 03/51] ignore mapping if struct in memory (#1308) fix https://github.com/ethereum/remix-project/issues/271 --- libs/remix-debug/src/solidity-decoder/types/Mapping.ts | 2 +- libs/remix-debug/src/solidity-decoder/types/Struct.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/remix-debug/src/solidity-decoder/types/Mapping.ts b/libs/remix-debug/src/solidity-decoder/types/Mapping.ts index b8d1623cac..acb11e454d 100644 --- a/libs/remix-debug/src/solidity-decoder/types/Mapping.ts +++ b/libs/remix-debug/src/solidity-decoder/types/Mapping.ts @@ -38,7 +38,7 @@ export class Mapping extends RefType { decodeFromMemoryInternal (offset, memory) { // mappings can only exist in storage and not in memory // so this should never be called - return { value: '', length: '0x', type: this.typeName } + return { value: '', length: '0x0', type: this.typeName } } async decodeMappingsLocation (preimages, location, storageResolver) { diff --git a/libs/remix-debug/src/solidity-decoder/types/Struct.ts b/libs/remix-debug/src/solidity-decoder/types/Struct.ts index d71c43652c..f6ea2748bc 100644 --- a/libs/remix-debug/src/solidity-decoder/types/Struct.ts +++ b/libs/remix-debug/src/solidity-decoder/types/Struct.ts @@ -1,6 +1,7 @@ 'use strict' import { add } from './util' import { RefType } from './RefType' +import { Mapping } from './Mapping' export class Struct extends RefType { members @@ -33,7 +34,7 @@ export class Struct extends RefType { var contentOffset = offset var member = item.type.decodeFromMemory(contentOffset, memory) ret[item.name] = member - offset += 32 + if (!(item.type instanceof Mapping)) offset += 32 }) return { value: ret, type: this.typeName } } From 2b981bbdda2b888e75ebcfb84fad3ab7081397a3 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 29 Jun 2021 10:34:10 +0200 Subject: [PATCH 04/51] e2e for testing large value (#1304) fix https://github.com/ethereum/remix-project/issues/1272 --- apps/remix-ide-e2e/src/tests/specialFunctions.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/specialFunctions.test.ts b/apps/remix-ide-e2e/src/tests/specialFunctions.test.ts index 9056d43a63..279679bb60 100644 --- a/apps/remix-ide-e2e/src/tests/specialFunctions.test.ts +++ b/apps/remix-ide-e2e/src/tests/specialFunctions.test.ts @@ -177,10 +177,10 @@ module.exports = { .pause(1000) .perform((done) => { browser.getAddressAtPosition(4, (address) => { - browser.sendLowLevelTx(address, '1', '0xaa') + browser.sendLowLevelTx(address, '999999998765257135', '0xaa') .pause(1000) .journalLastChildIncludes('to: CheckSpecials.(fallback)') - .journalLastChildIncludes('value: 1 wei') + .journalLastChildIncludes('value: 999999998765257135 wei') .journalLastChildIncludes('data: 0xaa') .perform(done) }) From af71b9d0129b448e43f86ce1733f23b25e8dd5e4 Mon Sep 17 00:00:00 2001 From: dark64 Date: Sun, 23 May 2021 21:59:55 +0200 Subject: [PATCH 05/51] update ace-mode-zokrates --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index aac4527317..c7959fc85c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8443,9 +8443,9 @@ "dev": true }, "ace-mode-zokrates": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ace-mode-zokrates/-/ace-mode-zokrates-1.0.1.tgz", - "integrity": "sha512-+rTOLj1AJzV/XRXsMLNkWIjNQCIa8TYjWRunCTGJ620iUy7WRlMkU7uVRydq//t4GUdr0j2TkNM0fSqVs0zNWw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ace-mode-zokrates/-/ace-mode-zokrates-1.0.3.tgz", + "integrity": "sha512-g0pNtxsCFF5gs3/Gx6vuKrDX9zdnA0Mdcjuz/Yx1UYvAC34LT9+RGmtkreW+vGEHeVdbDyZlQQPABtlwFk4Imw==", "dev": true }, "acorn": { diff --git a/package.json b/package.json index f490be7e4d..c38299a2f4 100644 --- a/package.json +++ b/package.json @@ -219,7 +219,7 @@ "ace-mode-lexon": "^1.*.*", "ace-mode-move": "0.0.1", "ace-mode-solidity": "^0.1.0", - "ace-mode-zokrates": "^1.0.0", + "ace-mode-zokrates": "^1.0.3", "babel-eslint": "^10.0.0", "babel-jest": "25.1.0", "babel-plugin-add-module-exports": "^1.0.2", From 9909c1d2577324b459e158dc02adcfab453f86a8 Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 28 Jun 2021 11:43:12 +0200 Subject: [PATCH 06/51] update ace-mode-zokrates version --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index c7959fc85c..fa010f1b61 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8443,9 +8443,9 @@ "dev": true }, "ace-mode-zokrates": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ace-mode-zokrates/-/ace-mode-zokrates-1.0.3.tgz", - "integrity": "sha512-g0pNtxsCFF5gs3/Gx6vuKrDX9zdnA0Mdcjuz/Yx1UYvAC34LT9+RGmtkreW+vGEHeVdbDyZlQQPABtlwFk4Imw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/ace-mode-zokrates/-/ace-mode-zokrates-1.0.4.tgz", + "integrity": "sha512-jLpIg+PhJTlCWKu52U/EdJPQPJez9mMB0uzvCiyHgCJsX6+FY+s7jmBDrpxGdgNdNWJPQ20/MKzOx3oUnSF27A==", "dev": true }, "acorn": { diff --git a/package.json b/package.json index c38299a2f4..895639bd6c 100644 --- a/package.json +++ b/package.json @@ -219,7 +219,7 @@ "ace-mode-lexon": "^1.*.*", "ace-mode-move": "0.0.1", "ace-mode-solidity": "^0.1.0", - "ace-mode-zokrates": "^1.0.3", + "ace-mode-zokrates": "^1.0.4", "babel-eslint": "^10.0.0", "babel-jest": "25.1.0", "babel-plugin-add-module-exports": "^1.0.2", From 68d1cca5afbc29d67d7c4b76b02518380c4bc737 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Fri, 4 Jun 2021 14:04:26 +0530 Subject: [PATCH 07/51] short flags for options added --- libs/remixd/src/bin/remixd.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/remixd/src/bin/remixd.ts b/libs/remixd/src/bin/remixd.ts index 6b80867843..e783a927f0 100644 --- a/libs/remixd/src/bin/remixd.ts +++ b/libs/remixd/src/bin/remixd.ts @@ -58,9 +58,9 @@ function errorHandler (error: any, service: string) { program .usage('-s ') .description('Provide a two-way connection between the local computer and Remix IDE') - .option('--remix-ide ', 'URL of remix instance allowed to connect to this web sockect connection') + .option('-u, --remix-ide ', 'URL of remix instance allowed to connect to this web sockect connection') .option('-s, --shared-folder ', 'Folder to share with Remix IDE') - .option('--read-only', 'Treat shared folder as read-only (experimental)') + .option('-r, --read-only', 'Treat shared folder as read-only (experimental)') .on('--help', function () { console.log('\nExample:\n\n remixd -s ./ --remix-ide http://localhost:8080') }).parse(process.argv) From be39e2489b5d46b1a71272e86fd68733dd5a482f Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Fri, 4 Jun 2021 17:01:03 +0530 Subject: [PATCH 08/51] help updated --- libs/remixd/README.md | 20 +++++++++++--------- libs/remixd/src/bin/remixd.ts | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/libs/remixd/README.md b/libs/remixd/README.md index 21b18eb80a..648298445b 100644 --- a/libs/remixd/README.md +++ b/libs/remixd/README.md @@ -26,18 +26,20 @@ If you were using the old one you need to: ## HELP SECTION ``` - Usage: remixd -s --remix-ide https://remix.ethereum.org +Usage: remixd -s - Provide a two-way connection between the local computer and Remix IDE. - +Provide a two-way connection between the local computer and Remix IDE - Options: +Options: + -v, --version output the version number + -u, --remix-ide URL of remix instance allowed to connect to this web sockect connection + -s, --shared-folder Folder to share with Remix IDE + -r, --read-only Treat shared folder as read-only (experimental) + -h, --help output usage information - --remix-ide URL of remix instance allowed to connect to this - web sockect connection - -s, --shared-folder Folder to share with Remix IDE - --read-only Treat shared folder as read-only (experimental) - -h, --help output usage information +Example: + + remixd -s ./ -u http://localhost:8080 ``` diff --git a/libs/remixd/src/bin/remixd.ts b/libs/remixd/src/bin/remixd.ts index e783a927f0..2085735b8c 100644 --- a/libs/remixd/src/bin/remixd.ts +++ b/libs/remixd/src/bin/remixd.ts @@ -62,7 +62,7 @@ function errorHandler (error: any, service: string) { .option('-s, --shared-folder ', 'Folder to share with Remix IDE') .option('-r, --read-only', 'Treat shared folder as read-only (experimental)') .on('--help', function () { - console.log('\nExample:\n\n remixd -s ./ --remix-ide http://localhost:8080') + console.log('\nExample:\n\n remixd -s ./ -u http://localhost:8080') }).parse(process.argv) // eslint-disable-next-line From bf29aec305cc6b81bac027d34c79309921c685c1 Mon Sep 17 00:00:00 2001 From: Rob Date: Tue, 29 Jun 2021 06:24:32 -0400 Subject: [PATCH 09/51] update to Settings JavaScript VM (#1330) fix https://github.com/ethereum/remix-project/issues/1264 --- apps/remix-ide/src/app/tabs/settings-tab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/settings-tab.js b/apps/remix-ide/src/app/tabs/settings-tab.js index b692fb2611..3ef4d2953d 100644 --- a/apps/remix-ide/src/app/tabs/settings-tab.js +++ b/apps/remix-ide/src/app/tabs/settings-tab.js @@ -100,7 +100,7 @@ module.exports = class SettingsTab extends ViewPlugin {
` this._view.optionVM = yo`` - this._view.optionVMLabel = yo`` + this._view.optionVMLabel = yo`` if (this.config.get('settings/always-use-vm') === undefined) this.config.set('settings/always-use-vm', true) if (this.config.get('settings/always-use-vm')) this._view.optionVM.setAttribute('checked', '') elementStateChanged(self._view.optionVMLabel, !this.config.get('settings/always-use-vm')) From 103274a24d7642dfe31200d41b82ff29781afb46 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 21 Jun 2021 15:26:11 +0200 Subject: [PATCH 10/51] log with error input name --- libs/remix-lib/src/execution/txExecution.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libs/remix-lib/src/execution/txExecution.ts b/libs/remix-lib/src/execution/txExecution.ts index 639151c781..e87db02eb1 100644 --- a/libs/remix-lib/src/execution/txExecution.ts +++ b/libs/remix-lib/src/execution/txExecution.ts @@ -92,7 +92,7 @@ export function checkVMError (execResult, abi) { const returnDataHex = returnData.slice(0, 4).toString('hex') let customError if (abi) { - let decodedCustomErrorInputs + let decodedCustomErrorInputsClean for (const item of abi) { if (item.type === 'error') { // ethers doesn't crash anymore if "error" type is specified, but it doesn't extract the errors. see: @@ -104,16 +104,22 @@ export function checkVMError (execResult, abi) { if (!sign) continue if (returnDataHex === sign.replace('0x', '')) { customError = item.name - decodedCustomErrorInputs = fn.decodeFunctionData(fn.getFunction(item.name), returnData) + let functionDesc = fn.getFunction(item.name) + let decodedCustomErrorInputs = fn.decodeFunctionData(functionDesc, returnData) + decodedCustomErrorInputsClean = {} + for (const input of functionDesc.inputs) { + const v = decodedCustomErrorInputs[input.name] + decodedCustomErrorInputsClean[input.name] = v.toString ? v.toString() : v + } break } } } - if (decodedCustomErrorInputs) { + if (decodedCustomErrorInputsClean) { msg = '\tThe transaction has been reverted to the initial state.\nError provided by the contract:' msg += `\n${customError}` msg += '\nParameters:' - msg += `\n${decodedCustomErrorInputs}` + msg += `\n${JSON.stringify(decodedCustomErrorInputsClean, null, ' ')}` } } if (!customError) { From 9a91aad9831470d10e22bcbf923ede2849ec0dda Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 21 Jun 2021 18:03:22 +0200 Subject: [PATCH 11/51] add natspec info to error report --- .../src/tests/transactionExecution.spec.ts | 13 +++++++++++-- apps/remix-ide/src/app/ui/universal-dapp-ui.js | 8 +++++--- apps/remix-ide/src/blockchain/blockchain.js | 5 +++-- libs/remix-lib/src/execution/txExecution.ts | 14 ++++++++++++-- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/transactionExecution.spec.ts b/apps/remix-ide-e2e/src/tests/transactionExecution.spec.ts index e1d5ebb82f..d000d5e206 100644 --- a/apps/remix-ide-e2e/src/tests/transactionExecution.spec.ts +++ b/apps/remix-ide-e2e/src/tests/transactionExecution.spec.ts @@ -148,9 +148,14 @@ module.exports = { .click('.instance:nth-of-type(3) > div > button') .clickFunction('g - transact (not payable)') .journalLastChildIncludes('Error provided by the contract:') - .journalLastChildIncludes('CustomError') + .journalLastChildIncludes('CustomError: error description') .journalLastChildIncludes('Parameters:') - .journalLastChildIncludes('2,3,error_string_2') + .journalLastChildIncludes('"value": "2",') + .journalLastChildIncludes('"value": "3",') + .journalLastChildIncludes('"value": "error_string_2",') + .journalLastChildIncludes('"documentation": "param1"') + .journalLastChildIncludes('"documentation": "param2"') + .journalLastChildIncludes('"documentation": "param3"') .journalLastChildIncludes('Debug the transaction to get more information.') }, @@ -256,6 +261,10 @@ contract C { pragma solidity ^0.8.4; + /// error description + /// @param a param1 + /// @param b param2 + /// @param c param3 error CustomError(uint a, uint b, string c); contract C { function f() public pure { diff --git a/apps/remix-ide/src/app/ui/universal-dapp-ui.js b/apps/remix-ide/src/app/ui/universal-dapp-ui.js index 17fe7058c8..217217503f 100644 --- a/apps/remix-ide/src/app/ui/universal-dapp-ui.js +++ b/apps/remix-ide/src/app/ui/universal-dapp-ui.js @@ -44,14 +44,14 @@ UniversalDAppUI.prototype.renderInstance = function (contract, address, contract noInstances.parentNode.removeChild(noInstances) } const abi = txHelper.sortAbiFunction(contract.abi) - return this.renderInstanceFromABI(abi, address, contractName) + return this.renderInstanceFromABI(abi, address, contractName, contract) } // TODO this function was named before "appendChild". // this will render an instance: contract name, contract address, and all the public functions // basically this has to be called for the "atAddress" (line 393) and when a contract creation succeed // this returns a DOM element -UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address, contractName) { +UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address, contractName, contract) { const self = this address = (address.slice(0, 2) === '0x' ? '' : '0x') + address.toString('hex') address = ethJSUtil.toChecksumAddress(address) @@ -117,7 +117,8 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address funABI: funABI, address: address, contractABI: contractABI, - contractName: contractName + contractName: contractName, + contract })) }) @@ -255,6 +256,7 @@ UniversalDAppUI.prototype.runTransaction = function (lookupOnly, args, valArr, i args.contractName, args.contractABI, args.funABI, + args.contract, inputsValues, args.address, params, diff --git a/apps/remix-ide/src/blockchain/blockchain.js b/apps/remix-ide/src/blockchain/blockchain.js index f3dc841646..2b156e2a9b 100644 --- a/apps/remix-ide/src/blockchain/blockchain.js +++ b/apps/remix-ide/src/blockchain/blockchain.js @@ -249,7 +249,7 @@ class Blockchain { return txlistener } - runOrCallContractMethod (contractName, contractAbi, funABI, value, address, callType, lookupOnly, logMsg, logCallback, outputCb, confirmationCb, continueCb, promptCb) { + runOrCallContractMethod (contractName, contractAbi, funABI, contract, value, address, callType, lookupOnly, logMsg, logCallback, outputCb, confirmationCb, continueCb, promptCb) { // contractsDetails is used to resolve libraries txFormat.buildData(contractName, contractAbi, {}, false, funABI, callType, (error, data) => { if (error) { @@ -265,6 +265,7 @@ class Blockchain { if (data) { data.contractName = contractName data.contractABI = contractAbi + data.contract = contract } const useCall = funABI.stateMutability === 'view' || funABI.stateMutability === 'pure' this.runTx({ to: address, data, useCall }, confirmationCb, continueCb, promptCb, (error, txResult, _address, returnValue) => { @@ -490,7 +491,7 @@ class Blockchain { if (execResult) { // if it's not the VM, we don't have return value. We only have the transaction, and it does not contain the return value. returnValue = execResult ? execResult.returnValue : toBuffer(addHexPrefix(txResult.result) || '0x0000000000000000000000000000000000000000000000000000000000000000') - const vmError = txExecution.checkVMError(execResult, args.data.contractABI) + const vmError = txExecution.checkVMError(execResult, args.data.contractABI, args.data.contract) if (vmError.error) { return cb(vmError.message) } diff --git a/libs/remix-lib/src/execution/txExecution.ts b/libs/remix-lib/src/execution/txExecution.ts index e87db02eb1..035726c35e 100644 --- a/libs/remix-lib/src/execution/txExecution.ts +++ b/libs/remix-lib/src/execution/txExecution.ts @@ -57,7 +57,7 @@ export function callFunction (from, to, data, value, gasLimit, funAbi, txRunner, * @param {Object} execResult - execution result given by the VM * @return {Object} - { error: true/false, message: DOMNode } */ -export function checkVMError (execResult, abi) { +export function checkVMError (execResult, abi, contract) { const errorCode = { OUT_OF_GAS: 'out of gas', STACK_UNDERFLOW: 'stack underflow', @@ -107,9 +107,19 @@ export function checkVMError (execResult, abi) { let functionDesc = fn.getFunction(item.name) let decodedCustomErrorInputs = fn.decodeFunctionData(functionDesc, returnData) decodedCustomErrorInputsClean = {} + let devdoc = {} + if (contract && fn.functions && Object.keys(fn.functions).length) { + const functionSignature = Object.keys(fn.functions)[0] + devdoc = contract.object.devdoc.errors[functionSignature][0] || {} + let userdoc = contract.object.userdoc.errors[functionSignature][0] || {} + if (userdoc) customError += ' : ' + (userdoc as any).notice + } for (const input of functionDesc.inputs) { const v = decodedCustomErrorInputs[input.name] - decodedCustomErrorInputsClean[input.name] = v.toString ? v.toString() : v + decodedCustomErrorInputsClean[input.name] = { + value: v.toString ? v.toString() : v, + documentation: (devdoc as any).params[input.name] + } } break } From 74f9686f4b6e51099efd829cb53cedcc748cda9d Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 21 Jun 2021 18:13:35 +0200 Subject: [PATCH 12/51] linting --- libs/remix-lib/src/execution/txExecution.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/remix-lib/src/execution/txExecution.ts b/libs/remix-lib/src/execution/txExecution.ts index 035726c35e..bf6441e133 100644 --- a/libs/remix-lib/src/execution/txExecution.ts +++ b/libs/remix-lib/src/execution/txExecution.ts @@ -104,14 +104,14 @@ export function checkVMError (execResult, abi, contract) { if (!sign) continue if (returnDataHex === sign.replace('0x', '')) { customError = item.name - let functionDesc = fn.getFunction(item.name) - let decodedCustomErrorInputs = fn.decodeFunctionData(functionDesc, returnData) + const functionDesc = fn.getFunction(item.name) + const decodedCustomErrorInputs = fn.decodeFunctionData(functionDesc, returnData) decodedCustomErrorInputsClean = {} let devdoc = {} if (contract && fn.functions && Object.keys(fn.functions).length) { const functionSignature = Object.keys(fn.functions)[0] devdoc = contract.object.devdoc.errors[functionSignature][0] || {} - let userdoc = contract.object.userdoc.errors[functionSignature][0] || {} + const userdoc = contract.object.userdoc.errors[functionSignature][0] || {} if (userdoc) customError += ' : ' + (userdoc as any).notice } for (const input of functionDesc.inputs) { From 59e7788facc4a6017b5339eb032a9d82f40e94ac Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 22 Jun 2021 08:25:04 +0200 Subject: [PATCH 13/51] e2e test --- apps/remix-ide-e2e/src/tests/transactionExecution.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/transactionExecution.spec.ts b/apps/remix-ide-e2e/src/tests/transactionExecution.spec.ts index d000d5e206..f67a954706 100644 --- a/apps/remix-ide-e2e/src/tests/transactionExecution.spec.ts +++ b/apps/remix-ide-e2e/src/tests/transactionExecution.spec.ts @@ -148,7 +148,7 @@ module.exports = { .click('.instance:nth-of-type(3) > div > button') .clickFunction('g - transact (not payable)') .journalLastChildIncludes('Error provided by the contract:') - .journalLastChildIncludes('CustomError: error description') + .journalLastChildIncludes('CustomError : error description') .journalLastChildIncludes('Parameters:') .journalLastChildIncludes('"value": "2",') .journalLastChildIncludes('"value": "3",') From b3162c8de9bc06e4a5bae44a4bf8695da35bf443 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 29 Jun 2021 10:10:45 +0200 Subject: [PATCH 14/51] add comment --- libs/remix-lib/src/execution/txExecution.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libs/remix-lib/src/execution/txExecution.ts b/libs/remix-lib/src/execution/txExecution.ts index bf6441e133..792175a48c 100644 --- a/libs/remix-lib/src/execution/txExecution.ts +++ b/libs/remix-lib/src/execution/txExecution.ts @@ -105,20 +105,24 @@ export function checkVMError (execResult, abi, contract) { if (returnDataHex === sign.replace('0x', '')) { customError = item.name const functionDesc = fn.getFunction(item.name) + // decoding error parameters const decodedCustomErrorInputs = fn.decodeFunctionData(functionDesc, returnData) decodedCustomErrorInputsClean = {} let devdoc = {} + // "contract" reprensents the compilation result containing the NATSPEC documentation if (contract && fn.functions && Object.keys(fn.functions).length) { const functionSignature = Object.keys(fn.functions)[0] + // we check in the 'devdoc' if there's a developer documentation for this error devdoc = contract.object.devdoc.errors[functionSignature][0] || {} + // we check in the 'userdoc' if there's an user documentation for this error const userdoc = contract.object.userdoc.errors[functionSignature][0] || {} - if (userdoc) customError += ' : ' + (userdoc as any).notice + if (userdoc) customError += ' : ' + (userdoc as any).notice // we append the user doc if any } for (const input of functionDesc.inputs) { const v = decodedCustomErrorInputs[input.name] decodedCustomErrorInputsClean[input.name] = { value: v.toString ? v.toString() : v, - documentation: (devdoc as any).params[input.name] + documentation: (devdoc as any).params[input.name] // we add the developer documentation for this input parameter if any } } break From 42e9299af3fb4182bf00233de3a8f27be36a42ec Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 29 Jun 2021 12:13:44 +0200 Subject: [PATCH 15/51] fix e2e --- .../remix-ide-e2e/src/tests/transactionExecution.spec.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/transactionExecution.spec.ts b/apps/remix-ide-e2e/src/tests/transactionExecution.spec.ts index f67a954706..d06c1c1c9d 100644 --- a/apps/remix-ide-e2e/src/tests/transactionExecution.spec.ts +++ b/apps/remix-ide-e2e/src/tests/transactionExecution.spec.ts @@ -168,9 +168,14 @@ module.exports = { .click('.instance:nth-of-type(2) > div > button') .clickFunction('g - transact (not payable)') .journalLastChildIncludes('Error provided by the contract:') - .journalLastChildIncludes('CustomError') + .journalLastChildIncludes('CustomError : error description') .journalLastChildIncludes('Parameters:') - .journalLastChildIncludes('2,3,error_string_2') + .journalLastChildIncludes('"value": "2",') + .journalLastChildIncludes('"value": "3",') + .journalLastChildIncludes('"value": "error_string_2",') + .journalLastChildIncludes('"documentation": "param1"') + .journalLastChildIncludes('"documentation": "param2"') + .journalLastChildIncludes('"documentation": "param3"') .journalLastChildIncludes('Debug the transaction to get more information.') .end() } From 4ec58ea7d8a0f2336d3ade66a71bed2f956f9697 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 17 Jun 2021 14:15:08 +0200 Subject: [PATCH 16/51] make sure non zero are highlighted --- .../src/lib/vm-debugger/dropdown-panel.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx index 4ba9b16c12..0ce016fda4 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx @@ -34,10 +34,19 @@ export const DropdownPanel = (props: DropdownPanelProps) => { return ret } const formatSelfDefault = (key: string | number, data: ExtractData) => { + let value + if (typeof(data.self) === 'string') { + let regex = /^(0+)(.*)/g + let split = regex.exec(data.self.replace('0x', '')) + if (split && split[1] && split[2]) { + split[1] = data.self.indexOf('0x') === 0 ? '0x' + split[1] : split[1] + value = ({split[1]}{split[2]}) + } + } else value = data.self return (
- +
) } From 1c8eeffad8a8b94221deb251a48d5f6f95a7df8c Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 17 Jun 2021 14:40:48 +0200 Subject: [PATCH 17/51] use monospace for memory and stack --- .../debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx | 6 +++--- .../debugger-ui/src/lib/vm-debugger/memory-panel.tsx | 2 +- .../debugger-ui/src/lib/vm-debugger/stack-panel.tsx | 2 +- libs/remix-ui/debugger-ui/src/types/index.ts | 4 +++- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx index 0ce016fda4..3abd08fcbb 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx @@ -7,7 +7,7 @@ import './styles/dropdown-panel.css' export const DropdownPanel = (props: DropdownPanelProps) => { const [calldataObj, dispatch] = useReducer(reducer, initialState) - const { dropdownName, dropdownMessage, calldata, header, loading, extractFunc, formatSelfFunc, registerEvent, triggerEvent, loadMoreEvent, loadMoreCompletedEvent } = props + const { dropdownName, dropdownMessage, calldata, header, loading, extractFunc, formatSelfFunc, registerEvent, triggerEvent, loadMoreEvent, loadMoreCompletedEvent, headStyle, bodyStyle } = props const extractDataDefault: ExtractFunc = (item, parent?) => { const ret: ExtractData = {} @@ -193,14 +193,14 @@ export const DropdownPanel = (props: DropdownPanelProps) => { return (
-
+
{dropdownName}
{header}
-
+
{ state.data && diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/memory-panel.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/memory-panel.tsx index b772369ec6..75358e9c07 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/memory-panel.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/memory-panel.tsx @@ -3,7 +3,7 @@ import DropdownPanel from './dropdown-panel' // eslint-disable-line export const MemoryPanel = ({ calldata }) => { return ( - + ) } diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/stack-panel.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/stack-panel.tsx index fcb86b2699..1824a55477 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/stack-panel.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/stack-panel.tsx @@ -4,7 +4,7 @@ import DropdownPanel from './dropdown-panel' // eslint-disable-line export const StackPanel = ({ calldata }) => { return (
- +
) } diff --git a/libs/remix-ui/debugger-ui/src/types/index.ts b/libs/remix-ui/debugger-ui/src/types/index.ts index 45a26384dc..b968815242 100644 --- a/libs/remix-ui/debugger-ui/src/types/index.ts +++ b/libs/remix-ui/debugger-ui/src/types/index.ts @@ -27,7 +27,9 @@ export interface DropdownPanelProps { registerEvent?: Function, triggerEvent?: Function, loadMoreEvent?: string, - loadMoreCompletedEvent?: string + loadMoreCompletedEvent?: string, + bodyStyle?: React.CSSProperties + headStyle?: React.CSSProperties } export type FormatSelfFunc = (key: string | number, data: ExtractData) => JSX.Element From 9a76c08375f220ce9a145418bff18b0b7da351bc Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 17 Jun 2021 16:01:31 +0200 Subject: [PATCH 18/51] use hexHighlight --- .../src/lib/vm-debugger/dropdown-panel.tsx | 22 ++++++++++--------- .../src/lib/vm-debugger/memory-panel.tsx | 2 +- .../src/lib/vm-debugger/stack-panel.tsx | 2 +- .../src/lib/vm-debugger/step-detail.tsx | 2 +- libs/remix-ui/debugger-ui/src/types/index.ts | 5 +++-- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx index 3abd08fcbb..4b196b9796 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx @@ -7,7 +7,7 @@ import './styles/dropdown-panel.css' export const DropdownPanel = (props: DropdownPanelProps) => { const [calldataObj, dispatch] = useReducer(reducer, initialState) - const { dropdownName, dropdownMessage, calldata, header, loading, extractFunc, formatSelfFunc, registerEvent, triggerEvent, loadMoreEvent, loadMoreCompletedEvent, headStyle, bodyStyle } = props + const { dropdownName, dropdownMessage, calldata, header, loading, extractFunc, formatSelfFunc, registerEvent, triggerEvent, loadMoreEvent, loadMoreCompletedEvent, headStyle, bodyStyle, hexHighlight } = props const extractDataDefault: ExtractFunc = (item, parent?) => { const ret: ExtractData = {} @@ -34,15 +34,17 @@ export const DropdownPanel = (props: DropdownPanelProps) => { return ret } const formatSelfDefault = (key: string | number, data: ExtractData) => { - let value - if (typeof(data.self) === 'string') { - let regex = /^(0+)(.*)/g - let split = regex.exec(data.self.replace('0x', '')) - if (split && split[1] && split[2]) { - split[1] = data.self.indexOf('0x') === 0 ? '0x' + split[1] : split[1] - value = ({split[1]}{split[2]}) - } - } else value = data.self + let value + if (hexHighlight && typeof(data.self) === 'string') { + const isHex = data.self.startsWith('0x') || hexHighlight + if (isHex) { + let regex = /^(0+)(.*)/g + let split = regex.exec(data.self.replace('0x', '')) + if (split && split[1]) { + value = (0x{split[1]}{ split[2] && {split[2]} }) + } else value = (0x{data.self.replace('0x', '')}) + } else value = {data.self} + } else value = {data.self} return (
diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/memory-panel.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/memory-panel.tsx index 75358e9c07..8e6cd8b3be 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/memory-panel.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/memory-panel.tsx @@ -3,7 +3,7 @@ import DropdownPanel from './dropdown-panel' // eslint-disable-line export const MemoryPanel = ({ calldata }) => { return ( - + ) } diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/stack-panel.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/stack-panel.tsx index 1824a55477..0864ec035f 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/stack-panel.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/stack-panel.tsx @@ -4,7 +4,7 @@ import DropdownPanel from './dropdown-panel' // eslint-disable-line export const StackPanel = ({ calldata }) => { return (
- +
) } diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/step-detail.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/step-detail.tsx index 15d17a7792..f4669baebc 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/step-detail.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/step-detail.tsx @@ -4,7 +4,7 @@ import DropdownPanel from './dropdown-panel' // eslint-disable-line export const StepDetail = ({ stepDetail }) => { return (
- +
) } diff --git a/libs/remix-ui/debugger-ui/src/types/index.ts b/libs/remix-ui/debugger-ui/src/types/index.ts index b968815242..9d13aab883 100644 --- a/libs/remix-ui/debugger-ui/src/types/index.ts +++ b/libs/remix-ui/debugger-ui/src/types/index.ts @@ -28,8 +28,9 @@ export interface DropdownPanelProps { triggerEvent?: Function, loadMoreEvent?: string, loadMoreCompletedEvent?: string, - bodyStyle?: React.CSSProperties - headStyle?: React.CSSProperties + bodyStyle?: React.CSSProperties, + headStyle?: React.CSSProperties, + hexHighlight?: boolean // highlight non zero value of hex value } export type FormatSelfFunc = (key: string | number, data: ExtractData) => JSX.Element From 5704f367e44a8bbaff9e05bf70e737a70269537d Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 17 Jun 2021 22:37:23 +0200 Subject: [PATCH 19/51] linting --- .../src/lib/vm-debugger/dropdown-panel.tsx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx index 4b196b9796..207e99ea74 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx @@ -34,16 +34,16 @@ export const DropdownPanel = (props: DropdownPanelProps) => { return ret } const formatSelfDefault = (key: string | number, data: ExtractData) => { - let value - if (hexHighlight && typeof(data.self) === 'string') { - const isHex = data.self.startsWith('0x') || hexHighlight - if (isHex) { - let regex = /^(0+)(.*)/g - let split = regex.exec(data.self.replace('0x', '')) - if (split && split[1]) { - value = (0x{split[1]}{ split[2] && {split[2]} }) - } else value = (0x{data.self.replace('0x', '')}) - } else value = {data.self} + let value + if (hexHighlight && typeof (data.self) === 'string') { + const isHex = data.self.startsWith('0x') || hexHighlight + if (isHex) { + const regex = /^(0+)(.*)/g + const split = regex.exec(data.self.replace('0x', '')) + if (split && split[1]) { + value = (0x{split[1]}{ split[2] && {split[2]} }) + } else value = (0x{data.self.replace('0x', '')}) + } else value = {data.self} } else value = {data.self} return (
From 8a712184e3d90469e4aa8bae7ce8d039105cfbb9 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 17 Jun 2021 17:12:05 +0200 Subject: [PATCH 20/51] use a better code comparison --- libs/remix-lib/src/util.ts | 6 ++++-- package-lock.json | 5 +++++ package.json | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/libs/remix-lib/src/util.ts b/libs/remix-lib/src/util.ts index cc70e786e8..f14e48174a 100644 --- a/libs/remix-lib/src/util.ts +++ b/libs/remix-lib/src/util.ts @@ -1,5 +1,6 @@ 'use strict' import { BN, bufferToHex, keccak, setLengthLeft, toBuffer, addHexPrefix } from 'ethereumjs-util' +import stringSimilarity from 'string-similarity' /* contains misc util: @TODO should be splitted @@ -222,8 +223,9 @@ export function compareByteCode (code1, code2) { code2 = this.extractSwarmHash(code2) code2 = this.extractcborMetadata(code2) - if (code1 && code2 && code1.indexOf(code2) === 0) { - return true + if (code1 && code2) { + const compare = stringSimilarity.compareTwoStrings(code1, code2) + return compare > 0.5 } return false } diff --git a/package-lock.json b/package-lock.json index fa010f1b61..9e028132b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36072,6 +36072,11 @@ } } }, + "string-similarity": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-4.0.4.tgz", + "integrity": "sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==" + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", diff --git a/package.json b/package.json index 895639bd6c..07ab9d39e1 100644 --- a/package.json +++ b/package.json @@ -172,6 +172,7 @@ "react-dom": "16.13.1", "selenium": "^2.20.0", "signale": "^1.4.0", + "string-similarity": "^4.0.4", "time-stamp": "^2.2.0", "tslib": "^2.3.0", "web3": "1.2.4", From 6171000e171591e9ea22d76cb7fcff3960909287 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 17 Jun 2021 17:12:19 +0200 Subject: [PATCH 21/51] manage immutable --- libs/remix-debug/src/solidity-decoder/decodeInfo.ts | 11 +++++++---- libs/remix-debug/src/solidity-decoder/stateDecoder.ts | 4 ++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/libs/remix-debug/src/solidity-decoder/decodeInfo.ts b/libs/remix-debug/src/solidity-decoder/decodeInfo.ts index 5384b1af86..d506e5ca3e 100644 --- a/libs/remix-debug/src/solidity-decoder/decodeInfo.ts +++ b/libs/remix-debug/src/solidity-decoder/decodeInfo.ts @@ -336,7 +336,9 @@ function computeOffsets (types, stateDefinitions, contractName, location) { console.log('unable to retrieve decode info of ' + variable.typeDescriptions.typeString) return null } - if (!variable.constant && storagelocation.offset + type.storageBytes > 32) { + const immutable = variable.mutability === 'immutable' + const hasStorageSlots = !immutable && !variable.constant + if (hasStorageSlots && storagelocation.offset + type.storageBytes > 32) { storagelocation.slot++ storagelocation.offset = 0 } @@ -344,12 +346,13 @@ function computeOffsets (types, stateDefinitions, contractName, location) { name: variable.name, type: type, constant: variable.constant, + immutable, storagelocation: { - offset: variable.constant ? 0 : storagelocation.offset, - slot: variable.constant ? 0 : storagelocation.slot + offset: !hasStorageSlots ? 0 : storagelocation.offset, + slot: !hasStorageSlots ? 0 : storagelocation.slot } }) - if (!variable.constant) { + if (hasStorageSlots) { if (type.storageSlots === 1 && storagelocation.offset + type.storageBytes <= 32) { storagelocation.offset += type.storageBytes } else { diff --git a/libs/remix-debug/src/solidity-decoder/stateDecoder.ts b/libs/remix-debug/src/solidity-decoder/stateDecoder.ts index 0e27ac740c..b7908da3c3 100644 --- a/libs/remix-debug/src/solidity-decoder/stateDecoder.ts +++ b/libs/remix-debug/src/solidity-decoder/stateDecoder.ts @@ -15,9 +15,13 @@ export async function decodeState (stateVars, storageResolver) { try { const decoded = await stateVar.type.decodeFromStorage(stateVar.storagelocation, storageResolver) decoded.constant = stateVar.constant + decoded.immutable = stateVar.immutable if (decoded.constant) { decoded.value = '' } + if (decoded.immutable) { + decoded.value = '' + } ret[stateVar.name] = decoded } catch (e) { console.log(e) From 19f026db403daad95661b2c12c387a7ae6960873 Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 18 Jun 2021 14:10:43 +0200 Subject: [PATCH 22/51] fix e2e --- apps/remix-ide-e2e/src/tests/ballot.test.ts | 9 ++++++--- apps/remix-ide-e2e/src/tests/debugger.spec.ts | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/ballot.test.ts b/apps/remix-ide-e2e/src/tests/ballot.test.ts index b44b17746e..aa6d507120 100644 --- a/apps/remix-ide-e2e/src/tests/ballot.test.ts +++ b/apps/remix-ide-e2e/src/tests/ballot.test.ts @@ -121,7 +121,8 @@ const stateCheck = { chairperson: { value: '0xCA35B7D915458EF540ADE6068DFE2F44E8FA733C', type: 'address', - constant: false + constant: false, + immutable: false }, voters: { value: { @@ -148,7 +149,8 @@ const stateCheck = { } }, type: 'mapping(address => struct Ballot.Voter)', - constant: false + constant: false, + immutable: false }, proposals: { value: [ @@ -168,7 +170,8 @@ const stateCheck = { ], length: '0x1', type: 'struct Ballot.Proposal[]', - constant: false + constant: false, + immutable: false } } diff --git a/apps/remix-ide-e2e/src/tests/debugger.spec.ts b/apps/remix-ide-e2e/src/tests/debugger.spec.ts index 78406a7b8d..0baeee65b3 100644 --- a/apps/remix-ide-e2e/src/tests/debugger.spec.ts +++ b/apps/remix-ide-e2e/src/tests/debugger.spec.ts @@ -228,7 +228,7 @@ module.exports = { .waitForElementVisible('*[data-id="solidityLocals"]', 60000) .pause(10000) .checkVariableDebug('soliditylocals', { num: { value: '2', type: 'uint256' } }) - .checkVariableDebug('soliditystate', { number: { value: '0', type: 'uint256', constant: false } }) + .checkVariableDebug('soliditystate', { number: { value: '0', type: 'uint256', constant: false, immutable: false } }) .end() } } From 11bed910253fecb6634350a690db9f63b41e2f9f Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 24 Jun 2021 09:59:46 +0200 Subject: [PATCH 23/51] change comparison treshold --- libs/remix-lib/src/util.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/remix-lib/src/util.ts b/libs/remix-lib/src/util.ts index f14e48174a..58f5d875dd 100644 --- a/libs/remix-lib/src/util.ts +++ b/libs/remix-lib/src/util.ts @@ -225,8 +225,9 @@ export function compareByteCode (code1, code2) { if (code1 && code2) { const compare = stringSimilarity.compareTwoStrings(code1, code2) - return compare > 0.5 + return compare > 0.93 } + return false } /* util extracted out from remix-ide. @TODO split this file, cause it mix real util fn with solidity related stuff ... */ From 4a52c879f40b7f592dbb58eed525bcfe7eb64d5e Mon Sep 17 00:00:00 2001 From: David Zagi Date: Wed, 30 Jun 2021 08:17:02 +0100 Subject: [PATCH 24/51] feat: task configuration and creating of setting-tab in react (#1171) initial project setup and creation of setting tab in react Fixes https://github.com/ethereum/remix-project/issues/1159 --- .../src/tests/generalSettings.test.ts | 17 +- apps/remix-ide-e2e/src/tests/runAndDeploy.ts | 2 + apps/remix-ide/src/app/tabs/settings-tab.js | 221 ++---------------- .../copy-to-clipboard/copy-to-clipboard.tsx | 1 + libs/remix-ui/settings/.babelrc | 4 + libs/remix-ui/settings/.eslintrc | 19 ++ libs/remix-ui/settings/README.md | 7 + libs/remix-ui/settings/src/index.ts | 1 + libs/remix-ui/settings/src/lib/constants.ts | 12 + .../settings/src/lib/remix-ui-settings.css | 0 .../settings/src/lib/remix-ui-settings.tsx | 166 +++++++++++++ .../settings/src/lib/settingsAction.ts | 52 +++++ .../settings/src/lib/settingsReducer.ts | 103 ++++++++ libs/remix-ui/settings/tsconfig.json | 16 ++ libs/remix-ui/settings/tsconfig.lib.json | 13 ++ nx.json | 6 + package.json | 2 +- tsconfig.json | 4 +- workspace.json | 18 +- 19 files changed, 452 insertions(+), 212 deletions(-) create mode 100644 libs/remix-ui/settings/.babelrc create mode 100644 libs/remix-ui/settings/.eslintrc create mode 100644 libs/remix-ui/settings/README.md create mode 100644 libs/remix-ui/settings/src/index.ts create mode 100644 libs/remix-ui/settings/src/lib/constants.ts create mode 100644 libs/remix-ui/settings/src/lib/remix-ui-settings.css create mode 100644 libs/remix-ui/settings/src/lib/remix-ui-settings.tsx create mode 100644 libs/remix-ui/settings/src/lib/settingsAction.ts create mode 100644 libs/remix-ui/settings/src/lib/settingsReducer.ts create mode 100644 libs/remix-ui/settings/tsconfig.json create mode 100644 libs/remix-ui/settings/tsconfig.lib.json diff --git a/apps/remix-ide-e2e/src/tests/generalSettings.test.ts b/apps/remix-ide-e2e/src/tests/generalSettings.test.ts index 9c605afec0..b79d2e5054 100644 --- a/apps/remix-ide-e2e/src/tests/generalSettings.test.ts +++ b/apps/remix-ide-e2e/src/tests/generalSettings.test.ts @@ -18,6 +18,7 @@ module.exports = { 'Should activate `generate contract metadata`': function (browser) { browser.waitForElementVisible('*[data-id="remixIdeSidePanel"]', 5000) .waitForElementVisible('*[data-id="settingsTabGenerateContractMetadataLabel"]', 5000) + .verify.elementPresent('[data-id="settingsTabGenerateContractMetadata"]:checked') .click('*[data-id="verticalIconsFileExplorerIcons"]') .click('[data-id="treeViewLitreeViewItemcontracts"]') .openFile('contracts/3_Ballot.sol') @@ -39,22 +40,26 @@ module.exports = { .click('*[data-id="verticalIconsKindsettings"]') .setValue('*[data-id="settingsTabGistAccessToken"]', '**********') .click('*[data-id="settingsTabSaveGistToken"]') - .waitForElementVisible('*[data-shared="tooltipPopup"]:nth-last-of-type(1)', 5000) - .assert.containsText('*[data-shared="tooltipPopup"]:nth-last-of-type(1)', 'Access token has been saved') + .waitForElementVisible('*[data-shared="tooltipPopup"]', 5000) + .assert.containsText('*[data-shared="tooltipPopup"]', 'Access token has been saved') + .pause(3000) }, 'Should copy github access token to clipboard': function (browser: NightwatchBrowser) { browser.waitForElementVisible('*[data-id="verticalIconsKindsettings"]', 5000) .click('*[data-id="copyToClipboardCopyIcon"]') - .waitForElementVisible('*[data-shared="tooltipPopup"]:nth-last-of-type(1)', 5000) - .assert.containsText('*[data-shared="tooltipPopup"]:nth-last-of-type(1)', 'Copied value to clipboard.') + .waitForElementVisible('*[data-shared="tooltipPopup"]', 5000) + // .waitForElementVisible('*[data-shared="tooltipPopup"]:nth-last-of-type(1) , 5000) + // .assert.containsText('*[data-shared="tooltipPopup"]', 'Copied value to clipboard.') + // .assert.containsText('*[data-shared="tooltipPopup"]:nth-last-of-type(1)', 'Copied value to clipboard.') }, 'Should remove github access token': function (browser: NightwatchBrowser) { browser.waitForElementVisible('*[data-id="verticalIconsKindsettings"]', 5000) + .pause(1000) .click('*[data-id="settingsTabRemoveGistToken"]') - .waitForElementVisible('*[data-shared="tooltipPopup"]:nth-last-of-type(1)', 5000) - .assert.containsText('*[data-shared="tooltipPopup"]:nth-last-of-type(1)', 'Access token removed') + .waitForElementVisible('*[data-shared="tooltipPopup"]', 5000) + .assert.containsText('*[data-shared="tooltipPopup"]', 'Access token removed') .assert.containsText('*[data-id="settingsTabGistAccessToken"]', '') }, diff --git a/apps/remix-ide-e2e/src/tests/runAndDeploy.ts b/apps/remix-ide-e2e/src/tests/runAndDeploy.ts index 20455df8b3..a138bc77d1 100644 --- a/apps/remix-ide-e2e/src/tests/runAndDeploy.ts +++ b/apps/remix-ide-e2e/src/tests/runAndDeploy.ts @@ -32,6 +32,8 @@ module.exports = { 'Should sign message using account key': function (browser: NightwatchBrowser) { browser.waitForElementPresent('*[data-id="settingsRemixRunSignMsg"]') + .click('select[id="selectExEnvOptions"] option[value="vm-berlin"]') + .pause(2000) .click('*[data-id="settingsRemixRunSignMsg"]') .pause(2000) .waitForElementPresent('*[data-id="modalDialogCustomPromptText"]') diff --git a/apps/remix-ide/src/app/tabs/settings-tab.js b/apps/remix-ide/src/app/tabs/settings-tab.js index 3ef4d2953d..8c3889a02b 100644 --- a/apps/remix-ide/src/app/tabs/settings-tab.js +++ b/apps/remix-ide/src/app/tabs/settings-tab.js @@ -1,12 +1,10 @@ +import React from 'react' // eslint-disable-line import { ViewPlugin } from '@remixproject/engine-web' +import ReactDOM from 'react-dom' import * as packageJson from '../../../../../package.json' -const yo = require('yo-yo') +import { RemixUiSettings } from '@remix-ui/settings' //eslint-disable-line const globalRegistry = require('../../global/registry') -const tooltip = require('../ui/tooltip') -const copyToClipboard = require('../ui/copy-to-clipboard') const EventManager = require('../../lib/events') -const css = require('./styles/settings-tab-styles') -const _paq = window._paq = window._paq || [] const profile = { name: 'settings', @@ -51,210 +49,27 @@ module.exports = class SettingsTab extends ViewPlugin { textWrapLabel: null } /* eslint-enable */ this.event = new EventManager() + this.element = document.createElement('div') + this.element.setAttribute('id', 'settingsTab') } - createThemeCheckies () { - const themes = this._deps.themeModule.getThemes() - const onswitchTheme = (event, name) => { - this._deps.themeModule.switchTheme(name) - } - if (themes) { - return yo`
- ${themes.map((aTheme) => { - const el = yo`
- { onswitchTheme(event, aTheme.name) }} class="align-middle custom-control-input" name="theme" id="${aTheme.name}" data-id="settingsTabTheme${aTheme.name}"> - -
` - if (this._deps.themeModule.active === aTheme.name) el.querySelector('input').setAttribute('checked', 'checked') - return el - })} -
` - } + onActivation () { + this.renderComponent() } render () { - const self = this - if (self._view.el) return self._view.el - - // Gist settings - const token = this.config.get('settings/gist-access-token') - const gistAccessToken = yo`` - if (token) gistAccessToken.value = token - const removeToken = () => { self.config.set('settings/gist-access-token', ''); gistAccessToken.value = ''; tooltip('Access token removed') } - const saveToken = () => { - this.config.set('settings/gist-access-token', gistAccessToken.value) - tooltip('Access token has been saved. RELOAD the page to apply it.') - } - const gistAddToken = yo` saveToken()} value="Save" type="button">` - const gistRemoveToken = yo`` - this._view.gistToken = yo` -
- ${gistAccessToken} -
- ${copyToClipboard(() => gistAccessToken.value)}${gistAddToken}${gistRemoveToken} -
-

- - Please reload Remix after having saved the token. -

-
- ` - this._view.optionVM = yo`` - this._view.optionVMLabel = yo`` - if (this.config.get('settings/always-use-vm') === undefined) this.config.set('settings/always-use-vm', true) - if (this.config.get('settings/always-use-vm')) this._view.optionVM.setAttribute('checked', '') - elementStateChanged(self._view.optionVMLabel, !this.config.get('settings/always-use-vm')) - - this._view.textWrap = yo`` - this._view.textWrapLabel = yo`` - if (this.config.get('settings/text-wrap')) this._view.textWrap.setAttribute('checked', '') - elementStateChanged(self._view.textWrapLabel, !this.config.get('settings/text-wrap')) - - const warnText = `Transaction sent over Web3 will use the web3.personal API - be sure the endpoint is opened before enabling it. - This mode allows to provide the passphrase in the Remix interface without having to unlock the account. - Although this is very convenient, you should completely trust the backend you are connected to (Geth, Parity, ...). - Remix never persist any passphrase.`.split('\n').map(s => s.trim()).join(' ') - - this._view.personal = yo`` - this._view.warnPersonalMode = yo`` - this._view.personalLabel = yo`` - if (this.config.get('settings/personal-mode')) this._view.personal.setAttribute('checked', '') - elementStateChanged(self._view.personalLabel, !this.config.get('settings/personal-mode')) - - this._view.useMatomoAnalytics = yo`` - this._view.useMatomoAnalyticsLabel = yo` - - ` - if (this.config.get('settings/matomo-analytics')) { - this._view.useMatomoAnalytics.setAttribute('checked', '') - _paq.push(['forgetUserOptOut']) - // @TODO remove next line when https://github.com/matomo-org/matomo/commit/9e10a150585522ca30ecdd275007a882a70c6df5 is used - document.cookie = 'mtm_consent_removed=; expires=Thu, 01 Jan 1970 00:00:01 GMT;' - } else { - _paq.push(['optUserOut']) - } - elementStateChanged(self._view.useMatomoAnalyticsLabel, !this.config.get('settings/matomo-analytics')) - - this._view.generateContractMetadata = yo`` - this._view.generateContractMetadataLabel = yo`` - if (this.config.get('settings/generate-contract-metadata') === undefined) this.config.set('settings/generate-contract-metadata', true) - if (this.config.get('settings/generate-contract-metadata')) this._view.generateContractMetadata.setAttribute('checked', '') - elementStateChanged(self._view.generateContractMetadataLabel, !this.config.get('settings/generate-contract-metadata')) - - this._view.pluginInput = yo`` - - this._view.themes = this._deps.themeModule.getThemes() - this._view.themesCheckBoxes = this.createThemeCheckies() - - this._view.config.general = yo` -
-
-
General settings
-
- ${this._view.generateContractMetadata} - ${this._view.generateContractMetadataLabel} -
-
- ${this._view.optionVM} - ${this._view.optionVMLabel} -
-
- ${this._view.textWrap} - ${this._view.textWrapLabel} -
-
- ${this._view.personal} - ${this._view.personalLabel} -
-
- ${this._view.useMatomoAnalytics} - ${this._view.useMatomoAnalyticsLabel} -
-
-
- ` - this._view.gistToken = yo` -
-
-
Github Access Token
-

Manage the access token used to publish to Gist and retrieve Github contents.

-

Go to github token page (link below) to create a new token and save it in Remix. Make sure this token has only 'create gist' permission.

-

https://github.com/settings/tokens

-
${this._view.gistToken}
-
-
` - this._view.config.themes = yo` -
-
-
Themes
- ${this._view.themesCheckBoxes} -
-
` - this._view.el = yo` -
- ${this._view.config.general} - ${this._view.gistToken} - ${this._view.config.themes} -
` - - function onchangeGenerateContractMetadata (event) { - const isChecked = self.config.get('settings/generate-contract-metadata') - - self.config.set('settings/generate-contract-metadata', !isChecked) - elementStateChanged(self._view.generateContractMetadataLabel, isChecked) - } - - function onchangeOption (event) { - const isChecked = self.config.get('settings/always-use-vm') - - self.config.set('settings/always-use-vm', !isChecked) - elementStateChanged(self._view.optionVMLabel, isChecked) - } - - function textWrapEvent (event) { - const isChecked = self.config.get('settings/text-wrap') - - self.config.set('settings/text-wrap', !isChecked) - elementStateChanged(self._view.textWrapLabel, isChecked) - self.editor.resize(!isChecked) - } - - function onchangePersonal (event) { - const isChecked = self.config.get('settings/personal-mode') - - self.config.set('settings/personal-mode', !isChecked) - elementStateChanged(self._view.personalLabel, isChecked) - } - - function onchangeMatomoAnalytics (event) { - const isChecked = self.config.get('settings/matomo-analytics') - - self.config.set('settings/matomo-analytics', !isChecked) - elementStateChanged(self._view.useMatomoAnalyticsLabel, isChecked) - if (event.target.checked) { - _paq.push(['forgetUserOptOut']) - // @TODO remove next line when https://github.com/matomo-org/matomo/commit/9e10a150585522ca30ecdd275007a882a70c6df5 is used - document.cookie = 'mtm_consent_removed=; expires=Thu, 01 Jan 1970 00:00:01 GMT;' - } else { - _paq.push(['optUserOut']) - } - } - - function elementStateChanged (el, isChanged) { - if (isChanged) { - el.classList.remove('text-dark') - el.classList.add('text-secondary') - } else { - el.classList.add('text-dark') - el.classList.remove('text-secondary') - } - } + return this.element + } - this._deps.themeModule.switchTheme() - return this._view.el + renderComponent () { + ReactDOM.render( + , + this.element + ) } getGithubAccessToken () { diff --git a/libs/remix-ui/clipboard/src/lib/copy-to-clipboard/copy-to-clipboard.tsx b/libs/remix-ui/clipboard/src/lib/copy-to-clipboard/copy-to-clipboard.tsx index 2bea5aed07..fbfdc6dfba 100644 --- a/libs/remix-ui/clipboard/src/lib/copy-to-clipboard/copy-to-clipboard.tsx +++ b/libs/remix-ui/clipboard/src/lib/copy-to-clipboard/copy-to-clipboard.tsx @@ -6,6 +6,7 @@ import './copy-to-clipboard.css' export const CopyToClipboard = ({ content, tip='Copy', icon='fa-copy', ...otherProps }) => { const [message, setMessage] = useState(tip) + const handleClick = (event) => { if (content && content !== '') { // module `copy` keeps last copied thing in the memory, so don't show tooltip if nothing is copied, because nothing was added to memory try { diff --git a/libs/remix-ui/settings/.babelrc b/libs/remix-ui/settings/.babelrc new file mode 100644 index 0000000000..09d67939cc --- /dev/null +++ b/libs/remix-ui/settings/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["@nrwl/react/babel"], + "plugins": [] +} diff --git a/libs/remix-ui/settings/.eslintrc b/libs/remix-ui/settings/.eslintrc new file mode 100644 index 0000000000..dae5c6feeb --- /dev/null +++ b/libs/remix-ui/settings/.eslintrc @@ -0,0 +1,19 @@ +{ + "env": { + "browser": true, + "es6": true + }, + "extends": "../../../.eslintrc", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 11, + "sourceType": "module" + }, + "rules": { + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "error" + } +} diff --git a/libs/remix-ui/settings/README.md b/libs/remix-ui/settings/README.md new file mode 100644 index 0000000000..d4a8337744 --- /dev/null +++ b/libs/remix-ui/settings/README.md @@ -0,0 +1,7 @@ +# remix-ui-settings + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test remix-ui-settings` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/remix-ui/settings/src/index.ts b/libs/remix-ui/settings/src/index.ts new file mode 100644 index 0000000000..432ac58185 --- /dev/null +++ b/libs/remix-ui/settings/src/index.ts @@ -0,0 +1 @@ +export * from './lib/remix-ui-settings' diff --git a/libs/remix-ui/settings/src/lib/constants.ts b/libs/remix-ui/settings/src/lib/constants.ts new file mode 100644 index 0000000000..4d6d2a06de --- /dev/null +++ b/libs/remix-ui/settings/src/lib/constants.ts @@ -0,0 +1,12 @@ +export const generateContractMetadataText = 'Generate contract metadata. Generate a JSON file in the contract folder. Allows to specify library addresses the contract depends on. If nothing is specified, Remix deploys libraries automatically.' +export const textSecondary = 'text-secondary' +export const textDark = 'text-dark' +export const warnText = 'Be sure the endpoint is opened before enabling it. \nThis mode allows a user to provide a passphrase in the Remix interface without having to unlock the account. Although this is very convenient, you should completely trust the backend you are connected to (Geth, Parity, ...). Remix never persists any passphrase'.split('\n').map(s => s.trim()).join(' ') +export const gitAccessTokenTitle = 'Github Access Token' +export const gitAccessTokenText = 'Manage the access token used to publish to Gist and retrieve Github contents.' +export const gitAccessTokenText2 = 'Go to github token page (link below) to create a new token and save it in Remix. Make sure this token has only \'create gist\' permission.' +export const gitAccessTokenLink = 'https://github.com/settings/tokens' +export const ethereunVMText = 'Always use Ethereum VM at load' +export const wordWrapText = 'Word wrap in editor' +export const enablePersonalModeText = ' Enable Personal Mode for web3 provider. Transaction sent over Web3 will use the web3.personal API.\n' +export const matomoAnalytics = 'Enable Matomo Analytics. We do not collect personally identifiable information (PII). The info is used to improve the site’s UX & UI. See more about ' diff --git a/libs/remix-ui/settings/src/lib/remix-ui-settings.css b/libs/remix-ui/settings/src/lib/remix-ui-settings.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx new file mode 100644 index 0000000000..ef8c3ed6c5 --- /dev/null +++ b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx @@ -0,0 +1,166 @@ +import React, { useState, useReducer, useEffect, useCallback } from 'react' // eslint-disable-line +import { CopyToClipboard } from '@remix-ui/clipboard' // eslint-disable-line + +import { enablePersonalModeText, ethereunVMText, generateContractMetadataText, gitAccessTokenLink, gitAccessTokenText, gitAccessTokenText2, gitAccessTokenTitle, matomoAnalytics, textDark, textSecondary, warnText, wordWrapText } from './constants' + +import './remix-ui-settings.css' +import { etherumVM, generateContractMetadat, personal, textWrapEventAction, useMatomoAnalytics, saveTokenToast, removeTokenToast } from './settingsAction' +import { initialState, toastInitialState, toastReducer, settingReducer } from './settingsReducer' +import { Toaster } from '@remix-ui/toaster'// eslint-disable-line + +/* eslint-disable-next-line */ +export interface RemixUiSettingsProps { + config: any, + editor: any, + _deps: any +} + +export const RemixUiSettings = (props: RemixUiSettingsProps) => { + const [, dispatch] = useReducer(settingReducer, initialState) + const [state, dispatchToast] = useReducer(toastReducer, toastInitialState) + const [tokenValue, setTokenValue] = useState('') + const [themeName, setThemeName] = useState('') + + useEffect(() => { + const token = props.config.get('settings/gist-access-token') + if (token === undefined) { + props.config.set('settings/generate-contract-metadata', true) + dispatch({ type: 'contractMetadata', payload: { name: 'contractMetadata', isChecked: true, textClass: textDark } }) + } + if (token) { + setTokenValue(token) + } + }, [themeName, state.message]) + + const onchangeGenerateContractMetadata = (event) => { + generateContractMetadat(props, event, dispatch) + } + + const onchangeOption = (event) => { + etherumVM(props, event, dispatch) + } + + const textWrapEvent = (event) => { + textWrapEventAction(props, event, dispatch) + } + + const onchangePersonal = event => { + personal(props, event, dispatch) + } + + const onchangeMatomoAnalytics = event => { + useMatomoAnalytics(props, event, dispatch) + } + + const onswitchTheme = (event, name) => { + props._deps.themeModule.switchTheme(name) + setThemeName(name) + } + + const getTextClass = (key) => { + if (props.config.get(key)) { + return textDark + } else { + return textSecondary + } + } + + const generalConfig = () => ( +
+
+
General settings
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ ) + + const saveToken = () => { + saveTokenToast(props, dispatchToast, tokenValue) + } + + const removeToken = () => { + setTokenValue('') + removeTokenToast(props, dispatchToast) + } + + const handleSaveTokenState = useCallback( + (event) => { + setTokenValue(event.target.value) + }, + [tokenValue] + ) + + const gistToken = () => ( +
+
+
{ gitAccessTokenTitle }
+

{ gitAccessTokenText }

+

{ gitAccessTokenText2 }

+

{ gitAccessTokenLink }

+
+
+ +
+ + saveToken()} value="Save" type="button" disabled={tokenValue === ''}> + +
+
+
+
+ ) + + const themes = () => { + const themes = props._deps.themeModule.getThemes() + if (themes) { + return themes.map((aTheme, index) => ( +
+ { onswitchTheme(event, aTheme.name) }} className="align-middle custom-control-input" name='theme' id={aTheme.name} data-id={`settingsTabTheme${aTheme.name}`} checked = {props._deps.themeModule.active === aTheme.name ? true : null}/> + +
+ ) + ) + } + } + + return ( +
+ {state.message ? : null} + {generalConfig()} + {gistToken()} +
+
+
Themes
+
+ {themes()} +
+
+
+
+ ) +} diff --git a/libs/remix-ui/settings/src/lib/settingsAction.ts b/libs/remix-ui/settings/src/lib/settingsAction.ts new file mode 100644 index 0000000000..055c84449b --- /dev/null +++ b/libs/remix-ui/settings/src/lib/settingsAction.ts @@ -0,0 +1,52 @@ +import { textDark, textSecondary } from './constants' + +declare global { + interface Window { + _paq: any + } +} + +const _paq = window._paq = window._paq || [] //eslint-disable-line + +export const generateContractMetadat = (element, event, dispatch) => { + element.config.set('settings/generate-contract-metadata', event.target.checked) + dispatch({ type: 'contractMetadata', payload: { name: event.target.name, isChecked: event.target.checked, textClass: event.target.checked ? textDark : textSecondary } }) +} + +export const etherumVM = (element, event, dispatch) => { + element.config.set('settings/always-use-vm', event.target.checked) + dispatch({ type: 'ethereumVM', payload: { name: event.target.name, isChecked: event.target.checked, textClass: event.target.checked ? textDark : textSecondary } }) +} + +export const textWrapEventAction = (element, event, dispatch) => { + element.config.set('settings/text-wrap', event.target.checked) + element.editor.resize(event.target.checked) + dispatch({ type: 'textWrap', payload: { name: event.target.name, isChecked: event.target.checked, textClass: event.target.checked ? textDark : textSecondary } }) +} + +export const personal = (element, event, dispatch) => { + element.config.set('settings/personal-mode', event.target.checked) + dispatch({ type: 'personal', payload: { name: event.target.name, isChecked: event.target.checked, textClass: event.target.checked ? textDark : textSecondary } }) +} + +export const useMatomoAnalytics = (element, event, dispatch) => { + element.config.set('settings/matomo-analytics', event.target.checked) + dispatch({ type: 'useMatomoAnalytics', payload: { name: event.target.name, isChecked: event.target.checked, textClass: event.target.checked ? textDark : textSecondary } }) + if (event.target.checked) { + _paq.push(['forgetUserOptOut']) + // @TODO remove next line when https://github.com/matomo-org/matomo/commit/9e10a150585522ca30ecdd275007a882a70c6df5 is used + document.cookie = 'mtm_consent_removed=; expires=Thu, 01 Jan 1970 00:00:01 GMT;' + } else { + _paq.push(['optUserOut']) + } +} + +export const saveTokenToast = (props, dispatch, tokenValue) => { + props.config.set('settings/gist-access-token', tokenValue) + dispatch({ type: 'save', payload: { message: 'Access token has been saved' } }) +} + +export const removeTokenToast = (props, dispatch) => { + props.config.set('settings/gist-access-token', '') + dispatch({ type: 'removed', payload: { message: 'Access token removed' } }) +} diff --git a/libs/remix-ui/settings/src/lib/settingsReducer.ts b/libs/remix-ui/settings/src/lib/settingsReducer.ts new file mode 100644 index 0000000000..daf6453959 --- /dev/null +++ b/libs/remix-ui/settings/src/lib/settingsReducer.ts @@ -0,0 +1,103 @@ +import { textSecondary } from './constants' + +export const initialState = { + elementState: [ + { + name: 'contractMetadata', + isChecked: false, + textClass: textSecondary + }, + { + name: 'ethereumVM', + isChecked: false, + textClass: textSecondary + }, + { + name: 'textWrap', + isChecked: false, + textClass: textSecondary + }, + { + name: 'personal', + isChecked: false, + textClass: textSecondary + }, + { + name: 'useMatomoAnalytics', + isChecked: false, + textClass: textSecondary + } + ] +} + +export const settingReducer = (state, action) => { + switch (action.type) { + case 'contractMetadata': + state.elementState.map(element => { + if (element.name === 'contractMetadata') { + element.isChecked = action.payload.isChecked + element.textClass = action.payload.textClass + } + }) + return { + ...state + } + case 'ethereumVM': + state.elementState.map(element => { + if (element.name === 'ethereumVM') { + element.isChecked = action.payload.isChecked + element.textClass = action.payload.textClass + } + }) + return { + ...state + } + case 'textWrap': + state.elementState.map(element => { + if (element.name === 'textWrap') { + element.isChecked = action.payload.isChecked + element.textClass = action.payload.textClass + } + }) + return { + ...state + } + case 'personal': + state.elementState.map(element => { + if (element.name === 'personal') { + element.isChecked = action.payload.isChecked + element.textClass = action.payload.textClass + } + }) + return { + ...state + } + case 'useMatomoAnalytics': + state.elementState.map(element => { + if (element.name === 'useMatomoAnalytics') { + element.isChecked = action.payload.isChecked + element.textClass = action.payload.textClass + } + }) + return { + ...state + } + default: + return initialState + } +} + +export const toastInitialState = { + message: '' +} + +export const toastReducer = (state, action) => { + switch (action.type) { + case 'save' : + return { ...state, message: action.payload.message } + case 'removed' : + return { ...state, message: action.payload.message } + default : + return { ...state, message: '' } + } +} diff --git a/libs/remix-ui/settings/tsconfig.json b/libs/remix-ui/settings/tsconfig.json new file mode 100644 index 0000000000..6b65264565 --- /dev/null +++ b/libs/remix-ui/settings/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "jsx": "react", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} diff --git a/libs/remix-ui/settings/tsconfig.lib.json b/libs/remix-ui/settings/tsconfig.lib.json new file mode 100644 index 0000000000..b560bc4dec --- /dev/null +++ b/libs/remix-ui/settings/tsconfig.lib.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": ["node"] + }, + "files": [ + "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", + "../../../node_modules/@nrwl/react/typings/image.d.ts" + ], + "exclude": ["**/*.spec.ts", "**/*.spec.tsx"], + "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] +} diff --git a/nx.json b/nx.json index a63c015d64..64d8dcaeaf 100644 --- a/nx.json +++ b/nx.json @@ -96,11 +96,17 @@ "remix-ui-workspace": { "tags": [] }, + "remix-ui-settings": { + "tags": [] + }, "remix-ui-static-analyser": { "tags": [] }, "remix-ui-checkbox": { "tags": [] + }, + "remix-ui-settings": { + "tags": [] } } } diff --git a/package.json b/package.json index 07ab9d39e1..e238787d68 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "workspace-schematic": "nx workspace-schematic", "dep-graph": "nx dep-graph", "help": "nx help", - "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox", + "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings", "build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "publish:libs": "npm run build:libs && lerna publish --skip-git && npm run bumpVersion:libs", diff --git a/tsconfig.json b/tsconfig.json index 75db5bc6ff..573a63975e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -39,8 +39,10 @@ "@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"], "@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"], "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"], + "@remix-ui/settings": ["libs/remix-ui/settings/src/index.ts"], "@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"], - "@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"] + "@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"], + "@remix-ui/settings": ["libs/remix-ui/settings/src/index.ts"] } }, "exclude": ["node_modules", "tmp"] diff --git a/workspace.json b/workspace.json index 5d2bf912c0..04da7184e5 100644 --- a/workspace.json +++ b/workspace.json @@ -726,6 +726,22 @@ } } }, + "remix-ui-settings": { + "root": "libs/remix-ui/settings", + "sourceRoot": "libs/remix-ui/settings/src", + "projectType": "library", + "schematics": {}, + "architect": { + "lint": { + "builder": "@nrwl/linter:lint", + "options": { + "linter": "eslint", + "tsConfig": ["libs/remix-ui/settings/tsconfig.lib.json"], + "exclude": ["**/node_modules/**", "!libs/remix-ui/settings/**/*"] + } + } + } + }, "remix-ui-static-analyser": { "root": "libs/remix-ui/static-analyser", "sourceRoot": "libs/remix-ui/static-analyser/src", @@ -828,4 +844,4 @@ } }, "defaultProject": "remix-ide" -} +} \ No newline at end of file From a2f7af4f464a75ef024dddc4cb92739559d35b9f Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 25 Jun 2021 10:36:26 +0200 Subject: [PATCH 25/51] don't set a current fork if injected or web3 is used --- apps/remix-ide/src/blockchain/execution-context.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/apps/remix-ide/src/blockchain/execution-context.js b/apps/remix-ide/src/blockchain/execution-context.js index 352a689df3..0e1debeb2b 100644 --- a/apps/remix-ide/src/blockchain/execution-context.js +++ b/apps/remix-ide/src/blockchain/execution-context.js @@ -21,8 +21,7 @@ export class ExecutionContext { this.executionContext = null this.blockGasLimitDefault = 4300000 this.blockGasLimit = this.blockGasLimitDefault - this.defaultFork = 'berlin' - this.currentFork = this.defaultFork + this.currentFork = ' - ' this.mainNetGenesisHash = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' this.customNetWorks = {} this.blocks = {} @@ -125,18 +124,17 @@ export class ExecutionContext { executionContextChange (value, endPointUrl, confirmCb, infoCb, cb) { const context = value.context - const fork = value.fork || this.defaultFork if (!cb) cb = () => {} if (!confirmCb) confirmCb = () => {} if (!infoCb) infoCb = () => {} if (context === 'vm') { this.executionContext = context - this.currentFork = fork + this.currentFork = value.fork this.event.trigger('contextChanged', ['vm']) return cb() } - this.currentFork = this.defaultFork // in the case of injected and web3, we default to the last fork. + this.currentFork = ' - ' if (context === 'injected') { if (injectedProvider === undefined) { From edc7b95498a8a1a2699d26fa2833eca2633765b7 Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 25 Jun 2021 10:42:41 +0200 Subject: [PATCH 26/51] remove uneeded default value --- libs/remix-simulator/src/vm-context.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libs/remix-simulator/src/vm-context.ts b/libs/remix-simulator/src/vm-context.ts index e0a3aef849..a7e766c6ba 100644 --- a/libs/remix-simulator/src/vm-context.ts +++ b/libs/remix-simulator/src/vm-context.ts @@ -91,7 +91,6 @@ export class VMContext { blocks latestBlockNumber txs - defaultFork currentVm web3vm logsManager @@ -100,8 +99,7 @@ export class VMContext { constructor (fork?) { this.blockGasLimitDefault = 4300000 this.blockGasLimit = this.blockGasLimitDefault - this.defaultFork = fork || 'berlin' - this.currentFork = this.defaultFork + this.currentFork = fork this.currentVm = this.createVm(this.currentFork) this.blocks = {} this.latestBlockNumber = 0 From cab3b42823dc59b448bce87513125cf9b9cbaaf6 Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 25 Jun 2021 10:43:00 +0200 Subject: [PATCH 27/51] add London to Solidity EVM version --- libs/remix-solidity/src/compiler/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-solidity/src/compiler/types.ts b/libs/remix-solidity/src/compiler/types.ts index e10e99e52f..75091f366b 100644 --- a/libs/remix-solidity/src/compiler/types.ts +++ b/libs/remix-solidity/src/compiler/types.ts @@ -150,7 +150,7 @@ export interface CompilerInputOptions { language?: Language } -export type EVMVersion = 'homestead' | 'tangerineWhistle' | 'spuriousDragon' | 'byzantium' | 'constantinople' | 'petersburg' | 'istanbul' | 'muirGlacier' | 'berlin' | null +export type EVMVersion = 'homestead' | 'tangerineWhistle' | 'spuriousDragon' | 'byzantium' | 'constantinople' | 'petersburg' | 'istanbul' | 'muirGlacier' | 'berlin' | 'london' | null export type Language = 'Solidity' | 'Yul' From 6f1bfaf3792f94a50198d1e4a5473594127ab0af Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 25 Jun 2021 12:36:52 +0200 Subject: [PATCH 28/51] allow debugging various fork --- apps/debugger/src/app/debugger-api.ts | 3 +- .../src/blockchain/execution-context.js | 22 ++-- libs/remix-debug/src/Ethdebugger.ts | 4 +- libs/remix-debug/src/debugger/debugger.ts | 3 +- libs/remix-debug/src/trace/traceManager.ts | 12 +- libs/remix-lib/src/execution/forkAt.ts | 121 ++++++++++++++++++ libs/remix-lib/src/index.ts | 4 +- .../debugger-ui/src/lib/debugger-ui.tsx | 3 +- 8 files changed, 153 insertions(+), 19 deletions(-) create mode 100644 libs/remix-lib/src/execution/forkAt.ts diff --git a/apps/debugger/src/app/debugger-api.ts b/apps/debugger/src/app/debugger-api.ts index e1b66a3d48..0f99518e78 100644 --- a/apps/debugger/src/app/debugger-api.ts +++ b/apps/debugger/src/app/debugger-api.ts @@ -111,8 +111,7 @@ export const DebuggerApiMixin = (Base) => class extends Base { } return null }, - debugWithGeneratedSources: false, - fork: 'berlin' + debugWithGeneratedSources: false }) return await debug.debugger.traceManager.getTrace(hash) } diff --git a/apps/remix-ide/src/blockchain/execution-context.js b/apps/remix-ide/src/blockchain/execution-context.js index 0e1debeb2b..b6a988e915 100644 --- a/apps/remix-ide/src/blockchain/execution-context.js +++ b/apps/remix-ide/src/blockchain/execution-context.js @@ -1,6 +1,7 @@ /* global ethereum */ 'use strict' import Web3 from 'web3' +import { execution } from '@remix-project/remix-lib' import EventManager from '../lib/events' let web3 @@ -21,7 +22,7 @@ export class ExecutionContext { this.executionContext = null this.blockGasLimitDefault = 4300000 this.blockGasLimit = this.blockGasLimitDefault - this.currentFork = ' - ' + this.currentFork = 'berlin' this.mainNetGenesisHash = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' this.customNetWorks = {} this.blocks = {} @@ -134,8 +135,6 @@ export class ExecutionContext { return cb() } - this.currentFork = ' - ' - if (context === 'injected') { if (injectedProvider === undefined) { infoCb('No injected Web3 provider found. Make sure your provider (e.g. MetaMask) is active and running (when recently activated you may have to reload the page).') @@ -144,7 +143,7 @@ export class ExecutionContext { this.askPermission() this.executionContext = context web3.setProvider(injectedProvider) - this._updateBlockGasLimit() + this._updateChainContext() this.event.trigger('contextChanged', ['injected']) return cb() } @@ -171,12 +170,19 @@ export class ExecutionContext { this.listenOnLastBlockId = null } - _updateBlockGasLimit () { + _updateChainContext () { if (this.getProvider() !== 'vm') { - web3.eth.getBlock('latest', (err, block) => { + web3.eth.getBlock('latest', async (err, block) => { if (!err) { // we can't use the blockGasLimit cause the next blocks could have a lower limit : https://github.com/ethereum/remix/issues/506 this.blockGasLimit = (block && block.gasLimit) ? Math.floor(block.gasLimit - (5 * block.gasLimit) / 1024) : this.blockGasLimitDefault + try { + this.currentFork = execution.forkAt(await web3.eth.net.getId(), block.number) + } catch (e) { + this.currentFork = 'berlin' + console.log(`unable to detect fork, defaulting to ${this.currentFork}..`) + console.error(e) + } } else { this.blockGasLimit = this.blockGasLimitDefault } @@ -186,7 +192,7 @@ export class ExecutionContext { listenOnLastBlock () { this.listenOnLastBlockId = setInterval(() => { - this._updateBlockGasLimit() + this._updateChainContext() }, 15000) } @@ -200,7 +206,7 @@ export class ExecutionContext { web3.eth.net.isListening((err, isConnected) => { if (!err && isConnected === true) { this.executionContext = context - this._updateBlockGasLimit() + this._updateChainContext() this.event.trigger('contextChanged', [context]) this.event.trigger('web3EndpointChanged') cb() diff --git a/libs/remix-debug/src/Ethdebugger.ts b/libs/remix-debug/src/Ethdebugger.ts index 4c023c6028..3c492e1812 100644 --- a/libs/remix-debug/src/Ethdebugger.ts +++ b/libs/remix-debug/src/Ethdebugger.ts @@ -41,7 +41,7 @@ export class Ethdebugger { this.opts = opts this.event = new EventManager() - this.traceManager = new TraceManager({ web3: this.web3, fork: this.opts.fork }) + this.traceManager = new TraceManager({ web3: this.web3 }) this.codeManager = new CodeManager(this.traceManager) this.solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: this.traceManager.getCurrentCalledAddressAt.bind(this.traceManager), getCode: this.codeManager.getCode.bind(this.codeManager) }) this.storageResolver = null @@ -55,7 +55,7 @@ export class Ethdebugger { } setManagers () { - this.traceManager = new TraceManager({ web3: this.web3, fork: this.opts.fork }) + this.traceManager = new TraceManager({ web3: this.web3 }) this.codeManager = new CodeManager(this.traceManager) this.solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: this.traceManager.getCurrentCalledAddressAt.bind(this.traceManager), getCode: this.codeManager.getCode.bind(this.codeManager) }) this.storageResolver = null diff --git a/libs/remix-debug/src/debugger/debugger.ts b/libs/remix-debug/src/debugger/debugger.ts index 76d28746bd..11395026b3 100644 --- a/libs/remix-debug/src/debugger/debugger.ts +++ b/libs/remix-debug/src/debugger/debugger.ts @@ -26,8 +26,7 @@ export class Debugger { this.debugger = new Ethdebugger({ web3: options.web3, debugWithGeneratedSources: options.debugWithGeneratedSources, - compilationResult: this.compilationResult, - fork: options.fork + compilationResult: this.compilationResult }) const { traceManager, callTree, solidityProxy } = this.debugger diff --git a/libs/remix-debug/src/trace/traceManager.ts b/libs/remix-debug/src/trace/traceManager.ts index d3f3861e0f..8e78782922 100644 --- a/libs/remix-debug/src/trace/traceManager.ts +++ b/libs/remix-debug/src/trace/traceManager.ts @@ -1,9 +1,9 @@ 'use strict' +import { util, execution } from '@remix-project/remix-lib' import { TraceAnalyser } from './traceAnalyser' import { TraceCache } from './traceCache' import { TraceStepManager } from './traceStepManager' import { isCreateInstruction } from './traceHelper' -import { util } from '@remix-project/remix-lib' export class TraceManager { web3 @@ -17,7 +17,6 @@ export class TraceManager { constructor (options) { this.web3 = options.web3 - this.fork = options.fork this.isLoading = false this.trace = null this.traceCache = new TraceCache() @@ -37,6 +36,15 @@ export class TraceManager { if (result['structLogs'].length > 0) { this.trace = result['structLogs'] + try { + const networkId = await this.web3.eth.net.getId() + this.fork = execution.forkAt(networkId, tx.blockNumber) + } catch (e) { + this.fork = 'berlin' + console.log(`unable to detect fork, defaulting to ${this.fork}..`) + console.error(e) + } + this.traceAnalyser.analyse(result['structLogs'], tx) this.isLoading = false return true diff --git a/libs/remix-lib/src/execution/forkAt.ts b/libs/remix-lib/src/execution/forkAt.ts new file mode 100644 index 0000000000..5c4316f868 --- /dev/null +++ b/libs/remix-lib/src/execution/forkAt.ts @@ -0,0 +1,121 @@ +'use strict' + +/** + * returns the fork name for the @argument networkId and @argument blockNumber + * + * @param {Object} networkId - network Id (1 for VM, 3 for Ropsten, 4 for Rinkeby, 5 for Goerli) + * @param {Object} blockNumber - block number + * @return {String} - fork name (Berlin, Istanbul, ...) + */ +export function forkAt (networkId, blockNumber) { + if (forks[networkId]) { + let currentForkName = forks[networkId][0].name + for (const fork of forks[networkId]) { + if (blockNumber >= fork.number) { + currentForkName = fork.name + } + } + return currentForkName + } + return 'berlin' +} + +// see https://github.com/ethereum/go-ethereum/blob/master/params/config.go +const forks = { + 1: [ + { + number: 4370000, + name: 'byzantium' + }, + { + number: 7280000, + name: 'constantinople' + }, + { + number: 7280000, + name: 'petersburg' + }, + { + number: 9069000, + name: 'istanbul' + }, + { + number: 9200000, + name: 'muirglacier' + }, + { + number: 12244000, + name: 'berlin' + } + ], + 3: [ + { + number: 1700000, + name: 'byzantium' + }, + { + number: 4230000, + name: 'constantinople' + }, + { + number: 4939394, + name: 'petersburg' + }, + { + number: 6485846, + name: 'istanbul' + }, + { + number: 7117117, + name: 'muirglacier' + }, + { + number: 9812189, + name: 'berlin' + }, + { + number: 10499401, + name: 'london' + } + ], + 4: [ + { + number: 1035301, + name: 'byzantium' + }, + { + number: 3660663, + name: 'constantinople' + }, + { + number: 4321234, + name: 'petersburg' + }, + { + number: 5435345, + name: 'istanbul' + }, + { + number: 8290928, + name: 'berlin' + }, + { + number: 8897988, + name: 'london' + } + ], + 5: [ + { + number: 1561651, + name: 'istanbul' + }, + { + number: 4460644, + name: 'berlin' + }, + { + number: 5062605, + name: 'london' + } + ] +} diff --git a/libs/remix-lib/src/index.ts b/libs/remix-lib/src/index.ts index ae3864a8c9..d3d37231f1 100644 --- a/libs/remix-lib/src/index.ts +++ b/libs/remix-lib/src/index.ts @@ -13,6 +13,7 @@ import * as txFormat from './execution/txFormat' import { TxListener } from './execution/txListener' import { TxRunner } from './execution/txRunner' import { LogsManager } from './execution/logsManager' +import { forkAt } from './execution/forkAt' import * as typeConversion from './execution/typeConversion' import { TxRunnerVM } from './execution/txRunnerVM' import { TxRunnerWeb3 } from './execution/txRunnerWeb3' @@ -45,7 +46,8 @@ function modules () { TxRunnerWeb3: TxRunnerWeb3, TxRunnerVM: TxRunnerVM, typeConversion: typeConversion, - LogsManager + LogsManager, + forkAt } } } diff --git a/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx b/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx index 78ec2de174..af3648aa90 100644 --- a/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx @@ -208,8 +208,7 @@ export const DebuggerUI = (props: DebuggerUIProps) => { } return null }, - debugWithGeneratedSources: state.opt.debugWithGeneratedSources, - fork: 'berlin' + debugWithGeneratedSources: state.opt.debugWithGeneratedSources }) debuggerInstance.debug(blockNumber, txNumber, tx, () => { From 4ddba6b228d0ee1e2a5f2d02f6526acf9ba76b5b Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 28 Jun 2021 17:39:19 +0200 Subject: [PATCH 29/51] remix-simulator default to last fork --- libs/remix-simulator/src/vm-context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-simulator/src/vm-context.ts b/libs/remix-simulator/src/vm-context.ts index a7e766c6ba..363e9ab50e 100644 --- a/libs/remix-simulator/src/vm-context.ts +++ b/libs/remix-simulator/src/vm-context.ts @@ -99,7 +99,7 @@ export class VMContext { constructor (fork?) { this.blockGasLimitDefault = 4300000 this.blockGasLimit = this.blockGasLimitDefault - this.currentFork = fork + this.currentFork = fork || 'berlin' this.currentVm = this.createVm(this.currentFork) this.blocks = {} this.latestBlockNumber = 0 From 43029b7462f7c9a27e915be2877369d7ee32ed47 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 30 Jun 2021 11:28:40 +0200 Subject: [PATCH 30/51] Make sure current fork is set before continuing (#1340) --- .../src/blockchain/execution-context.js | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/apps/remix-ide/src/blockchain/execution-context.js b/apps/remix-ide/src/blockchain/execution-context.js index b6a988e915..f29d0ec0d4 100644 --- a/apps/remix-ide/src/blockchain/execution-context.js +++ b/apps/remix-ide/src/blockchain/execution-context.js @@ -123,7 +123,7 @@ export class ExecutionContext { this.executionContextChange(context, endPointUrl, confirmCb, infoCb, null) } - executionContextChange (value, endPointUrl, confirmCb, infoCb, cb) { + async executionContextChange (value, endPointUrl, confirmCb, infoCb, cb) { const context = value.context if (!cb) cb = () => {} if (!confirmCb) confirmCb = () => {} @@ -143,7 +143,7 @@ export class ExecutionContext { this.askPermission() this.executionContext = context web3.setProvider(injectedProvider) - this._updateChainContext() + await this._updateChainContext() this.event.trigger('contextChanged', ['injected']) return cb() } @@ -170,23 +170,23 @@ export class ExecutionContext { this.listenOnLastBlockId = null } - _updateChainContext () { + async _updateChainContext () { if (this.getProvider() !== 'vm') { - web3.eth.getBlock('latest', async (err, block) => { - if (!err) { - // we can't use the blockGasLimit cause the next blocks could have a lower limit : https://github.com/ethereum/remix/issues/506 - this.blockGasLimit = (block && block.gasLimit) ? Math.floor(block.gasLimit - (5 * block.gasLimit) / 1024) : this.blockGasLimitDefault - try { - this.currentFork = execution.forkAt(await web3.eth.net.getId(), block.number) - } catch (e) { - this.currentFork = 'berlin' - console.log(`unable to detect fork, defaulting to ${this.currentFork}..`) - console.error(e) - } - } else { - this.blockGasLimit = this.blockGasLimitDefault + try { + const block = await web3.eth.getBlock('latest') + // we can't use the blockGasLimit cause the next blocks could have a lower limit : https://github.com/ethereum/remix/issues/506 + this.blockGasLimit = (block && block.gasLimit) ? Math.floor(block.gasLimit - (5 * block.gasLimit) / 1024) : this.blockGasLimitDefault + try { + this.currentFork = execution.forkAt(await web3.eth.net.getId(), block.number) + } catch (e) { + this.currentFork = 'berlin' + console.log(`unable to detect fork, defaulting to ${this.currentFork}..`) + console.error(e) } - }) + } catch (e) { + console.error(e) + this.blockGasLimit = this.blockGasLimitDefault + } } } From c8bc5ae3be6bef030b27df327d046915729a71e2 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 22 Jun 2021 15:39:57 +0530 Subject: [PATCH 31/51] fix hardhat modal reappearing --- apps/remix-ide/src/app/tabs/hardhat-provider.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/hardhat-provider.js b/apps/remix-ide/src/app/tabs/hardhat-provider.js index 037117fa85..88fe3b7c85 100644 --- a/apps/remix-ide/src/app/tabs/hardhat-provider.js +++ b/apps/remix-ide/src/app/tabs/hardhat-provider.js @@ -39,12 +39,17 @@ export default class HardhatProvider extends Plugin { sendAsync (data) { return new Promise((resolve, reject) => { - if (!this.provider) { + if (!this.provider || data.method === 'net_listening') { modalDialogCustom.prompt('Hardhat node request', this.hardhatProviderDialogBody(), 'http://127.0.0.1:8545', (target) => { this.provider = new Web3.providers.HttpProvider(target) this.sendAsyncInternal(data, resolve, reject) }, () => { - this.sendAsyncInternal(data, resolve, reject) + if (data.method === 'net_listening') resolve({ jsonrpc: '2.0', result: 'canceled', id: data.id }) + else { + this.blockchain.changeExecutionContext('vm') + this.provider = this.blockchain.getCurrentProvider() + reject(new Error('Connection canceled')) + } }) } else { this.sendAsyncInternal(data, resolve, reject) @@ -62,8 +67,7 @@ export default class HardhatProvider extends Plugin { resolve(message) }) } else { - const result = data.method === 'net_listening' ? 'canceled' : [] - resolve({ jsonrpc: '2.0', result: result, id: data.id }) + resolve({ jsonrpc: '2.0', result: [], id: data.id }) } } } From 5ec31dd89a95d431b2489be857bec41e6e1720c3 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 22 Jun 2021 16:04:45 +0530 Subject: [PATCH 32/51] specific error on tooltip --- apps/remix-ide/src/app/tabs/hardhat-provider.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/remix-ide/src/app/tabs/hardhat-provider.js b/apps/remix-ide/src/app/tabs/hardhat-provider.js index 88fe3b7c85..8c2cd0ae05 100644 --- a/apps/remix-ide/src/app/tabs/hardhat-provider.js +++ b/apps/remix-ide/src/app/tabs/hardhat-provider.js @@ -59,6 +59,9 @@ export default class HardhatProvider extends Plugin { sendAsyncInternal (data, resolve, reject) { if (this.provider) { + // Check the case where current environment is VM on UI and it still sends RPC requests + // This will be displayed on UI tooltip as 'cannot get account list: Environment Updated !!' + if (this.blockchain.getProvider() !== 'Hardhat Provider' && data.method !== 'net_listening') return reject(new Error('Environment Updated !!')) this.provider[this.provider.sendAsync ? 'sendAsync' : 'send'](data, (error, message) => { if (error) { this.provider = null From 33d7115d4e326c1192e0cb996aa9ab4b9d131578 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 22 Jun 2021 19:02:01 +0530 Subject: [PATCH 33/51] comments --- apps/remix-ide/src/app/tabs/hardhat-provider.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/remix-ide/src/app/tabs/hardhat-provider.js b/apps/remix-ide/src/app/tabs/hardhat-provider.js index 8c2cd0ae05..0676d199d3 100644 --- a/apps/remix-ide/src/app/tabs/hardhat-provider.js +++ b/apps/remix-ide/src/app/tabs/hardhat-provider.js @@ -39,13 +39,17 @@ export default class HardhatProvider extends Plugin { sendAsync (data) { return new Promise((resolve, reject) => { + // If provider is not set, allow to open modal only when provider is trying to connect if (!this.provider || data.method === 'net_listening') { modalDialogCustom.prompt('Hardhat node request', this.hardhatProviderDialogBody(), 'http://127.0.0.1:8545', (target) => { this.provider = new Web3.providers.HttpProvider(target) this.sendAsyncInternal(data, resolve, reject) }, () => { + // If 'cancel' is clicked while trying to connect, handle it in custom manner if (data.method === 'net_listening') resolve({ jsonrpc: '2.0', result: 'canceled', id: data.id }) else { + // When node is abruptly stopped, modal will appear + // On which clicking on 'Cancel' will set the Envrionment to VM this.blockchain.changeExecutionContext('vm') this.provider = this.blockchain.getCurrentProvider() reject(new Error('Connection canceled')) From c36bd1d271720daab521ab479d3e85904c9a6d8e Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 22 Jun 2021 19:20:13 +0530 Subject: [PATCH 34/51] added info in modal --- apps/remix-ide/src/app/tabs/hardhat-provider.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/remix-ide/src/app/tabs/hardhat-provider.js b/apps/remix-ide/src/app/tabs/hardhat-provider.js index 0676d199d3..ec43d72ffc 100644 --- a/apps/remix-ide/src/app/tabs/hardhat-provider.js +++ b/apps/remix-ide/src/app/tabs/hardhat-provider.js @@ -32,12 +32,16 @@ export default class HardhatProvider extends Plugin {
For more info, visit: Hardhat Documentation

+ Note: Click on 'Cancel' if node is stopped. +

Hardhat JSON-RPC Endpoint
` } sendAsync (data) { + console.log('data in sendAsync-->', data) + console.log('provider in sendAsync-->', this.provider) return new Promise((resolve, reject) => { // If provider is not set, allow to open modal only when provider is trying to connect if (!this.provider || data.method === 'net_listening') { From 331f02c1a3a1e12aff128504366c060b2a138e2b Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 22 Jun 2021 19:22:01 +0530 Subject: [PATCH 35/51] consoles removed --- apps/remix-ide/src/app/tabs/hardhat-provider.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/hardhat-provider.js b/apps/remix-ide/src/app/tabs/hardhat-provider.js index ec43d72ffc..43fc613624 100644 --- a/apps/remix-ide/src/app/tabs/hardhat-provider.js +++ b/apps/remix-ide/src/app/tabs/hardhat-provider.js @@ -40,8 +40,6 @@ export default class HardhatProvider extends Plugin { } sendAsync (data) { - console.log('data in sendAsync-->', data) - console.log('provider in sendAsync-->', this.provider) return new Promise((resolve, reject) => { // If provider is not set, allow to open modal only when provider is trying to connect if (!this.provider || data.method === 'net_listening') { From 07e7d4789961d2a73d0225538ac99fa16cbd9720 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 28 Jun 2021 16:29:16 +0200 Subject: [PATCH 36/51] temporarily block provider --- .../src/app/tabs/hardhat-provider.js | 22 +++++++++---------- apps/remix-ide/src/remixAppManager.js | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/hardhat-provider.js b/apps/remix-ide/src/app/tabs/hardhat-provider.js index 43fc613624..fa99969d20 100644 --- a/apps/remix-ide/src/app/tabs/hardhat-provider.js +++ b/apps/remix-ide/src/app/tabs/hardhat-provider.js @@ -1,6 +1,7 @@ import * as packageJson from '../../../../../package.json' import { Plugin } from '@remixproject/engine' import Web3 from 'web3' +import toaster from '../ui/tooltip' const yo = require('yo-yo') const modalDialogCustom = require('../ui/modal-dialog-custom') @@ -17,11 +18,13 @@ export default class HardhatProvider extends Plugin { constructor (blockchain) { super(profile) this.provider = null + this.blocked = false // used to block any call when trying to recover after a failed connection. this.blockchain = blockchain } onDeactivation () { this.provider = null + this.blocked = false } hardhatProviderDialogBody () { @@ -41,21 +44,14 @@ export default class HardhatProvider extends Plugin { sendAsync (data) { return new Promise((resolve, reject) => { + if (this.blocked) return reject(new Error('provider temporarily blocked')) // If provider is not set, allow to open modal only when provider is trying to connect - if (!this.provider || data.method === 'net_listening') { + if (!this.provider) { modalDialogCustom.prompt('Hardhat node request', this.hardhatProviderDialogBody(), 'http://127.0.0.1:8545', (target) => { this.provider = new Web3.providers.HttpProvider(target) this.sendAsyncInternal(data, resolve, reject) }, () => { - // If 'cancel' is clicked while trying to connect, handle it in custom manner - if (data.method === 'net_listening') resolve({ jsonrpc: '2.0', result: 'canceled', id: data.id }) - else { - // When node is abruptly stopped, modal will appear - // On which clicking on 'Cancel' will set the Envrionment to VM - this.blockchain.changeExecutionContext('vm') - this.provider = this.blockchain.getCurrentProvider() - reject(new Error('Connection canceled')) - } + this.sendAsyncInternal(data, resolve, reject) }) } else { this.sendAsyncInternal(data, resolve, reject) @@ -68,9 +64,13 @@ export default class HardhatProvider extends Plugin { // Check the case where current environment is VM on UI and it still sends RPC requests // This will be displayed on UI tooltip as 'cannot get account list: Environment Updated !!' if (this.blockchain.getProvider() !== 'Hardhat Provider' && data.method !== 'net_listening') return reject(new Error('Environment Updated !!')) - this.provider[this.provider.sendAsync ? 'sendAsync' : 'send'](data, (error, message) => { + this.provider[this.provider.sendAsync ? 'sendAsync' : 'send'](data, async (error, message) => { if (error) { + this.blocked = true + modalDialogCustom.alert('Hardhat', `Error while connecting to the hardhat provider: ${error.message}`) + await this.call('udapp', 'setEnvironmentMode', 'vm') this.provider = null + setTimeout(_ => this.blocked = false, 1000) return reject(error) } resolve(message) diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index 26f684e432..45bc5a7421 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -14,7 +14,7 @@ const requiredModules = [ // services + layout views + system views const dependentModules = ['git', 'hardhat'] // module which shouldn't be manually activated (e.g git is activated by remixd) export function isNative (name) { - const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity'] + const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'hardhat-provider'] return nativePlugins.includes(name) || requiredModules.includes(name) } From 45db3361c6e2d0d8862309ad7c04204cbe7adf32 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 29 Jun 2021 15:47:21 +0200 Subject: [PATCH 37/51] linting --- apps/remix-ide/src/app/tabs/hardhat-provider.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/hardhat-provider.js b/apps/remix-ide/src/app/tabs/hardhat-provider.js index fa99969d20..afcd72276a 100644 --- a/apps/remix-ide/src/app/tabs/hardhat-provider.js +++ b/apps/remix-ide/src/app/tabs/hardhat-provider.js @@ -1,7 +1,6 @@ import * as packageJson from '../../../../../package.json' import { Plugin } from '@remixproject/engine' import Web3 from 'web3' -import toaster from '../ui/tooltip' const yo = require('yo-yo') const modalDialogCustom = require('../ui/modal-dialog-custom') @@ -70,7 +69,7 @@ export default class HardhatProvider extends Plugin { modalDialogCustom.alert('Hardhat', `Error while connecting to the hardhat provider: ${error.message}`) await this.call('udapp', 'setEnvironmentMode', 'vm') this.provider = null - setTimeout(_ => this.blocked = false, 1000) + setTimeout(_ => { this.blocked = false }, 1000) return reject(error) } resolve(message) From b645d45883e61f7de59928bf5d3fb9df3fbd1c61 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 29 Jun 2021 16:41:54 +0200 Subject: [PATCH 38/51] label & comment --- apps/remix-ide/src/app/tabs/hardhat-provider.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/hardhat-provider.js b/apps/remix-ide/src/app/tabs/hardhat-provider.js index afcd72276a..06d9459426 100644 --- a/apps/remix-ide/src/app/tabs/hardhat-provider.js +++ b/apps/remix-ide/src/app/tabs/hardhat-provider.js @@ -43,7 +43,7 @@ export default class HardhatProvider extends Plugin { sendAsync (data) { return new Promise((resolve, reject) => { - if (this.blocked) return reject(new Error('provider temporarily blocked')) + if (this.blocked) return reject(new Error('provider unable to connect')) // If provider is not set, allow to open modal only when provider is trying to connect if (!this.provider) { modalDialogCustom.prompt('Hardhat node request', this.hardhatProviderDialogBody(), 'http://127.0.0.1:8545', (target) => { @@ -66,10 +66,10 @@ export default class HardhatProvider extends Plugin { this.provider[this.provider.sendAsync ? 'sendAsync' : 'send'](data, async (error, message) => { if (error) { this.blocked = true - modalDialogCustom.alert('Hardhat', `Error while connecting to the hardhat provider: ${error.message}`) + modalDialogCustom.alert('Hardhat Provider', `Error while connecting to the hardhat provider: ${error.message}`) await this.call('udapp', 'setEnvironmentMode', 'vm') this.provider = null - setTimeout(_ => { this.blocked = false }, 1000) + setTimeout(_ => { this.blocked = false }, 1000) // we wait 1 second for letting remix to switch to vm return reject(error) } resolve(message) From 8ae678dd3b7cb2dad11ee365daf9286245a76609 Mon Sep 17 00:00:00 2001 From: Aniket <30843294+Aniket-Engg@users.noreply.github.com> Date: Wed, 30 Jun 2021 12:03:24 +0530 Subject: [PATCH 39/51] Update hardhat-provider.js --- apps/remix-ide/src/app/tabs/hardhat-provider.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/hardhat-provider.js b/apps/remix-ide/src/app/tabs/hardhat-provider.js index 06d9459426..805bc37e08 100644 --- a/apps/remix-ide/src/app/tabs/hardhat-provider.js +++ b/apps/remix-ide/src/app/tabs/hardhat-provider.js @@ -34,8 +34,6 @@ export default class HardhatProvider extends Plugin {
For more info, visit: Hardhat Documentation

- Note: Click on 'Cancel' if node is stopped. -

Hardhat JSON-RPC Endpoint
` @@ -75,7 +73,8 @@ export default class HardhatProvider extends Plugin { resolve(message) }) } else { - resolve({ jsonrpc: '2.0', result: [], id: data.id }) + const result = data.method === 'net_listening' ? 'canceled' : [] + resolve({ jsonrpc: '2.0', result: result, id: data.id }) } } } From d5d79381187e2b5a4b3cd5befadf873edffb55ce Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 22 Jun 2021 14:27:13 +0200 Subject: [PATCH 40/51] improve loading opcodes --- .../debugger-ui/src/reducers/assembly-items.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts b/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts index 4038cce2d9..35d428c667 100644 --- a/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts +++ b/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts @@ -20,6 +20,14 @@ export const initialState = { hasError: null } +const reducedOpcode = (opCodes) => { + const length = 50 + let bottom = opCodes.index - 10 + bottom = bottom < 0 ? 0 : bottom + const top = bottom + length + return { top, bottom, display: opCodes.code.slice(bottom, top) } +} + export const reducer = (state = initialState, action: Action) => { switch (action.type) { case 'FETCH_OPCODES_REQUEST': { @@ -34,16 +42,12 @@ export const reducer = (state = initialState, action: Action) => { const opCodes = action.payload.address === state.opCodes.address ? { ...state.opCodes, index: action.payload.index } : deepEqual(action.payload.code, state.opCodes.code) ? state.opCodes : action.payload - const top = opCodes.index - 3 > 0 ? opCodes.index - 3 : 0 - const bottom = opCodes.index + 4 < opCodes.code.length ? opCodes.index + 4 : opCodes.code.length - const display = opCodes.code.slice(top, bottom) + const reduced = reducedOpcode(opCodes) return { opCodes, - display, - index: display.findIndex(code => code === opCodes.code[opCodes.index]), - top, - bottom, + display: reduced.display, + index: reduced.display.findIndex(code => code === opCodes.code[opCodes.index]), isRequesting: false, isSuccessful: true, hasError: null From cd997ee69a8453972966f3848779d7dc13e4378c Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 23 Jun 2021 11:05:37 +0200 Subject: [PATCH 41/51] highlight the next opcode to be executed --- libs/remix-debug/src/code/codeManager.ts | 4 +- libs/remix-debug/src/debugger/VmDebugger.ts | 4 +- .../src/lib/vm-debugger/assembly-items.tsx | 56 ++++++++++++++++--- .../src/reducers/assembly-items.ts | 14 +++-- 4 files changed, 62 insertions(+), 16 deletions(-) diff --git a/libs/remix-debug/src/code/codeManager.ts b/libs/remix-debug/src/code/codeManager.ts index fff30cba15..b0f61a0a24 100644 --- a/libs/remix-debug/src/code/codeManager.ts +++ b/libs/remix-debug/src/code/codeManager.ts @@ -147,13 +147,15 @@ export class CodeManager { private retrieveIndexAndTrigger (codeMananger, address, step, code) { let result + let next try { result = codeMananger.getInstructionIndex(address, step) + next = codeMananger.getInstructionIndex(address, step + 1) } catch (error) { return console.log(error) } try { - codeMananger.event.trigger('changed', [code, address, result]) + codeMananger.event.trigger('changed', [code, address, result, next]) } catch (e) { console.log('dispatching event failed', e) } diff --git a/libs/remix-debug/src/debugger/VmDebugger.ts b/libs/remix-debug/src/debugger/VmDebugger.ts index 2a90d0ed2c..47ea75ea4b 100644 --- a/libs/remix-debug/src/debugger/VmDebugger.ts +++ b/libs/remix-debug/src/debugger/VmDebugger.ts @@ -59,8 +59,8 @@ export class VmDebuggerLogic { } listenToCodeManagerEvents () { - this._codeManager.event.register('changed', (code, address, index) => { - this.event.trigger('codeManagerChanged', [code, address, index]) + this._codeManager.event.register('changed', (code, address, index, nextIndex) => { + this.event.trigger('codeManagerChanged', [code, address, index, nextIndex]) }) } diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx index 67f9821960..debabf4ce1 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx @@ -4,24 +4,28 @@ import './styles/assembly-items.css' export const AssemblyItems = ({ registerEvent }) => { const [assemblyItems, dispatch] = useReducer(reducer, initialState) + const [absoluteSelectedIndex, setAbsoluteSelectedIndex] = useState(0) const [selectedItem, setSelectedItem] = useState(0) + const [nextSelectedItem, setNextSelectedItem] = useState(1) const refs = useRef({}) const asmItemsRef = useRef(null) useEffect(() => { - registerEvent && registerEvent('codeManagerChanged', (code, address, index) => { - dispatch({ type: 'FETCH_OPCODES_SUCCESS', payload: { code, address, index } }) + registerEvent && registerEvent('codeManagerChanged', (code, address, index, nextIndex) => { + dispatch({ type: 'FETCH_OPCODES_SUCCESS', payload: { code, address, index, nextIndex } }) }) }, []) useEffect(() => { - if (selectedItem !== assemblyItems.index) { + console.log('useEffect', assemblyItems.index) + if (absoluteSelectedIndex !== assemblyItems.index) { + clearItems() indexChanged(assemblyItems.index) + nextIndexChanged(assemblyItems.nextIndex) } - }, [assemblyItems.index]) + }, [assemblyItems.opCodes.index]) - const indexChanged = (index: number) => { - if (index < 0) return + const clearItems = () => { let currentItem = refs.current[selectedItem] ? refs.current[selectedItem] : null if (currentItem) { @@ -30,15 +34,49 @@ export const AssemblyItems = ({ registerEvent }) => { if (currentItem.firstChild) { currentItem.firstChild.removeAttribute('style') } - const codeView = asmItemsRef.current + } - currentItem = codeView.children[index] + currentItem = refs.current[nextSelectedItem] ? refs.current[nextSelectedItem] : null + + if (currentItem) { + currentItem.removeAttribute('selected') + currentItem.removeAttribute('style') + if (currentItem.firstChild) { + currentItem.firstChild.removeAttribute('style') + } + } + } + + const indexChanged = (index: number) => { + console.log("index " + index) + if (index < 0) return + + const codeView = asmItemsRef.current + + const currentItem = codeView.children[index] + if (currentItem) { currentItem.style.setProperty('border-color', 'var(--primary)') currentItem.style.setProperty('border-style', 'solid') currentItem.setAttribute('selected', 'selected') codeView.scrollTop = currentItem.offsetTop - parseInt(codeView.offsetTop) - setSelectedItem(index) } + + setSelectedItem(index) + setAbsoluteSelectedIndex(assemblyItems.opCodes.index) + } + + const nextIndexChanged = (index: number) => { + if (index < 0) return + + const codeView = asmItemsRef.current + + const currentItem = codeView.children[index] + if (currentItem) { + currentItem.style.setProperty('border-color', 'var(--secondary)') + currentItem.style.setProperty('border-style', 'dotted') + currentItem.setAttribute('selected', 'selected') + } + setNextSelectedItem(index) } return ( diff --git a/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts b/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts index 35d428c667..ff6fe23b40 100644 --- a/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts +++ b/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts @@ -13,6 +13,7 @@ export const initialState = { }, display: [], index: 0, + nextIndex: -1, top: 0, bottom: 0, isRequesting: false, @@ -21,11 +22,15 @@ export const initialState = { } const reducedOpcode = (opCodes) => { - const length = 50 + const length = 100 let bottom = opCodes.index - 10 bottom = bottom < 0 ? 0 : bottom const top = bottom + length - return { top, bottom, display: opCodes.code.slice(bottom, top) } + return { + index: opCodes.index - bottom, + nextIndex:opCodes.nextIndex - bottom, + display: opCodes.code.slice(bottom, top) + } } export const reducer = (state = initialState, action: Action) => { @@ -40,14 +45,15 @@ export const reducer = (state = initialState, action: Action) => { } case 'FETCH_OPCODES_SUCCESS': { const opCodes = action.payload.address === state.opCodes.address ? { - ...state.opCodes, index: action.payload.index + ...state.opCodes, index: action.payload.index, nextIndex: action.payload.nextIndex } : deepEqual(action.payload.code, state.opCodes.code) ? state.opCodes : action.payload const reduced = reducedOpcode(opCodes) return { opCodes, display: reduced.display, - index: reduced.display.findIndex(code => code === opCodes.code[opCodes.index]), + index: reduced.index, + nextIndex: reduced.nextIndex, isRequesting: false, isSuccessful: true, hasError: null From ac4d057db4c79f3f29773da1ec230a1741baf1bb Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 23 Jun 2021 11:13:26 +0200 Subject: [PATCH 42/51] linting --- .../debugger-ui/src/lib/vm-debugger/assembly-items.tsx | 10 +++++----- .../debugger-ui/src/reducers/assembly-items.ts | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx index debabf4ce1..248e4be9cc 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx @@ -48,9 +48,9 @@ export const AssemblyItems = ({ registerEvent }) => { } const indexChanged = (index: number) => { - console.log("index " + index) + console.log('index ' + index) if (index < 0) return - + const codeView = asmItemsRef.current const currentItem = codeView.children[index] @@ -60,21 +60,21 @@ export const AssemblyItems = ({ registerEvent }) => { currentItem.setAttribute('selected', 'selected') codeView.scrollTop = currentItem.offsetTop - parseInt(codeView.offsetTop) } - + setSelectedItem(index) setAbsoluteSelectedIndex(assemblyItems.opCodes.index) } const nextIndexChanged = (index: number) => { if (index < 0) return - + const codeView = asmItemsRef.current const currentItem = codeView.children[index] if (currentItem) { currentItem.style.setProperty('border-color', 'var(--secondary)') currentItem.style.setProperty('border-style', 'dotted') - currentItem.setAttribute('selected', 'selected') + currentItem.setAttribute('selected', 'selected') } setNextSelectedItem(index) } diff --git a/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts b/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts index ff6fe23b40..bc9ea96580 100644 --- a/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts +++ b/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts @@ -26,10 +26,10 @@ const reducedOpcode = (opCodes) => { let bottom = opCodes.index - 10 bottom = bottom < 0 ? 0 : bottom const top = bottom + length - return { + return { index: opCodes.index - bottom, - nextIndex:opCodes.nextIndex - bottom, - display: opCodes.code.slice(bottom, top) + nextIndex: opCodes.nextIndex - bottom, + display: opCodes.code.slice(bottom, top) } } From be52442ccd37429f1190d797a6071934027204fe Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 23 Jun 2021 11:18:27 +0200 Subject: [PATCH 43/51] add css style --- libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx b/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx index af3648aa90..7adc8a9312 100644 --- a/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx @@ -274,7 +274,7 @@ export const DebuggerUI = (props: DebuggerUIProps) => {

Debugger Configuration

-
+
{ setState(prevState => { return { ...prevState, opt: { debugWithGeneratedSources: checked } } From 93464327c9a82f8b5d04d509c2ef7ec9a94cf1f2 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 23 Jun 2021 23:11:37 +0200 Subject: [PATCH 44/51] keep track of stop/revert/return indexes and outofgad indexes --- libs/remix-debug/src/code/codeManager.ts | 30 ++++++-- libs/remix-debug/src/debugger/VmDebugger.ts | 4 +- libs/remix-debug/src/trace/traceAnalyser.ts | 11 +++ libs/remix-debug/src/trace/traceCache.ts | 14 +++- libs/remix-debug/src/trace/traceManager.ts | 8 +++ .../src/web3Provider/web3VmProvider.ts | 2 +- .../src/lib/vm-debugger/assembly-items.tsx | 69 ++++++++++++++++++- .../src/reducers/assembly-items.ts | 14 ++-- 8 files changed, 136 insertions(+), 16 deletions(-) diff --git a/libs/remix-debug/src/code/codeManager.ts b/libs/remix-debug/src/code/codeManager.ts index b0f61a0a24..fb04f64945 100644 --- a/libs/remix-debug/src/code/codeManager.ts +++ b/libs/remix-debug/src/code/codeManager.ts @@ -145,17 +145,37 @@ export class CodeManager { }) } - private retrieveIndexAndTrigger (codeMananger, address, step, code) { + private async retrieveIndexAndTrigger (codeMananger, address, step, code) { let result let next + let returnInstructionIndexes = [] + let outOfGasInstructionIndexes = [] + try { result = codeMananger.getInstructionIndex(address, step) next = codeMananger.getInstructionIndex(address, step + 1) - } catch (error) { - return console.log(error) - } + + let values = this.traceManager.getAllStopIndexes() + values = values.filter((value) => value.address === address) + if (values) { + for (const value of values) { + returnInstructionIndexes.push({ instructionIndex: this.getInstructionIndex(address, value.index), address }) + } + } + + values = this.traceManager.getAllOutofGasIndexes() + values = values.filter((value) => value.address === address) + if (values) { + for (const value of values) { + outOfGasInstructionIndexes.push({ instructionIndex: this.getInstructionIndex(address, value.index), address }) + } + } + + } catch (error) { + return console.log(error) + } try { - codeMananger.event.trigger('changed', [code, address, result, next]) + codeMananger.event.trigger('changed', [code, address, result, next, returnInstructionIndexes, outOfGasInstructionIndexes]) } catch (e) { console.log('dispatching event failed', e) } diff --git a/libs/remix-debug/src/debugger/VmDebugger.ts b/libs/remix-debug/src/debugger/VmDebugger.ts index 47ea75ea4b..72a131cfd6 100644 --- a/libs/remix-debug/src/debugger/VmDebugger.ts +++ b/libs/remix-debug/src/debugger/VmDebugger.ts @@ -59,8 +59,8 @@ export class VmDebuggerLogic { } listenToCodeManagerEvents () { - this._codeManager.event.register('changed', (code, address, index, nextIndex) => { - this.event.trigger('codeManagerChanged', [code, address, index, nextIndex]) + this._codeManager.event.register('changed', (code, address, index, nextIndex, returnInstructionIndexes, outOfGasInstructionIndexes) => { + this.event.trigger('codeManagerChanged', [code, address, index, nextIndex, returnInstructionIndexes, outOfGasInstructionIndexes]) }) } diff --git a/libs/remix-debug/src/trace/traceAnalyser.ts b/libs/remix-debug/src/trace/traceAnalyser.ts index ae8957b5ac..ba66f2dbb1 100644 --- a/libs/remix-debug/src/trace/traceAnalyser.ts +++ b/libs/remix-debug/src/trace/traceAnalyser.ts @@ -49,6 +49,17 @@ export class TraceAnalyser { this.traceCache.pushReturnValue(index, returnParamsObj) } + if (traceHelper.isReturnInstruction(step) || traceHelper.isStopInstruction(step) || traceHelper.isRevertInstruction(step)) { + this.traceCache.pushStopIndex(index, this.traceCache.currentCall.call.address) + } + + try { + if (parseInt(step.gas) - parseInt(step.gasCost) <= 0 || step.error === 'OutOfGas') { + this.traceCache.pushOutOfGasIndex(index, this.traceCache.currentCall.call.address) + } + } catch (e) { + console.error(e) + } } buildCalldata (index, step, tx, newContext) { diff --git a/libs/remix-debug/src/trace/traceCache.ts b/libs/remix-debug/src/trace/traceCache.ts index 7c2d381ccc..411e8e617c 100644 --- a/libs/remix-debug/src/trace/traceCache.ts +++ b/libs/remix-debug/src/trace/traceCache.ts @@ -5,6 +5,8 @@ const { sha3_256 } = util export class TraceCache { returnValues + stopIndexes + outofgasIndexes currentCall callsTree callsData @@ -24,6 +26,8 @@ export class TraceCache { // ...Changes contains index in the vmtrace of the corresponding changes this.returnValues = {} + this.stopIndexes = [] + this.outofgasIndexes = [] this.currentCall = null this.callsTree = null this.callsData = {} @@ -59,7 +63,7 @@ export class TraceCache { this.currentCall.call.reverted = reverted } var parent = this.currentCall.parent - this.currentCall = parent ? { call: parent.call, parent: parent.parent } : null + if (parent) this.currentCall = { call: parent.call, parent: parent.parent } return } const call = { @@ -78,6 +82,14 @@ export class TraceCache { this.currentCall = { call: call, parent: this.currentCall } } + pushOutOfGasIndex (index, address) { + this.outofgasIndexes.push({ index, address }) + } + + pushStopIndex (index, address) { + this.stopIndexes.push({ index, address }) + } + pushReturnValue (step, value) { this.returnValues[step] = value } diff --git a/libs/remix-debug/src/trace/traceManager.ts b/libs/remix-debug/src/trace/traceManager.ts index 8e78782922..848b3c57aa 100644 --- a/libs/remix-debug/src/trace/traceManager.ts +++ b/libs/remix-debug/src/trace/traceManager.ts @@ -209,6 +209,14 @@ export class TraceManager { return this.trace[stepIndex].pc } + getAllStopIndexes () { + return this.traceCache.stopIndexes + } + + getAllOutofGasIndexes () { + return this.traceCache.outofgasIndexes + } + getReturnValue (stepIndex) { try { this.checkRequestedStep(stepIndex) diff --git a/libs/remix-lib/src/web3Provider/web3VmProvider.ts b/libs/remix-lib/src/web3Provider/web3VmProvider.ts index 59b0e7e909..b5d8ea4732 100644 --- a/libs/remix-lib/src/web3Provider/web3VmProvider.ts +++ b/libs/remix-lib/src/web3Provider/web3VmProvider.ts @@ -138,7 +138,7 @@ export class Web3VmProvider { async txProcessed (data) { const lastOp = this.vmTraces[this.processingHash].structLogs[this.processingIndex - 1] if (lastOp) { - lastOp.error = lastOp.op !== 'RETURN' && lastOp.op !== 'STOP' && lastOp.op !== 'thisDESTRUCT' + lastOp.error = lastOp.op !== 'RETURN' && lastOp.op !== 'STOP' && lastOp.op !== 'DESTRUCT' } this.vmTraces[this.processingHash].gas = '0x' + data.gasUsed.toString(16) diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx index 248e4be9cc..de9c37e1bc 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx @@ -7,12 +7,14 @@ export const AssemblyItems = ({ registerEvent }) => { const [absoluteSelectedIndex, setAbsoluteSelectedIndex] = useState(0) const [selectedItem, setSelectedItem] = useState(0) const [nextSelectedItem, setNextSelectedItem] = useState(1) + const [returnInstructionIndexes, setReturnInstructionIndexes] = useState([]) + const [outOfGasInstructionIndexes, setOutOfGasInstructionIndexes] = useState([]) const refs = useRef({}) const asmItemsRef = useRef(null) useEffect(() => { - registerEvent && registerEvent('codeManagerChanged', (code, address, index, nextIndex) => { - dispatch({ type: 'FETCH_OPCODES_SUCCESS', payload: { code, address, index, nextIndex } }) + registerEvent && registerEvent('codeManagerChanged', (code, address, index, nextIndex, returnInstructionIndexes, outOfGasInstructionIndexes) => { + dispatch({ type: 'FETCH_OPCODES_SUCCESS', payload: { code, address, index, nextIndex, returnInstructionIndexes, outOfGasInstructionIndexes } }) }) }, []) @@ -22,6 +24,8 @@ export const AssemblyItems = ({ registerEvent }) => { clearItems() indexChanged(assemblyItems.index) nextIndexChanged(assemblyItems.nextIndex) + returnIndexes(assemblyItems.returnInstructionIndexes) + outOfGasIndexes(assemblyItems.outOfGasInstructionIndexes) } }, [assemblyItems.opCodes.index]) @@ -45,10 +49,37 @@ export const AssemblyItems = ({ registerEvent }) => { currentItem.firstChild.removeAttribute('style') } } + + returnInstructionIndexes.map((index) => { + if (index < 0) return + + currentItem = refs.current[index] ? refs.current[index] : null + + if (currentItem) { + currentItem.removeAttribute('selected') + currentItem.removeAttribute('style') + if (currentItem.firstChild) { + currentItem.firstChild.removeAttribute('style') + } + } + }) + + outOfGasInstructionIndexes.map((index) => { + if (index < 0) return + + currentItem = refs.current[index] ? refs.current[index] : null + + if (currentItem) { + currentItem.removeAttribute('selected') + currentItem.removeAttribute('style') + if (currentItem.firstChild) { + currentItem.firstChild.removeAttribute('style') + } + } + }) } const indexChanged = (index: number) => { - console.log('index ' + index) if (index < 0) return const codeView = asmItemsRef.current @@ -79,6 +110,38 @@ export const AssemblyItems = ({ registerEvent }) => { setNextSelectedItem(index) } + const returnIndexes = (indexes) => { + indexes.map((index) => { + if (index < 0) return + + const codeView = asmItemsRef.current + + const currentItem = codeView.children[index] + if (currentItem) { + currentItem.style.setProperty('border-color', 'var(--warning)') + currentItem.style.setProperty('border-style', 'dotted') + currentItem.setAttribute('selected', 'selected') + } + }) + setReturnInstructionIndexes(indexes) + } + + const outOfGasIndexes = (indexes) => { + indexes.map((index) => { + if (index < 0) return + + const codeView = asmItemsRef.current + + const currentItem = codeView.children[index] + if (currentItem) { + currentItem.style.setProperty('border-color', 'var(--danger)') + currentItem.style.setProperty('border-style', 'dotted') + currentItem.setAttribute('selected', 'selected') + } + }) + setOutOfGasInstructionIndexes(indexes) + } + return (
diff --git a/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts b/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts index bc9ea96580..d5a936bc95 100644 --- a/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts +++ b/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts @@ -14,6 +14,8 @@ export const initialState = { display: [], index: 0, nextIndex: -1, + returnInstructionIndexes: [], + outOfGasInstructionIndexes: [], top: 0, bottom: 0, isRequesting: false, @@ -21,7 +23,7 @@ export const initialState = { hasError: null } -const reducedOpcode = (opCodes) => { +const reducedOpcode = (opCodes, payload) => { const length = 100 let bottom = opCodes.index - 10 bottom = bottom < 0 ? 0 : bottom @@ -29,7 +31,9 @@ const reducedOpcode = (opCodes) => { return { index: opCodes.index - bottom, nextIndex: opCodes.nextIndex - bottom, - display: opCodes.code.slice(bottom, top) + display: opCodes.code.slice(bottom, top), + returnInstructionIndexes: payload.returnInstructionIndexes.map((index) => index.instructionIndex - bottom ), + outOfGasInstructionIndexes: payload.outOfGasInstructionIndexes.map((index) => index.instructionIndex - bottom ) } } @@ -48,7 +52,7 @@ export const reducer = (state = initialState, action: Action) => { ...state.opCodes, index: action.payload.index, nextIndex: action.payload.nextIndex } : deepEqual(action.payload.code, state.opCodes.code) ? state.opCodes : action.payload - const reduced = reducedOpcode(opCodes) + const reduced = reducedOpcode(opCodes, action.payload) return { opCodes, display: reduced.display, @@ -56,7 +60,9 @@ export const reducer = (state = initialState, action: Action) => { nextIndex: reduced.nextIndex, isRequesting: false, isSuccessful: true, - hasError: null + hasError: null, + returnInstructionIndexes: reduced.returnInstructionIndexes, + outOfGasInstructionIndexes: reduced.outOfGasInstructionIndexes } } case 'FETCH_OPCODES_ERROR': { From 3d2db3b6b53ca4d65ce43a1310e02402e533b70c Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 24 Jun 2021 09:01:55 +0200 Subject: [PATCH 45/51] linting --- libs/remix-debug/src/code/codeManager.ts | 11 +++++------ libs/remix-debug/src/trace/traceAnalyser.ts | 4 ++-- .../debugger-ui/src/reducers/assembly-items.ts | 4 ++-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/libs/remix-debug/src/code/codeManager.ts b/libs/remix-debug/src/code/codeManager.ts index fb04f64945..207f3e0510 100644 --- a/libs/remix-debug/src/code/codeManager.ts +++ b/libs/remix-debug/src/code/codeManager.ts @@ -148,8 +148,8 @@ export class CodeManager { private async retrieveIndexAndTrigger (codeMananger, address, step, code) { let result let next - let returnInstructionIndexes = [] - let outOfGasInstructionIndexes = [] + const returnInstructionIndexes = [] + const outOfGasInstructionIndexes = [] try { result = codeMananger.getInstructionIndex(address, step) @@ -170,10 +170,9 @@ export class CodeManager { outOfGasInstructionIndexes.push({ instructionIndex: this.getInstructionIndex(address, value.index), address }) } } - - } catch (error) { - return console.log(error) - } + } catch (error) { + return console.log(error) + } try { codeMananger.event.trigger('changed', [code, address, result, next, returnInstructionIndexes, outOfGasInstructionIndexes]) } catch (e) { diff --git a/libs/remix-debug/src/trace/traceAnalyser.ts b/libs/remix-debug/src/trace/traceAnalyser.ts index ba66f2dbb1..74651b228d 100644 --- a/libs/remix-debug/src/trace/traceAnalyser.ts +++ b/libs/remix-debug/src/trace/traceAnalyser.ts @@ -52,14 +52,14 @@ export class TraceAnalyser { if (traceHelper.isReturnInstruction(step) || traceHelper.isStopInstruction(step) || traceHelper.isRevertInstruction(step)) { this.traceCache.pushStopIndex(index, this.traceCache.currentCall.call.address) } - + try { if (parseInt(step.gas) - parseInt(step.gasCost) <= 0 || step.error === 'OutOfGas') { this.traceCache.pushOutOfGasIndex(index, this.traceCache.currentCall.call.address) } } catch (e) { console.error(e) - } + } } buildCalldata (index, step, tx, newContext) { diff --git a/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts b/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts index d5a936bc95..18622bfa68 100644 --- a/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts +++ b/libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts @@ -32,8 +32,8 @@ const reducedOpcode = (opCodes, payload) => { index: opCodes.index - bottom, nextIndex: opCodes.nextIndex - bottom, display: opCodes.code.slice(bottom, top), - returnInstructionIndexes: payload.returnInstructionIndexes.map((index) => index.instructionIndex - bottom ), - outOfGasInstructionIndexes: payload.outOfGasInstructionIndexes.map((index) => index.instructionIndex - bottom ) + returnInstructionIndexes: payload.returnInstructionIndexes.map((index) => index.instructionIndex - bottom), + outOfGasInstructionIndexes: payload.outOfGasInstructionIndexes.map((index) => index.instructionIndex - bottom) } } From e16b071108d0caf1aa3cd94c2dab5693339a582a Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 24 Jun 2021 14:37:50 +0200 Subject: [PATCH 46/51] remove unneeded loop --- libs/remix-debug/src/code/codeManager.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libs/remix-debug/src/code/codeManager.ts b/libs/remix-debug/src/code/codeManager.ts index 207f3e0510..390c988eed 100644 --- a/libs/remix-debug/src/code/codeManager.ts +++ b/libs/remix-debug/src/code/codeManager.ts @@ -156,18 +156,20 @@ export class CodeManager { next = codeMananger.getInstructionIndex(address, step + 1) let values = this.traceManager.getAllStopIndexes() - values = values.filter((value) => value.address === address) if (values) { for (const value of values) { - returnInstructionIndexes.push({ instructionIndex: this.getInstructionIndex(address, value.index), address }) + if (value.address === address) { + returnInstructionIndexes.push({ instructionIndex: this.getInstructionIndex(address, value.index), address }) + } } } values = this.traceManager.getAllOutofGasIndexes() - values = values.filter((value) => value.address === address) if (values) { for (const value of values) { - outOfGasInstructionIndexes.push({ instructionIndex: this.getInstructionIndex(address, value.index), address }) + if (value.address === address) { + outOfGasInstructionIndexes.push({ instructionIndex: this.getInstructionIndex(address, value.index), address }) + } } } } catch (error) { From 2720bbdda349e2858d962a85bac1960a4ec5e616 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 24 Jun 2021 14:38:25 +0200 Subject: [PATCH 47/51] remove console.log --- libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx index de9c37e1bc..3f1a4c5235 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx @@ -19,7 +19,6 @@ export const AssemblyItems = ({ registerEvent }) => { }, []) useEffect(() => { - console.log('useEffect', assemblyItems.index) if (absoluteSelectedIndex !== assemblyItems.index) { clearItems() indexChanged(assemblyItems.index) From 8d44d31cb32c5b70bfc33126b3e7309c7a34cc82 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 24 Jun 2021 14:42:14 +0200 Subject: [PATCH 48/51] refactor --- .../src/lib/vm-debugger/assembly-items.tsx | 41 ++++--------------- 1 file changed, 8 insertions(+), 33 deletions(-) diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx index 3f1a4c5235..af6c061e6c 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx @@ -28,19 +28,7 @@ export const AssemblyItems = ({ registerEvent }) => { } }, [assemblyItems.opCodes.index]) - const clearItems = () => { - let currentItem = refs.current[selectedItem] ? refs.current[selectedItem] : null - - if (currentItem) { - currentItem.removeAttribute('selected') - currentItem.removeAttribute('style') - if (currentItem.firstChild) { - currentItem.firstChild.removeAttribute('style') - } - } - - currentItem = refs.current[nextSelectedItem] ? refs.current[nextSelectedItem] : null - + let clearItem = (currentItem) => { if (currentItem) { currentItem.removeAttribute('selected') currentItem.removeAttribute('style') @@ -48,33 +36,20 @@ export const AssemblyItems = ({ registerEvent }) => { currentItem.firstChild.removeAttribute('style') } } + } + const clearItems = () => { + clearItem(refs.current[selectedItem] ? refs.current[selectedItem] : null) + clearItem(refs.current[nextSelectedItem] ? refs.current[nextSelectedItem] : null) + returnInstructionIndexes.map((index) => { if (index < 0) return - - currentItem = refs.current[index] ? refs.current[index] : null - - if (currentItem) { - currentItem.removeAttribute('selected') - currentItem.removeAttribute('style') - if (currentItem.firstChild) { - currentItem.firstChild.removeAttribute('style') - } - } + clearItem(refs.current[index] ? refs.current[index] : null) }) outOfGasInstructionIndexes.map((index) => { if (index < 0) return - - currentItem = refs.current[index] ? refs.current[index] : null - - if (currentItem) { - currentItem.removeAttribute('selected') - currentItem.removeAttribute('style') - if (currentItem.firstChild) { - currentItem.firstChild.removeAttribute('style') - } - } + clearItem(refs.current[index] ? refs.current[index] : null) }) } From ef2034a484f94b51bd2f7f31e3b50e963a40c2c0 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 29 Jun 2021 15:07:20 +0200 Subject: [PATCH 49/51] linting --- libs/remix-debug/src/code/codeManager.ts | 4 ++-- .../debugger-ui/src/lib/vm-debugger/assembly-items.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/remix-debug/src/code/codeManager.ts b/libs/remix-debug/src/code/codeManager.ts index 390c988eed..f0b38ea3d9 100644 --- a/libs/remix-debug/src/code/codeManager.ts +++ b/libs/remix-debug/src/code/codeManager.ts @@ -159,7 +159,7 @@ export class CodeManager { if (values) { for (const value of values) { if (value.address === address) { - returnInstructionIndexes.push({ instructionIndex: this.getInstructionIndex(address, value.index), address }) + returnInstructionIndexes.push({ instructionIndex: this.getInstructionIndex(address, value.index), address }) } } } @@ -168,7 +168,7 @@ export class CodeManager { if (values) { for (const value of values) { if (value.address === address) { - outOfGasInstructionIndexes.push({ instructionIndex: this.getInstructionIndex(address, value.index), address }) + outOfGasInstructionIndexes.push({ instructionIndex: this.getInstructionIndex(address, value.index), address }) } } } diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx index af6c061e6c..8b0ed07d9c 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx @@ -28,7 +28,7 @@ export const AssemblyItems = ({ registerEvent }) => { } }, [assemblyItems.opCodes.index]) - let clearItem = (currentItem) => { + const clearItem = (currentItem) => { if (currentItem) { currentItem.removeAttribute('selected') currentItem.removeAttribute('style') @@ -41,7 +41,7 @@ export const AssemblyItems = ({ registerEvent }) => { const clearItems = () => { clearItem(refs.current[selectedItem] ? refs.current[selectedItem] : null) clearItem(refs.current[nextSelectedItem] ? refs.current[nextSelectedItem] : null) - + returnInstructionIndexes.map((index) => { if (index < 0) return clearItem(refs.current[index] ? refs.current[index] : null) From 0354ece63b3e7208eeac7497a9cad5fa2cef0ba7 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 30 Jun 2021 16:52:09 +0200 Subject: [PATCH 50/51] change font style --- .../debugger-ui/src/lib/vm-debugger/assembly-items.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx index 8b0ed07d9c..1606ce8491 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx @@ -60,8 +60,8 @@ export const AssemblyItems = ({ registerEvent }) => { const currentItem = codeView.children[index] if (currentItem) { - currentItem.style.setProperty('border-color', 'var(--primary)') - currentItem.style.setProperty('border-style', 'solid') + currentItem.style.setProperty('background-color', 'var(--primary)') + currentItem.style.setProperty('color', 'var(--light)') currentItem.setAttribute('selected', 'selected') codeView.scrollTop = currentItem.offsetTop - parseInt(codeView.offsetTop) } From 3baf06687f06e3b685b2f7558e43454f37f50b80 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 30 Jun 2021 21:38:46 +0200 Subject: [PATCH 51/51] fix e2e --- apps/remix-ide-e2e/src/tests/pluginManager.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/pluginManager.spec.ts b/apps/remix-ide-e2e/src/tests/pluginManager.spec.ts index bd2884e4e5..f87bf1269e 100644 --- a/apps/remix-ide-e2e/src/tests/pluginManager.spec.ts +++ b/apps/remix-ide-e2e/src/tests/pluginManager.spec.ts @@ -5,7 +5,7 @@ import init from '../helpers/init' const testData = { pluginName: 'remixIde', pluginDisplayName: 'Remix IDE', - pluginUrl: 'https://zokrates-remix-plugin.netlify.app/' + pluginUrl: 'https://zokrates.github.io/zokrates-remix-plugin/' } module.exports = {