From f706ad00ebd4e38a5205f8381db0a7950d00b135 Mon Sep 17 00:00:00 2001 From: David Disu Date: Thu, 10 Feb 2022 12:18:13 +0100 Subject: [PATCH 01/55] Show create icon when all workspaces are deleted --- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index ceb6899c9b..a51224f86c 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -127,7 +127,7 @@ export function Workspace () { ) + +export const storageFullMessage = () => ( +
+ + + Cannot save this file due full LocalStorage. Backup existing files and free up some space. + +
+) From 4f2153f616ae3bfe2e23a05b606d9f8f28ef7a58 Mon Sep 17 00:00:00 2001 From: David Disu Date: Mon, 14 Feb 2022 11:17:35 +0100 Subject: [PATCH 29/55] Update toaster message --- libs/remix-ui/helper/src/lib/helper-components.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/helper/src/lib/helper-components.tsx b/libs/remix-ui/helper/src/lib/helper-components.tsx index 67ff3cae03..a71950315e 100644 --- a/libs/remix-ui/helper/src/lib/helper-components.tsx +++ b/libs/remix-ui/helper/src/lib/helper-components.tsx @@ -74,7 +74,7 @@ export const storageFullMessage = () => (
- Cannot save this file due full LocalStorage. Backup existing files and free up some space. + Cannot save this file due to full LocalStorage. Backup existing files and free up some space.
) From 96a694f971d3ee7fbcca367e999e27435f4c2a7d Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 17 Dec 2021 11:15:23 +0100 Subject: [PATCH 30/55] add editor stress e2e --- apps/remix-ide-e2e/src/tests/stress.editor.ts | 195 ++++++++++++++++++ package.json | 1 + 2 files changed, 196 insertions(+) create mode 100644 apps/remix-ide-e2e/src/tests/stress.editor.ts diff --git a/apps/remix-ide-e2e/src/tests/stress.editor.ts b/apps/remix-ide-e2e/src/tests/stress.editor.ts new file mode 100644 index 0000000000..57a047da8f --- /dev/null +++ b/apps/remix-ide-e2e/src/tests/stress.editor.ts @@ -0,0 +1,195 @@ +'use strict' + +import { NightwatchBrowser } from 'nightwatch' +import init from '../helpers/init' + +module.exports = { + + before: function (browser: NightwatchBrowser, done: VoidFunction) { + init(browser, done) + }, + + 'Should create 10 files, reload, and check if the files are saved': function (browser: NightwatchBrowser) { + const contents = {} + const checkContent = function (i, done) { + const name = 'test_' + i + '.sol' + browser + .openFile(name) + .pause(500) + .getEditorValue((content) => { + browser.assert.ok(content === contents[i]) + done() + }) + } + browser.clickLaunchIcon('filePanel').perform((done) => { + let contentEditSet = content.slice() + for (let i = 0; i < 10; i++) { + contentEditSet += contentEditSet + contents[i] = contentEditSet + const name = 'test_' + i + '.sol' + browser.click('[data-id="fileExplorerNewFilecreateNewFile"]') + .waitForElementContainsText('*[data-id$="/blank"]', '', 60000) + .sendKeys('*[data-id$="/blank"] .remixui_items', name) + .sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER) + .waitForElementVisible(`li[data-id="treeViewLitreeViewItem${name}"]`, 60000) + .setEditorValue(contentEditSet) + } + done() + }).pause(10000).refresh() + .perform(done => checkContent(0, done)) + .perform(done => checkContent(1, done)) + .perform(done => checkContent(2, done)) + .perform(done => checkContent(3, done)) + .perform(done => checkContent(4, done)) + .perform(done => checkContent(5, done)) + .perform(done => checkContent(6, done)) + .perform(done => checkContent(7, done)) + .perform(done => checkContent(8, done)) + .perform(done => checkContent(9, done)) + .end() + } +} + +const content: string = ` +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity >=0.7.0 <0.9.0; + +/** + * @title Ballot + * @dev Implements voting process along with vote delegation| + */ +contract Ballot { + + struct Voter { + uint weight; // weight is accumulated by delegation + bool voted; // if true, that person already voted + address delegate; // person delegated to + uint vote; // index of the voted proposal + } + + struct Proposal { + // If you can limit the length to a certain number of bytes, + // always use one of bytes1 to bytes32 because they are much cheaper + bytes32 name; // short name (up to 32 bytes) + uint voteCount; // number of accumulated votes + } + + address public chairperson; + + mapping(address => Voter) public voters; + + Proposal[] public proposals; + +function () test { + + /** + * @dev Create a new ballot to choose one of 'proposalNames'. + * @param proposalNames names of proposals + */ + constructor(bytes32[] memory proposalNames) { + chairperson = msg.sender; + voters[chairperson].weight = 1; + + for (uint i = 0; i < proposalNames.length; i++) { + // 'Proposal({...})' creates a temporary + // Proposal object and 'proposals.push(...)' + // appends it to the end of 'proposals'. + proposals.push(Proposal({ + name: proposalNames[i], + voteCount: 0 + })); + } + } + + /** + * @dev Give 'voter' the right to vote on this ballot. May only be called by 'chairperson'. + * @param voter address of voter + */ + function giveRightToVote(address voter) public { + require( + msg.sender == chairperson, + "Only chairperson can give right to vote." + ); + require( + !voters[voter].voted, + "The voter already voted." + ); + require(voters[voter].weight == 0); + voters[voter].weight = 1; + } + + /** + * @dev Delegate your vote to the voter 'to'. + * @param to address to which vote is delegated + */ + function delegate(address to) public { + Voter storage sender = voters[msg.sender]; + require(!sender.voted, "You already voted."); + require(to != msg.sender, "Self-delegation is disallowed."); + + while (voters[to].delegate != address(0)) { + to = voters[to].delegate; + + // We found a loop in the delegation, not allowed. + require(to != msg.sender, "Found loop in delegation."); + } + sender.voted = true; + sender.delegate = to; + Voter storage delegate_ = voters[to]; + if (delegate_.voted) { + // If the delegate already voted, + // directly add to the number of votes + proposals[delegate_.vote].voteCount += sender.weight; + } else { + // If the delegate did not vote yet, + // add to her weight. + delegate_.weight += sender.weight; + } + } + + /** + * @dev Give your vote (including votes delegated to you) to proposal 'proposals[proposal].name'. + * @param proposal index of proposal in the proposals array + */ + function vote(uint proposal) public { + Voter storage sender = voters[msg.sender]; + require(sender.weight != 0, "Has no right to vote"); + require(!sender.voted, "Already voted."); + sender.voted = true; + sender.vote = proposal; + + // If 'proposal' is out of the range of the array, + // this will throw automatically and revert all + // changes. + proposals[proposal].voteCount += sender.weight; + } + + /** + * @dev Computes the winning proposal taking all previous votes into account. + * @return winningProposal_ index of winning proposal in the proposals array + */ + function winningProposal() public view + returns (uint winningProposal_) + { + uint winningVoteCount = 0; + for (uint p = 0; p < proposals.length; p++) { + if (proposals[p].voteCount > winningVoteCount) { + winningVoteCount = proposals[p].voteCount; + winningProposal_ = p; + } + } + } + + /** + * @dev Calls winningProposal() function to get the index of the winner contained in the proposals array and then + * @return winnerName_ the name of the winner + */ + function winnerName() public view + returns (bytes32 winnerName_) + { + winnerName_ = proposals[winningProposal()].name; + } +} + +` diff --git a/package.json b/package.json index dc47278bd3..b37e2a9cb8 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,7 @@ "nightwatch_local_verticalIconscontextmenu": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/verticalIconsPanel.test.js --env=chrome", "nightwatch_local_pluginApi": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/plugin_api_*.js --env=chrome", "nightwatch_local_migrate_filesystem": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/migrateFileSystem.test.js --env=chrome", + "nightwatch_local_stress_editor": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/stress.editor.js --env=chromeDesktop", "onchange": "onchange apps/remix-ide/build/app.js -- npm-run-all lint", "remixd": "nx build remixd && chmod +x dist/libs/remixd/src/bin/remixd.js && dist/libs/remixd/src/bin/remixd.js -s ./apps/remix-ide/contracts --remix-ide http://127.0.0.1:8080", "selenium": "selenium-standalone start", From a3baa31654205f94c15b81a49675133dcd4de449 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 16 Feb 2022 14:03:47 +0100 Subject: [PATCH 31/55] fix linting --- apps/remix-ide-e2e/src/tests/stress.editor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/stress.editor.ts b/apps/remix-ide-e2e/src/tests/stress.editor.ts index 57a047da8f..ddb007b12a 100644 --- a/apps/remix-ide-e2e/src/tests/stress.editor.ts +++ b/apps/remix-ide-e2e/src/tests/stress.editor.ts @@ -50,7 +50,7 @@ module.exports = { } } -const content: string = ` +const content = ` // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; From 61304156b9b1b1f5005107adfaa3bf8b6d888c5a Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Fri, 11 Feb 2022 18:45:58 +0530 Subject: [PATCH 32/55] Run with mocha option in context menu --- apps/remix-ide/src/remixAppManager.js | 1 + libs/remix-ui/workspace/src/lib/actions/index.ts | 11 +++++++++++ .../src/lib/components/file-explorer-context-menu.tsx | 6 +++++- .../workspace/src/lib/components/file-explorer.tsx | 9 +++++++++ libs/remix-ui/workspace/src/lib/contexts/index.ts | 1 + .../src/lib/providers/FileSystemProvider.tsx | 7 ++++++- .../remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 2 ++ libs/remix-ui/workspace/src/lib/types/index.ts | 2 ++ libs/remix-ui/workspace/src/lib/utils/index.ts | 6 ++++++ 9 files changed, 43 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index ce7ea97b27..24814eb43d 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -114,6 +114,7 @@ export class RemixAppManager extends PluginManager { const res = await fetch(this.pluginsDirectory) plugins = await res.json() plugins = plugins.filter((plugin) => { + if (plugin.name === 'scriptRunner') plugin.url = 'http://127.0.0.1:8081' if (plugin.targets && Array.isArray(plugin.targets) && plugin.targets.length > 0) { return (plugin.targets.includes('remix')) } diff --git a/libs/remix-ui/workspace/src/lib/actions/index.ts b/libs/remix-ui/workspace/src/lib/actions/index.ts index ae248d6fa8..12f178348c 100644 --- a/libs/remix-ui/workspace/src/lib/actions/index.ts +++ b/libs/remix-ui/workspace/src/lib/actions/index.ts @@ -256,6 +256,17 @@ export const runScript = async (path: string) => { }) } +export const runScriptWithMocha = async (path: string) => { + const provider = plugin.fileManager.currentFileProvider() + provider.get(path, (error, content: string) => { + if (error) { + return dispatch(displayPopUp(error)) + } + if (content) content = content + '\n' + 'mocha.run()' + plugin.call('scriptRunner', 'execute', content) + }) +} + export const emitContextMenuEvent = async (cmd: customAction) => { await plugin.call(cmd.id, cmd.name, cmd) } diff --git a/libs/remix-ui/workspace/src/lib/components/file-explorer-context-menu.tsx b/libs/remix-ui/workspace/src/lib/components/file-explorer-context-menu.tsx index 5e6518c2de..b9bad4b170 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer-context-menu.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer-context-menu.tsx @@ -12,7 +12,7 @@ declare global { const _paq = window._paq = window._paq || [] //eslint-disable-line export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => { - const { actions, createNewFile, createNewFolder, deletePath, renamePath, hideContextMenu, pushChangesToGist, publishFileToGist, publishFolderToGist, copy, paste, runScript, emit, pageX, pageY, path, type, focus, ...otherProps } = props + const { actions, createNewFile, createNewFolder, deletePath, renamePath, hideContextMenu, pushChangesToGist, publishFileToGist, publishFolderToGist, copy, paste, runScript, runScriptWithMocha, emit, pageX, pageY, path, type, focus, ...otherProps } = props const contextMenuRef = useRef(null) useEffect(() => { contextMenuRef.current.focus() @@ -98,6 +98,10 @@ export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => _paq.push(['trackEvent', 'fileExplorer', 'runScript']) runScript(path) break + case 'Run with Mocha': + _paq.push(['trackEvent', 'fileExplorer', 'runScriptWithMocha']) + runScriptWithMocha(path) + break case 'Copy': copy(path, type) break diff --git a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx index 5ae7de8d05..d5c0fa8f75 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -221,6 +221,14 @@ export const FileExplorer = (props: FileExplorerProps) => { } } + const runScriptWithMocha = async (path: string) => { + try { + props.dispatchRunScriptWithMocha(path) + } catch (error) { + props.toast('Run script with Mocha failed') + } + } + const emitContextMenuEvent = (cmd: customAction) => { try { props.dispatchEmitContextMenuEvent(cmd) @@ -454,6 +462,7 @@ export const FileExplorer = (props: FileExplorerProps) => { deletePath={deletePath} renamePath={editModeOn} runScript={runScript} + runScriptWithMocha={runScriptWithMocha} copy={handleCopyClick} paste={handlePasteClick} emit={emitContextMenuEvent} diff --git a/libs/remix-ui/workspace/src/lib/contexts/index.ts b/libs/remix-ui/workspace/src/lib/contexts/index.ts index 1aedce98b5..20c9b46633 100644 --- a/libs/remix-ui/workspace/src/lib/contexts/index.ts +++ b/libs/remix-ui/workspace/src/lib/contexts/index.ts @@ -25,6 +25,7 @@ export const FileSystemContext = createContext<{ dispatchCopyFile: (src: string, dest: string) => Promise, dispatchCopyFolder: (src: string, dest: string) => Promise, dispatchRunScript: (path: string) => Promise, + dispatchRunScriptWithMocha: (path: string) => Promise, dispatchEmitContextMenuEvent: (cmd: customAction) => Promise, dispatchHandleClickFile: (path: string, type: 'file' | 'folder' | 'gist') => Promise dispatchHandleExpandPath: (paths: string[]) => Promise diff --git a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx index 904ed7cade..330270cf5e 100644 --- a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx +++ b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx @@ -5,7 +5,7 @@ import { Toaster } from '@remix-ui/toaster' // eslint-disable-line // eslint-disable-next-line @typescript-eslint/no-unused-vars import { FileSystemContext } from '../contexts' import { browserReducer, browserInitialState } from '../reducers/workspace' -import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder, deletePath, renamePath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace, fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile } from '../actions' +import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder, deletePath, renamePath, copyFile, copyFolder, runScript, runScriptWithMocha, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace, fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile } from '../actions' import { Modal, WorkspaceProps } from '../types' // eslint-disable-next-line @typescript-eslint/no-unused-vars import { Workspace } from '../remix-ui-workspace' @@ -103,6 +103,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => { await runScript(path) } + const dispatchRunScriptWithMocha = async (path: string) => { + await runScriptWithMocha(path) + } + const dispatchEmitContextMenuEvent = async (cmd: customAction) => { await emitContextMenuEvent(cmd) } @@ -212,6 +216,7 @@ export const FileSystemProvider = (props: WorkspaceProps) => { dispatchCopyFile, dispatchCopyFolder, dispatchRunScript, + dispatchRunScriptWithMocha, dispatchEmitContextMenuEvent, dispatchHandleClickFile, dispatchHandleExpandPath diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index a51224f86c..a5a84e1e1f 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -198,6 +198,7 @@ export function Workspace () { dispatchCopyFolder={global.dispatchCopyFolder} dispatchPublishToGist={global.dispatchPublishToGist} dispatchRunScript={global.dispatchRunScript} + dispatchRunScriptWithMocha={global.dispatchRunScriptWithMocha} dispatchEmitContextMenuEvent={global.dispatchEmitContextMenuEvent} dispatchHandleClickFile={global.dispatchHandleClickFile} dispatchSetFocusElement={global.dispatchSetFocusElement} @@ -233,6 +234,7 @@ export function Workspace () { dispatchCopyFolder={global.dispatchCopyFolder} dispatchPublishToGist={global.dispatchPublishToGist} dispatchRunScript={global.dispatchRunScript} + dispatchRunScriptWithMocha={global.dispatchRunScriptWithMocha} dispatchEmitContextMenuEvent={global.dispatchEmitContextMenuEvent} dispatchHandleClickFile={global.dispatchHandleClickFile} dispatchSetFocusElement={global.dispatchSetFocusElement} diff --git a/libs/remix-ui/workspace/src/lib/types/index.ts b/libs/remix-ui/workspace/src/lib/types/index.ts index bf4b24d661..5db5bd0a99 100644 --- a/libs/remix-ui/workspace/src/lib/types/index.ts +++ b/libs/remix-ui/workspace/src/lib/types/index.ts @@ -78,6 +78,7 @@ export interface FileExplorerProps { dispatchCopyFile: (src: string, dest: string) => Promise, dispatchCopyFolder: (src: string, dest: string) => Promise, dispatchRunScript: (path: string) => Promise, + dispatchRunScriptWithMocha: (path: string) => Promise, dispatchPublishToGist: (path?: string, type?: string) => Promise, dispatchEmitContextMenuEvent: (cmd: customAction) => Promise, dispatchHandleClickFile: (path: string, type: 'file' | 'folder' | 'gist') => Promise, @@ -108,6 +109,7 @@ export interface FileExplorerContextMenuProps { publishFolderToGist?: (path?: string, type?: string) => void, publishFileToGist?: (path?: string, type?: string) => void, runScript?: (path: string) => void, + runScriptWithMocha?: (path: string) => void, emit?: (cmd: customAction) => void, pageX: number, pageY: number, diff --git a/libs/remix-ui/workspace/src/lib/utils/index.ts b/libs/remix-ui/workspace/src/lib/utils/index.ts index 0dd70b14bc..f2558c1b2c 100644 --- a/libs/remix-ui/workspace/src/lib/utils/index.ts +++ b/libs/remix-ui/workspace/src/lib/utils/index.ts @@ -30,6 +30,12 @@ export const contextMenuActions: MenuItems = [{ extension: ['.js'], multiselect: false, label: '' +}, { + id: 'runWithMocha', + name: 'Run with Mocha', + extension: ['.js'], + multiselect: false, + label: '' }, { id: 'pushChangesToGist', name: 'Push changes to gist', From b4e702e7ee041b7f207624f1e87186433546d68f Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 15 Feb 2022 13:59:27 +0530 Subject: [PATCH 33/55] getArtefactsByContractName added --- libs/remix-core-plugin/src/lib/compiler-artefacts.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libs/remix-core-plugin/src/lib/compiler-artefacts.ts b/libs/remix-core-plugin/src/lib/compiler-artefacts.ts index 1198a012db..1732337394 100644 --- a/libs/remix-core-plugin/src/lib/compiler-artefacts.ts +++ b/libs/remix-core-plugin/src/lib/compiler-artefacts.ts @@ -4,7 +4,7 @@ import { CompilerAbstract } from '@remix-project/remix-solidity' const profile = { name: 'compilerArtefacts', - methods: ['get', 'addResolvedContract', 'getCompilerAbstract', 'getAllContractDatas', 'getLastCompilationResult'], + methods: ['get', 'addResolvedContract', 'getCompilerAbstract', 'getAllContractDatas', 'getLastCompilationResult', 'getArtefactsByContractName'], events: [], version: '0.0.1' } @@ -72,6 +72,16 @@ export class CompilerArtefacts extends Plugin { return contractsData } + getArtefactsByContractName (contractName) { + const contractsDataByFilename = this.getAllContractDatas() + const contractsData = Object.values(contractsDataByFilename) + if(contractsData && contractsData.length) { + const index = contractsData.findIndex((contractsObj) => Object.keys(contractsObj).includes(contractName)) + if (index != -1) return contractsData[index][contractName] + else throw new Error(`Could not find artifacts for ${contractName}. Make sure it is compiled.`) + } else throw new Error(`No contract compiled`) + } + getCompilerAbstract (file) { return this.compilersArtefactsPerFile[file] } From 36c936be0a023a83f6608e620d46c41cbca5b1fd Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 15 Feb 2022 14:41:15 +0530 Subject: [PATCH 34/55] linting fix --- libs/remix-core-plugin/src/lib/compiler-artefacts.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/remix-core-plugin/src/lib/compiler-artefacts.ts b/libs/remix-core-plugin/src/lib/compiler-artefacts.ts index 1732337394..041b98199e 100644 --- a/libs/remix-core-plugin/src/lib/compiler-artefacts.ts +++ b/libs/remix-core-plugin/src/lib/compiler-artefacts.ts @@ -75,11 +75,11 @@ export class CompilerArtefacts extends Plugin { getArtefactsByContractName (contractName) { const contractsDataByFilename = this.getAllContractDatas() const contractsData = Object.values(contractsDataByFilename) - if(contractsData && contractsData.length) { + if (contractsData && contractsData.length) { const index = contractsData.findIndex((contractsObj) => Object.keys(contractsObj).includes(contractName)) - if (index != -1) return contractsData[index][contractName] + if (index !== -1) return contractsData[index][contractName] else throw new Error(`Could not find artifacts for ${contractName}. Make sure it is compiled.`) - } else throw new Error(`No contract compiled`) + } else throw new Error('No contract compiled') } getCompilerAbstract (file) { From e23d824c338c9194a49082700f78c0a23c7e4bef Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 17 Feb 2022 13:20:29 +0530 Subject: [PATCH 35/55] fileList --- apps/remix-ide/src/app/files/fileManager.ts | 9 ++++++++- libs/remix-core-plugin/src/lib/compiler-artefacts.ts | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/app/files/fileManager.ts b/apps/remix-ide/src/app/files/fileManager.ts index d9789f4512..aff574f5a8 100644 --- a/apps/remix-ide/src/app/files/fileManager.ts +++ b/apps/remix-ide/src/app/files/fileManager.ts @@ -704,7 +704,14 @@ class FileManager extends Plugin { return collectList(path) } - isRemixDActive() { + async fileList (dirPath) { + const paths: any = await this.readdir(dirPath) + for( const path in paths) + if(paths[path].isDirectory) delete paths[path] + return paths + } + + isRemixDActive () { return this.appManager.isActive('remixd') } diff --git a/libs/remix-core-plugin/src/lib/compiler-artefacts.ts b/libs/remix-core-plugin/src/lib/compiler-artefacts.ts index 041b98199e..99abe5b7d8 100644 --- a/libs/remix-core-plugin/src/lib/compiler-artefacts.ts +++ b/libs/remix-core-plugin/src/lib/compiler-artefacts.ts @@ -77,7 +77,7 @@ export class CompilerArtefacts extends Plugin { const contractsData = Object.values(contractsDataByFilename) if (contractsData && contractsData.length) { const index = contractsData.findIndex((contractsObj) => Object.keys(contractsObj).includes(contractName)) - if (index !== -1) return contractsData[index][contractName] + if (index !== -1) return { abi: contractsData[index][contractName].abi, bytecode: contractsData[index][contractName].evm.bytecode.object } else throw new Error(`Could not find artifacts for ${contractName}. Make sure it is compiled.`) } else throw new Error('No contract compiled') } From 9a9e34df2a3d9232eeb428b11245a8d10968da26 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 17 Feb 2022 13:54:17 +0530 Subject: [PATCH 36/55] get artifacts from file explorer --- apps/remix-ide/src/app/files/fileManager.ts | 4 ++-- .../src/lib/compiler-artefacts.ts | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide/src/app/files/fileManager.ts b/apps/remix-ide/src/app/files/fileManager.ts index aff574f5a8..df40820b27 100644 --- a/apps/remix-ide/src/app/files/fileManager.ts +++ b/apps/remix-ide/src/app/files/fileManager.ts @@ -19,7 +19,7 @@ const profile = { icon: 'assets/img/fileManager.webp', permission: true, version: packageJson.version, - methods: ['closeAllFiles', 'closeFile', 'file', 'exists', 'open', 'writeFile', 'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'remove', 'getCurrentFile', 'getFile', 'getFolder', 'setFile', 'switchFile', 'refresh', 'getProviderOf', 'getProviderByName', 'getPathFromUrl', 'getUrlFromPath', 'saveCurrentFile', 'setBatchFiles'], + methods: ['closeAllFiles', 'closeFile', 'file', 'exists', 'open', 'writeFile', 'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'dirList', 'fileList', 'remove', 'getCurrentFile', 'getFile', 'getFolder', 'setFile', 'switchFile', 'refresh', 'getProviderOf', 'getProviderByName', 'getPathFromUrl', 'getUrlFromPath', 'saveCurrentFile', 'setBatchFiles'], kind: 'file-system' } const errorMsg = { @@ -708,7 +708,7 @@ class FileManager extends Plugin { const paths: any = await this.readdir(dirPath) for( const path in paths) if(paths[path].isDirectory) delete paths[path] - return paths + return Object.keys(paths) } isRemixDActive () { diff --git a/libs/remix-core-plugin/src/lib/compiler-artefacts.ts b/libs/remix-core-plugin/src/lib/compiler-artefacts.ts index 99abe5b7d8..21f2d29b1a 100644 --- a/libs/remix-core-plugin/src/lib/compiler-artefacts.ts +++ b/libs/remix-core-plugin/src/lib/compiler-artefacts.ts @@ -72,14 +72,29 @@ export class CompilerArtefacts extends Plugin { return contractsData } - getArtefactsByContractName (contractName) { + async getArtefactsFromFE (path, contractName) { + const dirList = await this.call('fileManager', 'dirList', path) + if(dirList.includes(path + '/artifacts')) { + const fileList = await this.call('fileManager', 'fileList', path + '/artifacts') + const artefactsFilePaths = fileList.filter(filePath => { + const filenameArr = filePath.split('/') + const filename = filenameArr[filenameArr.length - 1] + if (filename === `${contractName}.json` || filename === `${contractName}_metadata.json`) return true + }) + const content = await this.call('fileManager', 'readFile', artefactsFilePaths[1]) + const artifacts = JSON.parse(content) + return { abi: artifacts.abi, bytecode: artifacts.data.bytecode.object } + } + } + + async getArtefactsByContractName (contractName) { const contractsDataByFilename = this.getAllContractDatas() const contractsData = Object.values(contractsDataByFilename) if (contractsData && contractsData.length) { const index = contractsData.findIndex((contractsObj) => Object.keys(contractsObj).includes(contractName)) if (index !== -1) return { abi: contractsData[index][contractName].abi, bytecode: contractsData[index][contractName].evm.bytecode.object } else throw new Error(`Could not find artifacts for ${contractName}. Make sure it is compiled.`) - } else throw new Error('No contract compiled') + } else await this.getArtefactsFromFE ('contracts', contractName) } getCompilerAbstract (file) { From f13ccf1822ac92092253ce29d9add3685797fa2f Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 17 Feb 2022 17:02:12 +0530 Subject: [PATCH 37/55] check for artifacts in all dirs --- .../src/lib/compiler-artefacts.ts | 48 ++++++++++++++----- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/libs/remix-core-plugin/src/lib/compiler-artefacts.ts b/libs/remix-core-plugin/src/lib/compiler-artefacts.ts index 21f2d29b1a..d35fa36141 100644 --- a/libs/remix-core-plugin/src/lib/compiler-artefacts.ts +++ b/libs/remix-core-plugin/src/lib/compiler-artefacts.ts @@ -74,17 +74,31 @@ export class CompilerArtefacts extends Plugin { async getArtefactsFromFE (path, contractName) { const dirList = await this.call('fileManager', 'dirList', path) - if(dirList.includes(path + '/artifacts')) { - const fileList = await this.call('fileManager', 'fileList', path + '/artifacts') - const artefactsFilePaths = fileList.filter(filePath => { - const filenameArr = filePath.split('/') - const filename = filenameArr[filenameArr.length - 1] - if (filename === `${contractName}.json` || filename === `${contractName}_metadata.json`) return true - }) - const content = await this.call('fileManager', 'readFile', artefactsFilePaths[1]) - const artifacts = JSON.parse(content) - return { abi: artifacts.abi, bytecode: artifacts.data.bytecode.object } - } + if(dirList && dirList.length) { + if(dirList.includes(path + '/artifacts')) { + const fileList = await this.call('fileManager', 'fileList', path + '/artifacts') + const artefactsFilePaths = fileList.filter(filePath => { + const filenameArr = filePath.split('/') + const filename = filenameArr[filenameArr.length - 1] + if (filename === `${contractName}.json` || filename === `${contractName}_metadata.json`) return true + }) + if (artefactsFilePaths && artefactsFilePaths.length) { + const content = await this.call('fileManager', 'readFile', artefactsFilePaths[1]) + const artifacts = JSON.parse(content) + return { abi: artifacts.abi, bytecode: artifacts.data.bytecode.object } + } else { + for (const dirPath of dirList) { + const result = await this.getArtefactsFromFE (dirPath, contractName) + if (result) return result + } + } + } else { + for (const dirPath of dirList) { + const result = await this.getArtefactsFromFE (dirPath, contractName) + if (result) return result + } + } + } else return } async getArtefactsByContractName (contractName) { @@ -93,8 +107,16 @@ export class CompilerArtefacts extends Plugin { if (contractsData && contractsData.length) { const index = contractsData.findIndex((contractsObj) => Object.keys(contractsObj).includes(contractName)) if (index !== -1) return { abi: contractsData[index][contractName].abi, bytecode: contractsData[index][contractName].evm.bytecode.object } - else throw new Error(`Could not find artifacts for ${contractName}. Make sure it is compiled.`) - } else await this.getArtefactsFromFE ('contracts', contractName) + else { + const result = await this.getArtefactsFromFE ('contracts', contractName) + if (result) return result + else throw new Error(`Could not find artifacts for ${contractName}. Compile contract to generate artifacts.`) + } + } else { + const result = await this.getArtefactsFromFE ('contracts', contractName) + if (result) return result + else throw new Error(`Could not find artifacts for ${contractName}. Compile contract to generate artifacts.`) + } } getCompilerAbstract (file) { From 6cc3af041a6a6eff42e844143e0b1c183528918c Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 17 Feb 2022 17:12:35 +0530 Subject: [PATCH 38/55] removed local link --- apps/remix-ide/src/remixAppManager.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index 24814eb43d..ce7ea97b27 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -114,7 +114,6 @@ export class RemixAppManager extends PluginManager { const res = await fetch(this.pluginsDirectory) plugins = await res.json() plugins = plugins.filter((plugin) => { - if (plugin.name === 'scriptRunner') plugin.url = 'http://127.0.0.1:8081' if (plugin.targets && Array.isArray(plugin.targets) && plugin.targets.length > 0) { return (plugin.targets.includes('remix')) } From ffd47328e9ccca2d5b31b733ef2a01ecf211d7b0 Mon Sep 17 00:00:00 2001 From: lianahus Date: Wed, 16 Feb 2022 10:11:24 +0100 Subject: [PATCH 39/55] fixed layout of home --- libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx b/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx index 1fa810ef79..e13ed5c28b 100644 --- a/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx +++ b/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx @@ -297,7 +297,7 @@ export const RemixUiHomeTab = (props: RemixUiHomeTabProps) => {
-
+

