From 5c37b20442848130a8a0157e2ff2dd3c9ec4e650 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 15 Aug 2022 11:02:03 +0200 Subject: [PATCH 1/9] fix listen on transactions --- apps/remix-ide-e2e/src/tests/terminal.test.ts | 25 ++++++++-- libs/remix-lib/src/execution/txListener.ts | 47 ++++++++++--------- .../terminal/src/lib/remix-ui-terminal.tsx | 1 + 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index f944b453f9..15151aab1d 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -217,13 +217,30 @@ module.exports = { .addFile('scripts/log_tx_block.js', { content: scriptBlockAndTransaction } ) .pause(1000) .executeScriptInTerminal('remix.execute(\'scripts/log_tx_block.js\')') - .pause(10000) // check if the input of the transaction is being logged (web3 call) - .journalChildIncludes('0x775526410000000000000000000000000000000000000000000000000000000000000060464c0335b2f1609abd9de25141c0a3b49db516fc7375970dc737c32b986e88e3000000000000000000000000000000000000000000000000000000000000039e000000000000000000000000000000000000000000000000000000000000000602926b30b10e7a514d92bc71e085f5bff2687fac2856ae43ef7621bf1756fa370516d310bec5727543089be9a4d5f68471174ee528e95a2520b0ca36c2b6c6eb0000000000000000000000000000000000000000000000000000000000046f49036f5e4ea4dd042801c8841e3db8e654124305da0f11824fc1db60c405dbb39f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') + .waitForElementContainsText('*[data-id="terminalJournal"]', '0x775526410000000000000000000000000000000000000000000000000000000000000060464c0335b2f1609abd9de25141c0a3b49db516fc7375970dc737c32b986e88e3000000000000000000000000000000000000000000000000000000000000039e000000000000000000000000000000000000000000000000000000000000000602926b30b10e7a514d92bc71e085f5bff2687fac2856ae43ef7621bf1756fa370516d310bec5727543089be9a4d5f68471174ee528e95a2520b0ca36c2b6c6eb0000000000000000000000000000000000000000000000000000000000046f49036f5e4ea4dd042801c8841e3db8e654124305da0f11824fc1db60c405dbb39f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', 120000) // check if the logsBloom is being logged (web3 call) - .journalChildIncludes('0x00000000000000000000000000100000000000000000020000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000040000000060000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000100000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000001') + .waitForElementContainsText('*[data-id="terminalJournal"]', '0x00000000000000000000000000100000000000000000020000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000040000000060000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000100000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000001', 120000) // check if the logsBloom is being logged (ethers.js call) - .journalChildIncludes('"hex":"0x025cd8"') + .waitForElementContainsText('*[data-id="terminalJournal"]', '"hex":"0x025cd8"', 120000) + }, + + 'Should listen on all transactions #group7': function (browser: NightwatchBrowser) { + browser // it's already connected to goerli + .click('[data-id="terminalClearConsole"]') // clear the console + .click('[data-id="listenNetworkCheckInput"]') // start to listen + .waitForElementContainsText('*[data-id="terminalJournal"]', 'from:', 200000) + .waitForElementContainsText('*[data-id="terminalJournal"]', 'to:', 200000) + .click('[data-id="terminalClearConsole"]') // clear the console + .waitForElementContainsText('*[data-id="terminalJournal"]', 'from:', 200000) + .waitForElementContainsText('*[data-id="terminalJournal"]', 'to:', 200000) + .click('[data-id="listenNetworkCheckInput"]') // stop to listen + .pause(20000) + .execute(function () { + return (document.querySelector('[data-id="terminalJournal"]') as any).innerText + }, [], function (result) { + browser.assert.equal(result.value, '', 'terminal log should be empty') + }) } } diff --git a/libs/remix-lib/src/execution/txListener.ts b/libs/remix-lib/src/execution/txListener.ts index 0d5b26eb84..dd2b582347 100644 --- a/libs/remix-lib/src/execution/txListener.ts +++ b/libs/remix-lib/src/execution/txListener.ts @@ -34,8 +34,7 @@ export class TxListener { _listenOnNetwork:boolean _loopId blocks - lastBlock - + constructor (opt, executionContext) { this.event = new EventManager() // has a default for now for backwards compatability @@ -123,9 +122,7 @@ export class TxListener { if (this._loopId) { clearInterval(this._loopId) } - if (this._listenOnNetwork) { - this._startListenOnNetwork() - } + this._listenOnNetwork ? this._startListenOnNetwork() : this.stopListening() } /** @@ -133,7 +130,6 @@ export class TxListener { */ init () { this.blocks = [] - this.lastBlock = -1 } /** @@ -164,26 +160,33 @@ export class TxListener { this._isListening = false } - _startListenOnNetwork () { + async _startListenOnNetwork () { + let lastSeenBlock = this.executionContext.lastBlock?.number this._loopId = setInterval(() => { const currentLoopId = this._loopId - this.executionContext.web3().eth.getBlockNumber((error, blockNumber) => { - if (this._loopId === null) return - if (error) return console.log(error) - if (currentLoopId === this._loopId && blockNumber > this.lastBlock) { - let current = this.lastBlock + 1 - this.lastBlock = blockNumber - while (blockNumber >= current) { - try { - this._manageBlock(current) - } catch (e) { - console.log(e) - } - current++ + if (this._loopId === null) return + if (!lastSeenBlock) { + lastSeenBlock = this.executionContext.lastBlock?.number // trying to resynchronize + console.log('listen on blocks, resynchronising') + return + } + const current = this.executionContext.lastBlock?.number + if (!current) { + console.error(new Error('no last block found')) + return + } + if (currentLoopId === this._loopId && lastSeenBlock < current) { + while (lastSeenBlock <= current) { + try { + this._manageBlock(lastSeenBlock) + } catch (e) { + console.log(e) } + lastSeenBlock++ } - }) - }, 2000) + lastSeenBlock = current + } + }, 10000) } _manageBlock (blockNumber) { 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 4962101798..11a3cbd57d 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -461,6 +461,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { className="pt-1 form-check-label custom-control-label text-nowrap" title="If checked Remix will listen on all transactions mined in the current environment and not only transactions created by you" htmlFor="listenNetworkCheck" + data-id="listenNetworkCheckInput" > listen on all transactions From 81b04fb667c2b2bf6e77f4a0104b9ad4c99f1abf Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 18 Aug 2022 08:40:08 +0200 Subject: [PATCH 2/9] update dev node --- apps/remix-ide-e2e/src/tests/terminal.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index 15151aab1d..55d2497e39 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -210,7 +210,7 @@ module.exports = { .execute(() => { (document.querySelector('*[data-id="basic-http-providerModalDialogContainer-react"] input[data-id="modalDialogCustomPromp"]') as any).focus() }, [], () => {}) - .setValue('[data-id="modalDialogCustomPromp"]', 'https://remix-goerli.ethdevops.io') + .setValue('[data-id="modalDialogCustomPromp"]', 'https://goerli.infura.io/v3/08b2a484451e4635a28b3d8234f24332o') .modalFooterOKClick('basic-http-provider') .clickLaunchIcon('filePanel') .openFile('README.txt') From 8701bea2a80547510ee45a9c4c69acdfcbef4ece Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 18 Aug 2022 09:16:16 +0200 Subject: [PATCH 3/9] log instead of error --- libs/remix-lib/src/execution/txListener.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-lib/src/execution/txListener.ts b/libs/remix-lib/src/execution/txListener.ts index dd2b582347..b4bb564639 100644 --- a/libs/remix-lib/src/execution/txListener.ts +++ b/libs/remix-lib/src/execution/txListener.ts @@ -172,7 +172,7 @@ export class TxListener { } const current = this.executionContext.lastBlock?.number if (!current) { - console.error(new Error('no last block found')) + console.log(new Error('no last block found')) return } if (currentLoopId === this._loopId && lastSeenBlock < current) { From 609e6c44382706f262d9791f54a14b3ca91a800d Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 18 Aug 2022 09:44:50 +0200 Subject: [PATCH 4/9] fix tests --- apps/remix-ide-e2e/src/tests/terminal.test.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index 55d2497e39..194f8d3321 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -210,7 +210,7 @@ module.exports = { .execute(() => { (document.querySelector('*[data-id="basic-http-providerModalDialogContainer-react"] input[data-id="modalDialogCustomPromp"]') as any).focus() }, [], () => {}) - .setValue('[data-id="modalDialogCustomPromp"]', 'https://goerli.infura.io/v3/08b2a484451e4635a28b3d8234f24332o') + .setValue('[data-id="modalDialogCustomPromp"]', 'https://remix-goerli.ethdevops.io') .modalFooterOKClick('basic-http-provider') .clickLaunchIcon('filePanel') .openFile('README.txt') @@ -225,8 +225,16 @@ module.exports = { .waitForElementContainsText('*[data-id="terminalJournal"]', '"hex":"0x025cd8"', 120000) }, - 'Should listen on all transactions #group7': function (browser: NightwatchBrowser) { - browser // it's already connected to goerli + 'Should listen on all transactions #group8': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('udapp') // connect to mainnet + .switchEnvironment('External Http Provider') + .waitForElementPresent('[data-id="basic-http-provider-modal-footer-ok-react"]') + .execute(() => { + (document.querySelector('*[data-id="basic-http-providerModalDialogContainer-react"] input[data-id="modalDialogCustomPromp"]') as any).focus() + }, [], () => {}) + .setValue('[data-id="modalDialogCustomPromp"]', 'https://rpc.archivenode.io/e50zmkroshle2e2e50zm0044i7ao04ym') + .modalFooterOKClick('basic-http-provider') .click('[data-id="terminalClearConsole"]') // clear the console .click('[data-id="listenNetworkCheckInput"]') // start to listen .waitForElementContainsText('*[data-id="terminalJournal"]', 'from:', 200000) @@ -235,6 +243,8 @@ module.exports = { .waitForElementContainsText('*[data-id="terminalJournal"]', 'from:', 200000) .waitForElementContainsText('*[data-id="terminalJournal"]', 'to:', 200000) .click('[data-id="listenNetworkCheckInput"]') // stop to listen + .pause(30000) + .click('[data-id="terminalClearConsole"]') // clear the console .pause(20000) .execute(function () { return (document.querySelector('[data-id="terminalJournal"]') as any).innerText From 3cde784cf514de340c7d916661ab07468a0e3b95 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 18 Aug 2022 10:29:23 +0200 Subject: [PATCH 5/9] better way to listen and log new blocks --- libs/remix-lib/src/execution/txListener.ts | 39 ++++++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/libs/remix-lib/src/execution/txListener.ts b/libs/remix-lib/src/execution/txListener.ts index b4bb564639..373546ffb9 100644 --- a/libs/remix-lib/src/execution/txListener.ts +++ b/libs/remix-lib/src/execution/txListener.ts @@ -1,5 +1,4 @@ 'use strict' -import { each } from 'async' import { ethers } from 'ethers' import { toBuffer, addHexPrefix } from 'ethereumjs-util' import { EventManager } from '../eventManager' @@ -122,7 +121,7 @@ export class TxListener { if (this._loopId) { clearInterval(this._loopId) } - this._listenOnNetwork ? this._startListenOnNetwork() : this.stopListening() + this._listenOnNetwork ? this.startListening() : this.stopListening() } /** @@ -162,22 +161,31 @@ export class TxListener { async _startListenOnNetwork () { let lastSeenBlock = this.executionContext.lastBlock?.number + let processingBlock = false this._loopId = setInterval(() => { + if (processingBlock) return + processingBlock = true const currentLoopId = this._loopId - if (this._loopId === null) return + if (this._loopId === null) { + processingBlock = false + return + } if (!lastSeenBlock) { lastSeenBlock = this.executionContext.lastBlock?.number // trying to resynchronize console.log('listen on blocks, resynchronising') + processingBlock = false return } const current = this.executionContext.lastBlock?.number if (!current) { console.log(new Error('no last block found')) + processingBlock = false return } if (currentLoopId === this._loopId && lastSeenBlock < current) { while (lastSeenBlock <= current) { try { + if (!this._isListening) break this._manageBlock(lastSeenBlock) } catch (e) { console.log(e) @@ -186,7 +194,8 @@ export class TxListener { } lastSeenBlock = current } - }, 10000) + processingBlock = false + }, 20000) } _manageBlock (blockNumber) { @@ -225,24 +234,32 @@ export class TxListener { }) } - _resolve (transactions, callback) { - each(transactions, (tx, cb) => { + _resolveAsync (tx) { + return new Promise((resolve, reject) => { this._api.resolveReceipt(tx, (error, receipt) => { - if (error) return cb(error) + if (error) return reject(error) this._resolveTx(tx, receipt, (error, resolvedData) => { - if (error) cb(error) + if (error) return reject(error) if (resolvedData) { this.event.trigger('txResolved', [tx, receipt, resolvedData]) } this.event.trigger('newTransaction', [tx, receipt]) - cb() + resolve({}) }) }) - }, () => { - callback() }) } + async _resolve (transactions, callback) { + for (const tx of transactions) { + try { + if (!this._isListening) break + await this._resolveAsync(tx) + } catch (e) {} + } + callback() + } + _resolveTx (tx, receipt, cb) { const contracts = this._api.contracts() if (!contracts) return cb() From 2873ab2eda19f5995cb5dba7607ebc1013916040 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 18 Aug 2022 14:36:27 +0200 Subject: [PATCH 6/9] make it all async --- libs/remix-lib/src/execution/txListener.ts | 33 +++++++++++----------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/libs/remix-lib/src/execution/txListener.ts b/libs/remix-lib/src/execution/txListener.ts index 373546ffb9..17f5a8f2b8 100644 --- a/libs/remix-lib/src/execution/txListener.ts +++ b/libs/remix-lib/src/execution/txListener.ts @@ -105,8 +105,7 @@ export class TxListener { addExecutionCosts(txResult, tx, execResult) tx.envMode = this.executionContext.getProvider() tx.status = txResult.receipt.status // 0x0 or 0x1 - this._resolve([tx], () => { - }) + this._resolve([tx]) }) }) } @@ -162,7 +161,8 @@ export class TxListener { async _startListenOnNetwork () { let lastSeenBlock = this.executionContext.lastBlock?.number let processingBlock = false - this._loopId = setInterval(() => { + + const processBlocks = async () => { if (processingBlock) return processingBlock = true const currentLoopId = this._loopId @@ -186,7 +186,7 @@ export class TxListener { while (lastSeenBlock <= current) { try { if (!this._isListening) break - this._manageBlock(lastSeenBlock) + await this._manageBlock(lastSeenBlock) } catch (e) { console.log(e) } @@ -195,15 +195,16 @@ export class TxListener { lastSeenBlock = current } processingBlock = false - }, 20000) + } + processBlocks() + this._loopId = setInterval(processBlocks, 20000) } - _manageBlock (blockNumber) { - this.executionContext.web3().eth.getBlock(blockNumber, true, (error, result) => { - if (!error) { - this._newBlock(Object.assign({ type: 'web3' }, result)) - } - }) + async _manageBlock (blockNumber) { + try { + const result = await this.executionContext.web3().eth.getBlock(blockNumber, true) + return await this._newBlock(Object.assign({ type: 'web3' }, result)) + } catch (e) {} } /** @@ -227,11 +228,10 @@ export class TxListener { return this._resolvedTransactions[txHash] } - _newBlock (block) { + async _newBlock (block) { this.blocks.push(block) - this._resolve(block.transactions, () => { - this.event.trigger('newBlock', [block]) - }) + await this._resolve(block.transactions) + this.event.trigger('newBlock', [block]) } _resolveAsync (tx) { @@ -250,14 +250,13 @@ export class TxListener { }) } - async _resolve (transactions, callback) { + async _resolve (transactions) { for (const tx of transactions) { try { if (!this._isListening) break await this._resolveAsync(tx) } catch (e) {} } - callback() } _resolveTx (tx, receipt, cb) { From 9acf193722df4b9eb461ae1ef7fe0e56809550b3 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 18 Aug 2022 14:54:09 +0200 Subject: [PATCH 7/9] fix logging empty block --- libs/remix-ui/terminal/src/lib/actions/terminalAction.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts index 5871a4d2cd..87951d8a98 100644 --- a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts +++ b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts @@ -115,7 +115,7 @@ export const initListeningOnNetwork = (plugins, dispatch: React.Dispatch) = plugins.txListener.event.register(NEW_BLOCK, (block) => { if (!block.transactions || (block.transactions && !block.transactions.length)) { - dispatch({ type: EMPTY_BLOCK, payload: { message: 0, provider } }) + dispatch({ type: EMPTY_BLOCK, payload: { message: block.number, provider } }) } }) plugins.txListener.event.register(KNOWN_TRANSACTION, () => { From 16d64aa9735e4de37799a8b3e5372db8d9d6570c Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 18 Aug 2022 14:54:40 +0200 Subject: [PATCH 8/9] start logging as soon as possible --- libs/remix-lib/src/execution/txListener.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/remix-lib/src/execution/txListener.ts b/libs/remix-lib/src/execution/txListener.ts index 17f5a8f2b8..808d9fe4e0 100644 --- a/libs/remix-lib/src/execution/txListener.ts +++ b/libs/remix-lib/src/execution/txListener.ts @@ -159,10 +159,11 @@ export class TxListener { } async _startListenOnNetwork () { - let lastSeenBlock = this.executionContext.lastBlock?.number + let lastSeenBlock = this.executionContext.lastBlock?.number - 1 let processingBlock = false const processBlocks = async () => { + if (!this._isListening) return if (processingBlock) return processingBlock = true const currentLoopId = this._loopId @@ -196,8 +197,8 @@ export class TxListener { } processingBlock = false } - processBlocks() this._loopId = setInterval(processBlocks, 20000) + processBlocks() } async _manageBlock (blockNumber) { From 4a210d2fa0f4f91a78a39924387c0c842ea89713 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 18 Aug 2022 15:11:29 +0200 Subject: [PATCH 9/9] fix test --- apps/remix-ide-e2e/src/tests/terminal.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index 194f8d3321..baf0639cc5 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -245,6 +245,8 @@ module.exports = { .click('[data-id="listenNetworkCheckInput"]') // stop to listen .pause(30000) .click('[data-id="terminalClearConsole"]') // clear the console + .pause(5000) + .click('[data-id="terminalClearConsole"]') // clear the console .pause(20000) .execute(function () { return (document.querySelector('[data-id="terminalJournal"]') as any).innerText