Featured Plugins

From 6d2531654cd28b077ed9a78c9cfcf0a8448600de Mon Sep 17 00:00:00 2001 From: lianahus Date: Wed, 16 Feb 2022 11:06:03 +0100 Subject: [PATCH 40/55] fix the gap between icon sections --- .../src/lib/remix-ui-vertical-icons-panel.css | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/remix-ui/vertical-icons-panel/src/lib/remix-ui-vertical-icons-panel.css b/libs/remix-ui/vertical-icons-panel/src/lib/remix-ui-vertical-icons-panel.css index 5fd6e085ee..393ee84773 100644 --- a/libs/remix-ui/vertical-icons-panel/src/lib/remix-ui-vertical-icons-panel.css +++ b/libs/remix-ui/vertical-icons-panel/src/lib/remix-ui-vertical-icons-panel.css @@ -111,6 +111,7 @@ flex-basis: 510px; flex-grow: 2; text-align: center; + margin-top: -6px; /* border-bottom: 3px solid #3f4455; */ } .remixui_scrollbar::-webkit-scrollbar { /* Chrome, Safari and other Webkit browsers*/ From 3b4788e8d15ec1871644bada612150c996323381 Mon Sep 17 00:00:00 2001 From: lianahus Date: Thu, 17 Feb 2022 12:06:14 +0100 Subject: [PATCH 41/55] autocomplete commands after 1 symbol instead of 3 --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx index f5a2a8868a..73b5b3e424 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -382,7 +382,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const handleAutoComplete = () => (
2)) && autoCompletState.data._options.length > 0 ? 'block' : 'none' }} + style={{ display: (autoCompletState.showSuggestions && autoCompletState.userInput !== '' && (autoCompletState.userInput.length > 0)) && autoCompletState.data._options.length > 0 ? 'block' : 'none' }} >
{autoCompletState.data._options.map((item, index) => { From de2f10ba099c1561b834580da0d62000ae7c2ade Mon Sep 17 00:00:00 2001 From: lianahus Date: Fri, 18 Feb 2022 11:51:24 +0100 Subject: [PATCH 42/55] edited terminal's welcome text --- apps/remix-ide/src/lib/commands.js | 57 ------------------- libs/remix-ui/terminal/src/lib/commands.ts | 1 - .../terminal/src/lib/terminalWelcome.tsx | 4 +- 3 files changed, 3 insertions(+), 59 deletions(-) delete mode 100644 apps/remix-ide/src/lib/commands.js diff --git a/apps/remix-ide/src/lib/commands.js b/apps/remix-ide/src/lib/commands.js deleted file mode 100644 index 0f6ca3f897..0000000000 --- a/apps/remix-ide/src/lib/commands.js +++ /dev/null @@ -1,57 +0,0 @@ -const allPrograms = [ - { ethers: 'The ethers.js library is a compact and complete JavaScript library for Ethereum.' }, - { remix: 'Ethereum IDE and tools for the web.' }, - { web3: 'The web3.js library is a collection of modules which contain specific functionality for the ethereum ecosystem.' }, - { swarmgw: 'This library can be used to upload/download files to Swarm via https://swarm-gateways.net/.' } -] - -const allCommands = [ - { 'remix.execute(filepath)': 'Run the script specified by file path. If filepath is empty, script currently displayed in the editor is executed.' }, - { 'remix.exeCurrent()': 'Run the script currently displayed in the editor.' }, - { 'remix.help()': 'Display this help message.' }, - { 'remix.loadgist(id)': 'Load a gist in the file explorer.' }, - { 'remix.loadurl(url)': 'Load the given url in the file explorer. The url can be of type github, swarm or ipfs.' }, - - { 'swarmgw.get(url, cb)': 'Download files from Swarm via https://swarm-gateways.net/' }, - { 'swarmgw.put(content, cb)': 'Upload files to Swarm via https://swarm-gateways.net/' }, - - { 'ethers.Contract': 'This API provides a graceful connection to a contract deployed on the blockchain, simplifying calling and querying its functions and handling all the binary protocol and conversion as necessarily.' }, - { 'ethers.HDNode': 'A Hierarchical Deterministic Wallet represents a large tree of private keys which can reliably be reproduced from an initial seed.' }, - { 'ethers.Interface': 'The Interface Object is a meta-class that accepts a Solidity (or compatible) Application Binary Interface (ABI) and populates functions to deal with encoding and decoding the parameters to pass in and results returned.' }, - { 'ethers.providers': 'A Provider abstracts a connection to the Ethereum blockchain, for issuing queries and sending state changing transactions.' }, - { 'ethers.SigningKey': 'The SigningKey interface provides an abstraction around the secp256k1 elliptic curve cryptography library.' }, - { 'ethers.utils': 'The utility functions exposed in both the ethers umbrella package and the ethers-utils.' }, - { 'ethers.utils.AbiCoder': 'Create a new ABI Coder object' }, - { 'ethers.utils.RLP': 'This encoding method is used internally for several aspects of Ethereum, such as encoding transactions and determining contract addresses.' }, - { 'ethers.Wallet': 'A wallet manages a private/public key pair which is used to cryptographically sign transactions and prove ownership on the Ethereum network.' }, - { 'ethers.version': 'Contains the version of the ethers container object.' }, - - { 'web3.eth': 'Eth module for interacting with the Ethereum network.' }, - { 'web3.eth.accounts': 'The web3.eth.accounts contains functions to generate Ethereum accounts and sign transactions and data.' }, - { 'web3.eth.abi': 'The web3.eth.abi functions let you de- and encode parameters to ABI (Application Binary Interface) for function calls to the EVM (Ethereum Virtual Machine).' }, - { 'web3.eth.ens': 'The web3.eth.ens functions let you interacting with ENS.' }, - { 'web3.eth.Iban': 'The web3.eth.Iban function lets convert Ethereum addresses from and to IBAN and BBAN.' }, - { 'web3.eth.net': 'Net module for interacting with network properties.' }, - { 'web3.eth.personal': 'Personal module for interacting with the Ethereum accounts.' }, - { 'web3.eth.subscribe': 'The web3.eth.subscribe function lets you subscribe to specific events in the blockchain.' }, - { 'web3.givenProvider': 'When using web3.js in an Ethereum compatible browser, it will set with the current native provider by that browser. Will return the given provider by the (browser) environment, otherwise null.' }, - { 'web3.modules': 'Contains the version of the web3 container object.' }, - { 'web3.providers': 'Contains the current available providers.' }, - { 'web3.shh': 'Shh module for interacting with the whisper protocol' }, - { 'web3.utils': 'This package provides utility functions for Ethereum dapps and other web3.js packages.' }, - { 'web3.version': 'Contains the version of the web3 container object.' }, - - { 'web3.eth.clearSubscriptions();': 'Resets subscriptions.' }, - { 'web3.eth.Contract(jsonInterface[, address][, options])': 'The web3.eth.Contract object makes it easy to interact with smart contracts on the ethereum blockchain.' }, - { 'web3.eth.accounts.create([entropy]);': 'The web3.eth.accounts contains functions to generate Ethereum accounts and sign transactions and data.' }, - { 'web3.eth.getAccounts();': 'Retrieve the list of accounts' }, - { 'web3.eth.accounts.privateKeyToAccount(privateKey [, ignoreLength ]);': 'Get the account from the private key' }, - { 'web3.eth.accounts.signTransaction(tx, privateKey [, callback]);': 'Sign Transaction' }, - { 'web3.eth.accounts.recoverTransaction(rawTransaction);': 'Sign Transaction' }, - { 'web3.eth.accounts.hashMessage(message);': 'Hash message' } -] - -module.exports = { - allPrograms, - allCommands -} diff --git a/libs/remix-ui/terminal/src/lib/commands.ts b/libs/remix-ui/terminal/src/lib/commands.ts index cc3b5e6963..0dc02b371b 100644 --- a/libs/remix-ui/terminal/src/lib/commands.ts +++ b/libs/remix-ui/terminal/src/lib/commands.ts @@ -8,7 +8,6 @@ export const allPrograms = [ export const allCommands = [ { 'remix.execute(filepath)': 'Run the script specified by file path. If filepath is empty, script currently displayed in the editor is executed.' }, { 'remix.exeCurrent()': 'Run the script currently displayed in the editor.' }, - // { 'remix.help()': 'Display this help message.' }, { 'remix.loadgist(id)': 'Load a gist in the file explorer.' }, // { 'remix.loadurl(url)': 'Load the given url in the file explorer. The url can be of type github, swarm or ipfs.' }, diff --git a/libs/remix-ui/terminal/src/lib/terminalWelcome.tsx b/libs/remix-ui/terminal/src/lib/terminalWelcome.tsx index f222aca38e..2b2eba1c86 100644 --- a/libs/remix-ui/terminal/src/lib/terminalWelcome.tsx +++ b/libs/remix-ui/terminal/src/lib/terminalWelcome.tsx @@ -16,12 +16,14 @@ const TerminalWelcomeMessage = ({ packageJson }) => { - Right click on a JavaScript file in the file explorer and then click \`Run\` +
The following libraries are accessible:
+
Type the library name to see available commands.
) } From c4068ce358c7127057d30135e2dfa1d5f4523f46 Mon Sep 17 00:00:00 2001 From: lianahus Date: Fri, 18 Feb 2022 12:06:04 +0100 Subject: [PATCH 43/55] style --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.css | 3 +++ libs/remix-ui/terminal/src/lib/terminalWelcome.tsx | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css index 0ffe440548..13402e45ee 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -53,6 +53,9 @@ element.style { .remix_ui_terminal_block > pre { max-height : 200px; } +.remix_ui_terminal_welcome { + font-weight: bold; +} .remix_ui_terminal_cli { white-space : nowrap; line-height : 1.7em; diff --git a/libs/remix-ui/terminal/src/lib/terminalWelcome.tsx b/libs/remix-ui/terminal/src/lib/terminalWelcome.tsx index 2b2eba1c86..8a18545f67 100644 --- a/libs/remix-ui/terminal/src/lib/terminalWelcome.tsx +++ b/libs/remix-ui/terminal/src/lib/terminalWelcome.tsx @@ -3,7 +3,7 @@ import React from 'react' // eslint-disable-line const TerminalWelcomeMessage = ({ packageJson }) => { return (
-
- Welcome to Remix {packageJson} -

+
Welcome to Remix {packageJson}

You can use this terminal to:
  • Check transactions details and start debugging.
  • From 53ad0354653933786e737664d535a957191afa80 Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 18 Feb 2022 19:55:11 +0100 Subject: [PATCH 44/55] fix retrieving events abi --- libs/remix-lib/src/execution/eventsDecoder.ts | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/libs/remix-lib/src/execution/eventsDecoder.ts b/libs/remix-lib/src/execution/eventsDecoder.ts index 833cf189f0..4622b245fd 100644 --- a/libs/remix-lib/src/execution/eventsDecoder.ts +++ b/libs/remix-lib/src/execution/eventsDecoder.ts @@ -56,18 +56,19 @@ export class EventsDecoder { return eventsABI } - _event (hash, eventsABI) { - for (const k in eventsABI) { - if (eventsABI[k][hash]) { - const event = eventsABI[k][hash] - for (const input of event.inputs) { - if (input.type === 'function') { - input.type = 'bytes24' - input.baseType = 'bytes24' - } + _event (hash: string, eventsABI: Record, contractName: string) { + const events = eventsABI[contractName] + if (!events) return null + + if (events[hash]) { + const event = events[hash] + for (const input of event.inputs) { + if (input.type === 'function') { + input.type = 'bytes24' + input.baseType = 'bytes24' } - return event } + return event } return null } @@ -94,7 +95,7 @@ export class EventsDecoder { // [address, topics, mem] const log = logs[i] const topicId = log.topics[0] - const eventAbi = this._event(topicId.replace('0x', ''), eventsABI) + const eventAbi = this._event(topicId.replace('0x', ''), eventsABI, contractName) if (eventAbi) { const decodedlog = eventAbi.abi.parseLog(log) const decoded = {} From 746b8fb3602f73bb4c320c7f43c8b518ae616bfc Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 9 Feb 2022 10:12:43 +0100 Subject: [PATCH 45/55] add mote time for debugger related api calls --- apps/remix-ide/src/remixEngine.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/remix-ide/src/remixEngine.js b/apps/remix-ide/src/remixEngine.js index cbdf6c86c6..63e94d8669 100644 --- a/apps/remix-ide/src/remixEngine.js +++ b/apps/remix-ide/src/remixEngine.js @@ -15,6 +15,8 @@ export class RemixEngine extends Engine { if (name === 'hardhat') return { queueTimeout: 60000 * 4 } if (name === 'localPlugin') return { queueTimeout: 60000 * 4 } if (name === 'notification') return { queueTimeout: 60000 * 4 } + if (name === 'sourcify') return { queueTimeout: 60000 * 4 } + if (name === 'fetchAndCompile') return { queueTimeout: 60000 * 4 } return { queueTimeout: 10000 } } From 8730a4cb1ff1ecc5a94708adb434c5520eaf44e3 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 9 Feb 2022 10:12:59 +0100 Subject: [PATCH 46/55] fix optimizer settings --- libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts b/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts index 63a7880382..c6a8a6156b 100644 --- a/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts +++ b/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts @@ -108,7 +108,7 @@ export class FetchAndCompile extends Plugin { language: data.metadata.language, evmVersion: data.metadata.settings.evmVersion, optimize: data.metadata.settings.optimizer.enabled, - runs: data.metadata.settings.runs + runs: data.metadata.settings.optimizer.runs } try { setTimeout(_ => this.emit('compiling', settings), 0) From a41e698eba544c62d870ae8b2ea89365eae91d91 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 9 Feb 2022 10:13:21 +0100 Subject: [PATCH 47/55] fix reseting source location --- libs/remix-debug/src/debugger/debugger.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libs/remix-debug/src/debugger/debugger.ts b/libs/remix-debug/src/debugger/debugger.ts index 231c2d57f2..b77963d302 100644 --- a/libs/remix-debug/src/debugger/debugger.ts +++ b/libs/remix-debug/src/debugger/debugger.ts @@ -68,7 +68,10 @@ export class Debugger { try { const address = this.debugger.traceManager.getCurrentCalledAddressAt(index) const compilationResultForAddress = await this.compilationResult(address) - if (!compilationResultForAddress) return + if (!compilationResultForAddress) { + this.event.trigger('newSourceLocation', [null]) + return + } this.debugger.callTree.sourceLocationTracker.getValidSourceLocationFromVMTraceIndex(address, index, compilationResultForAddress.data.contracts).then(async (rawLocation) => { if (compilationResultForAddress && compilationResultForAddress.data) { @@ -91,6 +94,7 @@ export class Debugger { }) // }) } catch (error) { + this.event.trigger('newSourceLocation', [null]) return console.log(error) } } From c494d02225a651aa21335d9cee98510d1b2a43ca Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 9 Feb 2022 10:13:34 +0100 Subject: [PATCH 48/55] fix getting the storage --- libs/remix-debug/src/storage/storageResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-debug/src/storage/storageResolver.ts b/libs/remix-debug/src/storage/storageResolver.ts index 62a9f7df32..c5522f37f9 100644 --- a/libs/remix-debug/src/storage/storageResolver.ts +++ b/libs/remix-debug/src/storage/storageResolver.ts @@ -133,7 +133,7 @@ export class StorageResolver { resolve([{}, null]) } else { this.web3.debug.storageRangeAt( - tx.blockHash, tx.hash, + tx.blockHash, tx.transactionIndex, address, start, maxSize, From f6b7fb035dee1feb769951517a618d279e8668b7 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 16 Feb 2022 13:18:17 +0100 Subject: [PATCH 49/55] display source location status --- .../debugger-ui/src/lib/debugger-ui.tsx | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) 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 a9a8200e9b..de26b84af9 100644 --- a/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx @@ -32,7 +32,8 @@ export const DebuggerUI = (props: DebuggerUIProps) => { toastMessage: '', validationError: '', txNumberIsEmpty: true, - isLocalNodeUsed: false + isLocalNodeUsed: false, + sourceLocationStatus: '' }) useEffect(() => { @@ -87,7 +88,13 @@ export const DebuggerUI = (props: DebuggerUIProps) => { }) debuggerInstance.event.register('newSourceLocation', async (lineColumnPos, rawLocation, generatedSources, address) => { - if (!lineColumnPos) return + if (!lineColumnPos) { + await debuggerModule.discardHighlight() + setState(prevState => { + return { ...prevState, sourceLocationStatus: 'Source location not available.' } + }) + return + } const contracts = await debuggerModule.fetchContractAndCompile( address || currentReceipt.contractAddress || currentReceipt.to, currentReceipt) @@ -113,6 +120,9 @@ export const DebuggerUI = (props: DebuggerUIProps) => { } } if (path) { + setState(prevState => { + return { ...prevState, sourceLocationStatus: '' } + }) await debuggerModule.discardHighlight() await debuggerModule.highlight(lineColumnPos, path) } @@ -138,6 +148,12 @@ export const DebuggerUI = (props: DebuggerUIProps) => { const unloadRequested = (blockNumber, txIndex, tx) => { unLoad() + setState(prevState => { + return { + ...prevState, + sourceLocationStatus: '' + } + }) } const unLoad = () => { @@ -168,7 +184,8 @@ export const DebuggerUI = (props: DebuggerUIProps) => { setState(prevState => { return { ...prevState, - txNumber: txNumber + txNumber: txNumber, + sourceLocationStatus: '' } }) if (!isValidHash(txNumber)) { @@ -266,7 +283,8 @@ export const DebuggerUI = (props: DebuggerUIProps) => { return { ...prevState, validationError: '', - txNumber: txHash + txNumber: txHash, + sourceLocationStatus: '' } }) startDebugging(null, txHash, null, web3) @@ -315,6 +333,7 @@ export const DebuggerUI = (props: DebuggerUIProps) => { { state.validationError && {state.validationError} }
+ { state.debugging && state.sourceLocationStatus &&
{state.sourceLocationStatus}
} { state.debugging && } { state.debugging && }
From 34dd9cedfd8685201b3afc55ddbdadc531f52493 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 16 Feb 2022 13:50:49 +0100 Subject: [PATCH 50/55] fix displaying reverted calls in debugger --- libs/remix-debug/src/debugger/stepManager.ts | 13 ++++++++----- .../src/lib/button-navigator/button-navigator.css | 4 ++++ .../src/lib/button-navigator/button-navigator.tsx | 9 ++++----- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/libs/remix-debug/src/debugger/stepManager.ts b/libs/remix-debug/src/debugger/stepManager.ts index 1a64977e97..6fd2e5fa22 100644 --- a/libs/remix-debug/src/debugger/stepManager.ts +++ b/libs/remix-debug/src/debugger/stepManager.ts @@ -51,15 +51,18 @@ export class DebuggerStepManager { this.traceManager.buildCallPath(index).then((callsPath) => { this.currentCall = callsPath[callsPath.length - 1] if (this.currentCall.reverted) { - const revertedReason = this.currentCall.outofgas ? 'outofgas' : '' + const revertedReason = this.currentCall.outofgas ? 'outofgas' : 'reverted' this.revertionPoint = this.currentCall.return - return this.event.trigger('revertWarning', [revertedReason]) + this.event.trigger('revertWarning', [revertedReason]) + return } for (let k = callsPath.length - 2; k >= 0; k--) { const parent = callsPath[k] - if (!parent.reverted) continue - this.revertionPoint = parent.return - this.event.trigger('revertWarning', ['parenthasthrown']) + if (parent.reverted) { + this.revertionPoint = parent.return + this.event.trigger('revertWarning', ['parenthasthrown']) + return + } } this.event.trigger('revertWarning', ['']) }).catch((error) => { diff --git a/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.css b/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.css index 8990810a9e..835b54615b 100644 --- a/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.css +++ b/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.css @@ -19,4 +19,8 @@ .navigator { } .navigator:hover { +} + +.cursorPointerRemixDebugger { + cursor: pointer; } \ No newline at end of file diff --git a/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx b/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx index 680c3b9ef8..5200de41f7 100644 --- a/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx @@ -65,11 +65,10 @@ export const ButtonNavigation = ({ stepOverBack, stepIntoBack, stepIntoForward,
- - State changes made during this call will be reverted. - This call will run out of gas. - The parent call will throw an exception + This call has reverted, state changes made during the call will be reverted. + This call will run out of gas. + The parent call will throw an exception +
Click { jumpToException && jumpToException() }}>here to jump where the call reverted.
) From d76d77b083af05ce391fa6cfd737bf77ac883d4c Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 17 Feb 2022 10:36:06 +0100 Subject: [PATCH 51/55] stop updating the debugger for every slider update --- .../debugger-ui/src/lib/slider/slider.tsx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/libs/remix-ui/debugger-ui/src/lib/slider/slider.tsx b/libs/remix-ui/debugger-ui/src/lib/slider/slider.tsx index 81e036a8b8..06fe05e949 100644 --- a/libs/remix-ui/debugger-ui/src/lib/slider/slider.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/slider/slider.tsx @@ -1,10 +1,12 @@ -import React, { useState, useEffect } from 'react' // eslint-disable-line +import React, { useState, useEffect, useRef } from 'react' // eslint-disable-line export const Slider = ({ jumpTo, sliderValue, traceLength }) => { const [state, setState] = useState({ currentValue: 0 }) + const onChangeId = useRef(null) + useEffect(() => { setValue(sliderValue) }, [sliderValue]) @@ -18,9 +20,16 @@ export const Slider = ({ jumpTo, sliderValue, traceLength }) => { } const handleChange = (e) => { - const value = parseInt(e.target.value) - - setValue(value) + if (onChangeId.current) { + window.clearTimeout(onChangeId.current) + } + ((value) => { + onChangeId.current = setTimeout(() => { + console.log(value) + value = parseInt(value) + setValue(value) + }, 100) + })(e.target.value) } return ( From 164715c3e25ccfde3f869d4af82da6bba5c9d16a Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 17 Feb 2022 11:13:13 +0100 Subject: [PATCH 52/55] fix e2e --- apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts b/apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts index e84ab52367..688ac7a635 100644 --- a/apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts +++ b/apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts @@ -12,6 +12,7 @@ class GoToVmTraceStep extends EventEmitter { function goToVMtraceStep (browser: NightwatchBrowser, step: number, incr: number, done: VoidFunction) { browser.execute(function (step) { (document.getElementById('slider') as HTMLInputElement).value = (step - 1).toString() }, [step]) .setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW)) + .pause(500) .perform(() => { done() }) From 526ed2aacb97d59185309f29e84f7e4f11058b38 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 17 Feb 2022 16:34:37 +0100 Subject: [PATCH 53/55] refactor Web3VmProvider to VmProxy --- apps/remix-ide-e2e/src/tests/debugger.test.ts | 20 +------ .../src/tests/solidityUnittests.test.ts | 16 ++---- libs/remix-debug/src/Ethdebugger.ts | 1 - libs/remix-lib/README.md | 5 -- libs/remix-lib/src/index.ts | 11 +--- .../src/web3Provider/dummyProvider.ts | 55 ------------------- .../src/web3Provider/web3Providers.ts | 38 ------------- .../src/VmProxy.ts} | 49 ++++++++++------- libs/remix-simulator/src/vm-context.ts | 40 +++++++++----- 9 files changed, 65 insertions(+), 170 deletions(-) delete mode 100644 libs/remix-lib/src/web3Provider/dummyProvider.ts delete mode 100644 libs/remix-lib/src/web3Provider/web3Providers.ts rename libs/{remix-lib/src/web3Provider/web3VmProvider.ts => remix-simulator/src/VmProxy.ts} (89%) diff --git a/apps/remix-ide-e2e/src/tests/debugger.test.ts b/apps/remix-ide-e2e/src/tests/debugger.test.ts index cd3fafc3b3..e9292689e8 100644 --- a/apps/remix-ide-e2e/src/tests/debugger.test.ts +++ b/apps/remix-ide-e2e/src/tests/debugger.test.ts @@ -39,10 +39,7 @@ module.exports = { 'Should debug transaction using slider #group1': function (browser: NightwatchBrowser) { browser.waitForElementVisible('*[data-id="verticalIconsKindudapp"]') .waitForElementVisible('*[data-id="slider"]') - // eslint-disable-next-line dot-notation - .execute(function () { document.getElementById('slider')['value'] = '50' }) // It only moves slider to 50 but vm traces are not updated - .setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW)) - .pause(2000) + .goToVMTraceStep(51) .click('*[data-id="dropdownPanelSolidityLocals"]') .waitForElementContainsText('*[data-id="solidityLocals"]', 'no locals', 60000) .waitForElementContainsText('*[data-id="stepdetail"]', 'vm trace step:\n51', 60000) @@ -159,10 +156,7 @@ module.exports = { .pause(2000) .debugTransaction(0) .waitForElementVisible('*[data-id="slider"]').pause(2000) - // .setValue('*[data-id="slider"]', '5000') // Like this, setValue doesn't work properly for input type = range - // eslint-disable-next-line dot-notation - .execute(function () { document.getElementById('slider')['value'] = '7450' }).pause(10000) // It only moves slider to 7450 but vm traces are not updated - .setValue('*[data-id="slider"]', new Array(3).fill(browser.Keys.RIGHT_ARROW)) // This will press NEXT 3 times and will update the trace details + .goToVMTraceStep(7453) .waitForElementPresent('*[data-id="treeViewDivtreeViewItemarray"]') .click('*[data-id="treeViewDivtreeViewItemarray"]') .waitForElementPresent('*[data-id="treeViewDivtreeViewLoadMore"]') @@ -210,15 +204,7 @@ module.exports = { .pause(3000) .clickLaunchIcon('debugger') .waitForElementVisible('*[data-id="slider"]') - // eslint-disable-next-line dot-notation - .execute(function () { document.getElementById('slider')['value'] = '153' }) // It only moves slider to 153 but vm traces are not updated - .setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW)) - .pause(1000) - /* - setting the slider to 5 leads to "vm trace step: 91" for chrome and "vm trace step: 92" for firefox - => There is something going wrong with the nightwatch API here. - As we are only testing if debugger is active, this is ok to keep that for now. - */ + .goToVMTraceStep(154) .waitForElementContainsText('*[data-id="stepdetail"]', 'vm trace step:\n154', 60000) }, diff --git a/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts b/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts index 30d1a2c83c..bc1bb12cd7 100644 --- a/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts +++ b/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts @@ -283,9 +283,7 @@ module.exports = { .waitForElementVisible('*[data-id="dropdownPanelSolidityLocals"]').pause(1000) .click('*[data-id="dropdownPanelSolidityLocals"]') .waitForElementContainsText('*[data-id="solidityLocals"]', 'no locals', 60000) - // eslint-disable-next-line dot-notation - .execute(function () { document.getElementById('slider')['value'] = '315' }) // It only moves slider to 315 but vm traces are not updated - .setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW)) + .goToVMTraceStep(316) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalFailed()', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'vote(proposal)', 60000) .pause(5000) @@ -295,9 +293,7 @@ module.exports = { .scrollAndClick('#Check_winning_proposal_passed') .waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalPassed()', 60000) - // eslint-disable-next-line dot-notation - .execute(function () { document.getElementById('slider')['value'] = '1450' }) - .setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW)) + .goToVMTraceStep(1451) .waitForElementContainsText('*[data-id="functionPanel"]', 'equal(a, b, message)', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalPassed()', 60000) // remix_test.sol should be opened in editor @@ -307,9 +303,7 @@ module.exports = { .scrollAndClick('#Check_winning_proposal_again') .waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalAgain()', 60000) - // eslint-disable-next-line dot-notation - .execute(function () { document.getElementById('slider')['value'] = '1150' }) - .setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW)) + .goToVMTraceStep(1151) .waitForElementContainsText('*[data-id="functionPanel"]', 'equal(a, b, message)', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalAgain()', 60000) .pause(5000) @@ -317,9 +311,7 @@ module.exports = { .scrollAndClick('#Check_winnin_proposal_with_return_value').pause(5000) .waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinninProposalWithReturnValue()', 60000) - // eslint-disable-next-line dot-notation - .execute(function () { document.getElementById('slider')['value'] = '320' }) - .setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW)) + .goToVMTraceStep(321) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinninProposalWithReturnValue()', 60000) .clickLaunchIcon('filePanel') .pause(2000) diff --git a/libs/remix-debug/src/Ethdebugger.ts b/libs/remix-debug/src/Ethdebugger.ts index 0026c97ee9..e0f1a92ab5 100644 --- a/libs/remix-debug/src/Ethdebugger.ts +++ b/libs/remix-debug/src/Ethdebugger.ts @@ -11,7 +11,6 @@ import { SolidityProxy, stateDecoder, localDecoder, InternalCallTree } from './s /** * Ethdebugger is a wrapper around a few classes that helps debugging a transaction * - * - Web3Providers - define which environment (web3) the transaction will be retrieved from * - TraceManager - Load / Analyze the trace and retrieve details of specific test * - CodeManager - Retrieve loaded byte code and help to resolve AST item from vmtrace index * - SolidityProxy - Basically used to extract state variable from AST diff --git a/libs/remix-lib/README.md b/libs/remix-lib/README.md index 35be57053c..31075ad154 100644 --- a/libs/remix-lib/README.md +++ b/libs/remix-lib/README.md @@ -23,11 +23,6 @@ ui: uiHelper, compiler: compilerHelper }, - vm: { - Web3Providers: Web3Providers, - DummyProvider: DummyProvider, - Web3VMProvider: Web3VmProvider - }, Storage: Storage, util: util, execution: { diff --git a/libs/remix-lib/src/index.ts b/libs/remix-lib/src/index.ts index 54646e326e..1f2cdb6676 100644 --- a/libs/remix-lib/src/index.ts +++ b/libs/remix-lib/src/index.ts @@ -2,9 +2,6 @@ import { EventManager } from './eventManager' import * as uiHelper from './helpers/uiHelper' import * as compilerHelper from './helpers/compilerHelper' import * as util from './util' -import { Web3Providers } from './web3Provider/web3Providers' -import { DummyProvider } from './web3Provider/dummyProvider' -import { Web3VmProvider } from './web3Provider/web3VmProvider' import { Storage } from './storage' import { EventsDecoder } from './execution/eventsDecoder' import * as txExecution from './execution/txExecution' @@ -18,6 +15,7 @@ import * as typeConversion from './execution/typeConversion' import { TxRunnerVM } from './execution/txRunnerVM' import { TxRunnerWeb3 } from './execution/txRunnerWeb3' import * as txResultHelper from './helpers/txResultHelper' +export { ConsoleLogs } from './helpers/hhconsoleSigs' export { ICompilerApi, ConfigurationSettings } from './types/ICompilerApi' export { QueryParams } from './query-params' @@ -26,11 +24,6 @@ const helpers = { compiler: compilerHelper, txResultHelper } -const vm = { - Web3Providers: Web3Providers, - DummyProvider: DummyProvider, - Web3VMProvider: Web3VmProvider -} const execution = { EventsDecoder: EventsDecoder, txExecution: txExecution, @@ -44,4 +37,4 @@ const execution = { LogsManager, forkAt } -export { EventManager, helpers, vm, Storage, util, execution } +export { EventManager, helpers, Storage, util, execution } diff --git a/libs/remix-lib/src/web3Provider/dummyProvider.ts b/libs/remix-lib/src/web3Provider/dummyProvider.ts deleted file mode 100644 index c6e4ec8d82..0000000000 --- a/libs/remix-lib/src/web3Provider/dummyProvider.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class DummyProvider { - eth - debug - providers - currentProvider - - constructor () { - this.eth = {} - this.debug = {} - this.eth.getCode = (address, cb) => { return this.getCode(address, cb) } - this.eth.getTransaction = (hash, cb) => { return this.getTransaction(hash, cb) } - this.eth.getTransactionFromBlock = (blockNumber, txIndex, cb) => { return this.getTransactionFromBlock(blockNumber, txIndex, cb) } - this.eth.getBlockNumber = (cb) => { return this.getBlockNumber(cb) } - this.debug.traceTransaction = (hash, options, cb) => { return this.traceTransaction(hash, options, cb) } - this.debug.storageRangeAt = (blockNumber, txIndex, address, start, end, maxLength, cb) => { return this.storageRangeAt(blockNumber, txIndex, address, start, end, maxLength, cb) } - this.providers = { HttpProvider: function (url) {} } - this.currentProvider = { host: '' } - } - - getCode (address, cb) { - cb(null, '') - } - - setProvider (provider) {} - - traceTransaction (txHash, options, cb) { - if (cb) { - cb(null, {}) - } - return {} - } - - storageRangeAt (blockNumber, txIndex, address, start, end, maxLength, cb) { - if (cb) { - cb(null, {}) - } - return {} - } - - getBlockNumber (cb) { cb(null, '') } - - getTransaction (txHash, cb) { - if (cb) { - cb(null, {}) - } - return {} - } - - getTransactionFromBlock (blockNumber, txIndex, cb) { - if (cb) { - cb(null, {}) - } - return {} - } -} diff --git a/libs/remix-lib/src/web3Provider/web3Providers.ts b/libs/remix-lib/src/web3Provider/web3Providers.ts deleted file mode 100644 index dc68edb434..0000000000 --- a/libs/remix-lib/src/web3Provider/web3Providers.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Web3VmProvider } from './web3VmProvider' -import { loadWeb3, extendWeb3 } from '../init' - -export class Web3Providers { - modes - constructor () { - this.modes = {} - } - - addProvider (type, obj) { - if (type === 'INTERNAL') { - const web3 = loadWeb3() - this.addWeb3(type, web3) - } else if (type === 'vm') { - this.addVM(type, obj) - } else { - extendWeb3(obj) - this.addWeb3(type, obj) - } - } - - get (type, cb) { - if (this.modes[type]) { - return cb(null, this.modes[type]) - } - cb('error: this provider has not been setup (' + type + ')', null) - } - - addWeb3 (type, web3) { - this.modes[type] = web3 - } - - addVM (type, vm) { - const vmProvider = new Web3VmProvider() - vmProvider.setVM(vm) - this.modes[type] = vmProvider - } -} diff --git a/libs/remix-lib/src/web3Provider/web3VmProvider.ts b/libs/remix-simulator/src/VmProxy.ts similarity index 89% rename from libs/remix-lib/src/web3Provider/web3VmProvider.ts rename to libs/remix-simulator/src/VmProxy.ts index ecc006da9e..f7090d8b1d 100644 --- a/libs/remix-lib/src/web3Provider/web3VmProvider.ts +++ b/libs/remix-simulator/src/VmProxy.ts @@ -1,12 +1,16 @@ -import { hexListFromBNs, formatMemory } from '../util' -import { normalizeHexAddress } from '../helpers/uiHelper' -import { ConsoleLogs } from '../helpers/hhconsoleSigs' +import { util } from '@remix-project/remix-lib' +const { hexListFromBNs, formatMemory } = util +import { helpers } from '@remix-project/remix-lib' +const { normalizeHexAddress } = helpers.ui +import { ConsoleLogs } from '@remix-project/remix-lib' import { toChecksumAddress, BN, bufferToHex, Address } from 'ethereumjs-util' import Web3 from 'web3' import { ethers } from 'ethers' +import { VMContext } from './vm-context' -export class Web3VmProvider { - web3 +export class VmProxy { + vmContext: VMContext + web3: Web3 vm vmTraces txs @@ -38,7 +42,8 @@ export class Web3VmProvider { blocks latestBlockNumber - constructor () { + constructor (vmContext: VMContext) { + this.vmContext = vmContext this.web3 = new Web3() this.vm = null this.vmTraces = {} @@ -66,15 +71,15 @@ export class Web3VmProvider { this.lastProcessedStorageTxHash = {} this.sha3Preimages = {} // util - this.sha3 = (...args) => this.web3.utils.sha3(...args) - this.toHex = (...args) => this.web3.utils.toHex(...args) - this.toAscii = (...args) => this.web3.utils.hexToAscii(...args) - this.fromAscii = (...args) => this.web3.utils.asciiToHex(...args) - this.fromDecimal = (...args) => this.web3.utils.numberToHex(...args) - this.fromWei = (...args) => this.web3.utils.fromWei(...args) - this.toWei = (...args) => this.web3.utils.toWei(...args) - this.toBigNumber = (...args) => this.web3.utils.toBN(...args) - this.isAddress = (...args) => this.web3.utils.isAddress(...args) + this.sha3 = (...args) => this.web3.utils.sha3.apply(this, args) + this.toHex = (...args) => this.web3.utils.toHex.apply(this, args) + this.toAscii = (...args) => this.web3.utils.toAscii.apply(this, args) + this.fromAscii = (...args) => this.web3.utils.fromAscii.apply(this, args) + this.fromDecimal = (...args) => this.web3.utils.fromDecimal.apply(this, args) + this.fromWei = (...args) => this.web3.utils.fromWei.apply(this, args) + this.toWei = (...args) => this.web3.utils.toWei.apply(this, args) + this.toBigNumber = (...args) => this.web3.utils.toBN.apply(this, args) + this.isAddress = (...args) => this.web3.utils.isAddress.apply(this, args) this.utils = Web3.utils || [] this.txsMapBlock = {} this.blocks = {} @@ -289,16 +294,22 @@ export class Web3VmProvider { } } - storageRangeAt (blockNumber, txIndex, address, start, maxLength, cb) { // txIndex is the hash in the case of the VM + storageRangeAt (blockNumber, txIndex, address, start, maxLength, cb) { // we don't use the range params here address = toChecksumAddress(address) + let txHash if (txIndex === 'latest') { - txIndex = this.lastProcessedStorageTxHash[address] + txHash = this.lastProcessedStorageTxHash[address] + } else { + const block = this.vmContext.blocks[blockNumber] + txHash = '0x' + block.transactions[txIndex].hash().toString('hex') } + + - if (this.storageCache[txIndex] && this.storageCache[txIndex][address]) { - const storage = this.storageCache[txIndex][address] + if (this.storageCache[txHash] && this.storageCache[txHash][address]) { + const storage = this.storageCache[txHash][address] return cb(null, { storage: JSON.parse(JSON.stringify(storage)), nextKey: null diff --git a/libs/remix-simulator/src/vm-context.ts b/libs/remix-simulator/src/vm-context.ts index e862fd0e3f..9e9afdef0a 100644 --- a/libs/remix-simulator/src/vm-context.ts +++ b/libs/remix-simulator/src/vm-context.ts @@ -2,11 +2,15 @@ 'use strict' import Web3 from 'web3' import { rlp, keccak, bufferToHex } from 'ethereumjs-util' -import { vm as remixLibVm, execution } from '@remix-project/remix-lib' +import { execution } from '@remix-project/remix-lib' +const { LogsManager } = execution +import { VmProxy } from './VmProxy' import VM from '@ethereumjs/vm' import Common from '@ethereumjs/common' import StateManager from '@ethereumjs/vm/dist/state/stateManager' import { StorageDump } from '@ethereumjs/vm/dist/state/interface' +import { Block } from '@ethereumjs/block' +import { Transaction } from '@ethereumjs/tx' /* extend vm state manager and instanciate VM @@ -75,6 +79,13 @@ class StateManagerCommonStorageDump extends StateManager { } } +export type CurrentVm = { + vm: VM, + web3vm: VmProxy, + stateManager: StateManagerCommonStorageDump, + common: Common +} + /* trigger contextChanged, web3EndpointChanged */ @@ -82,15 +93,14 @@ export class VMContext { currentFork: string blockGasLimitDefault: number blockGasLimit: number - customNetWorks - blocks - latestBlockNumber - blockByTxHash - txByHash - currentVm - web3vm - logsManager - exeResults + blocks: Record + latestBlockNumber: string + blockByTxHash: Record + txByHash: Record + currentVm: CurrentVm + web3vm: VmProxy + logsManager: any // LogsManager + exeResults: Record constructor (fork?) { this.blockGasLimitDefault = 4300000 @@ -98,11 +108,11 @@ export class VMContext { this.currentFork = fork || 'london' this.currentVm = this.createVm(this.currentFork) this.blocks = {} - this.latestBlockNumber = 0 + this.latestBlockNumber = "0x0" this.blockByTxHash = {} this.txByHash = {} this.exeResults = {} - this.logsManager = new execution.LogsManager() + this.logsManager = new LogsManager() } createVm (hardfork) { @@ -115,7 +125,9 @@ export class VMContext { allowUnlimitedContractSize: true }) - const web3vm = new remixLibVm.Web3VMProvider() + // VmProxy and VMContext are very intricated. + // VmProxy is used to track the EVM execution (to listen on opcode execution, in order for instance to generate the VM trace) + const web3vm = new VmProxy(this) web3vm.setVM(vm) return { vm, web3vm, stateManager, common } } @@ -140,7 +152,7 @@ export class VMContext { return this.currentVm } - addBlock (block) { + addBlock (block: Block) { let blockNumber = '0x' + block.header.number.toString('hex') if (blockNumber === '0x') { blockNumber = '0x0' From b4ea409a97844d2ed7e28500d63f91c6ca22c2c5 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 17 Feb 2022 20:35:43 +0100 Subject: [PATCH 54/55] fix e2e --- apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts b/apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts index 688ac7a635..56616f1ac9 100644 --- a/apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts +++ b/apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts @@ -12,7 +12,7 @@ class GoToVmTraceStep extends EventEmitter { function goToVMtraceStep (browser: NightwatchBrowser, step: number, incr: number, done: VoidFunction) { browser.execute(function (step) { (document.getElementById('slider') as HTMLInputElement).value = (step - 1).toString() }, [step]) .setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW)) - .pause(500) + .pause(1000) .perform(() => { done() }) From 13d77e44f8820f335cdb45f09ac72bd98c5ecbad Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 21 Feb 2022 10:35:25 +0100 Subject: [PATCH 55/55] e2e test revert --- apps/remix-ide-e2e/src/tests/debugger.test.ts | 63 +++++++++++++++++-- .../lib/button-navigator/button-navigator.tsx | 2 +- .../src/lib/vm-debugger/assembly-items.tsx | 2 +- 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/debugger.test.ts b/apps/remix-ide-e2e/src/tests/debugger.test.ts index e9292689e8..56a1174521 100644 --- a/apps/remix-ide-e2e/src/tests/debugger.test.ts +++ b/apps/remix-ide-e2e/src/tests/debugger.test.ts @@ -40,8 +40,8 @@ module.exports = { browser.waitForElementVisible('*[data-id="verticalIconsKindudapp"]') .waitForElementVisible('*[data-id="slider"]') .goToVMTraceStep(51) - .click('*[data-id="dropdownPanelSolidityLocals"]') - .waitForElementContainsText('*[data-id="solidityLocals"]', 'no locals', 60000) + .waitForElementContainsText('*[data-id="solidityLocals"]', 'toast', 60000) + .waitForElementContainsText('*[data-id="solidityLocals"]', '999', 60000) .waitForElementContainsText('*[data-id="stepdetail"]', 'vm trace step:\n51', 60000) }, @@ -227,8 +227,23 @@ 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, immutable: false } }) - .end() + .checkVariableDebug('soliditystate', { number: { value: '0', type: 'uint256', constant: false, immutable: false } }) + }, + + 'Should debug reverted transactions #group5': function (browser: NightwatchBrowser) { + browser + .testContracts('reverted.sol', sources[6]['reverted.sol'], ['A', 'B', 'C']) + .clickLaunchIcon('udapp') + .selectContract('A') + .createContract('') + .pause(500) + .clickInstance(0) + .clickFunction('callA - transact (not payable)') + .debugTransaction(1) + .goToVMTraceStep(79) + .waitForElementVisible('*[data-id="debugGoToRevert"]', 60000) + .click('*[data-id="debugGoToRevert"]') + .waitForElementContainsText('*[data-id="asmitems"] div[selected="selected"]', '117 REVERT') } } @@ -352,6 +367,46 @@ const sources = [ } ` } + }, + { + 'reverted.sol': { + content: `contract A { + B b; + uint p; + constructor () { + b = new B(); + } + function callA() public { + p = 123; + try b.callB() { + + } + catch (bytes memory reason) { + + } + } + } + + contract B { + C c; + uint p; + constructor () { + c = new C(); + } + function callB() public { + p = 124; + revert("revert!"); + c.callC(); + } + } + + contract C { + uint p; + function callC() public { + p = 125; + } + }` + } } ] diff --git a/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx b/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx index 5200de41f7..2db94f72cc 100644 --- a/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx @@ -68,7 +68,7 @@ export const ButtonNavigation = ({ stepOverBack, stepIntoBack, stepIntoForward, This call has reverted, state changes made during the call will be reverted. This call will run out of gas. The parent call will throw an exception -
Click { jumpToException && jumpToException() }}>here to jump where the call reverted.
+
Click { jumpToException && jumpToException() }}>here to jump where the call reverted.
) 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 eb57159048..b32b229f0b 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 @@ -125,7 +125,7 @@ export const AssemblyItems = ({ registerEvent }) => {
-
+
{ assemblyItems.display.map((item, i) => { return
{ refs.current[i] = ref }}>{item}