force using local node

pull/5370/head
yann300 3 years ago
parent 3a8ae483c0
commit fe52493e50
  1. 1
      apps/debugger/src/app/debugger-api.ts
  2. 3
      apps/debugger/src/app/debugger.ts
  3. 8
      libs/remix-debug/src/Ethdebugger.ts
  4. 17
      libs/remix-debug/src/debugger/debugger.ts
  5. 3
      libs/remix-debug/src/trace/traceManager.ts
  6. 32
      libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx
  7. 3
      libs/remix-ui/debugger-ui/src/lib/idebugger-api.ts

@ -16,6 +16,7 @@ export const DebuggerApiMixin = (Base) => class extends Base {
} }
} }
this._web3 = new Web3(this.web3Provider) this._web3 = new Web3(this.web3Provider)
remixDebug.init.extendWeb3(this._web3)
this.offsetToLineColumnConverter = { this.offsetToLineColumnConverter = {
async offsetToLineColumn (rawLocation, file, sources, asts) { async offsetToLineColumn (rawLocation, file, sources, asts) {

@ -23,6 +23,7 @@ export class DebuggerClientApi extends DebuggerApiMixin(PluginClient) {
fetchContractAndCompile: (address: string, currentReceipt: TransactionReceipt) => Promise<CompilerAbstract> fetchContractAndCompile: (address: string, currentReceipt: TransactionReceipt) => Promise<CompilerAbstract>
getFile: (path: string) => Promise<string> getFile: (path: string) => Promise<string>
setFile: (path: string, content: string) => Promise<void> setFile: (path: string, content: string) => Promise<void>
getDebugWeb3: () => any // returns an instance of web3.js getDebugWeb3: () => any // returns an instance of web3.js, if applicable (mainet, goerli, ...) it returns a reference to a node from devops (so we are sure debug endpoint is available)
web3: () => any // returns an instance of web3.js
} }

@ -33,7 +33,6 @@ export class Ethdebugger {
storageResolver storageResolver
callTree callTree
breakpointManager breakpointManager
statusMessage
constructor (opts) { constructor (opts) {
this.compilationResult = opts.compilationResult || function (contractAddress) { return null } this.compilationResult = opts.compilationResult || function (contractAddress) { return null }
@ -151,22 +150,19 @@ export class Ethdebugger {
this.event.trigger('traceUnloaded') this.event.trigger('traceUnloaded')
} }
debug (tx) { async debug (tx) {
if (this.traceManager.isLoading) { if (this.traceManager.isLoading) {
return return
} }
tx.to = tx.to || contractCreationToken('0') tx.to = tx.to || contractCreationToken('0')
this.tx = tx this.tx = tx
this.traceManager.resolveTrace(tx).then(async (result) => { await this.traceManager.resolveTrace(tx)
this.setCompilationResult(await this.compilationResult(tx.to)) this.setCompilationResult(await this.compilationResult(tx.to))
this.event.trigger('newTraceLoaded', [this.traceManager.trace]) this.event.trigger('newTraceLoaded', [this.traceManager.trace])
if (this.breakpointManager && this.breakpointManager.hasBreakpoint()) { if (this.breakpointManager && this.breakpointManager.hasBreakpoint()) {
this.breakpointManager.jumpNextBreakpoint(false) this.breakpointManager.jumpNextBreakpoint(false)
} }
this.storageResolver = new StorageResolver({ web3: this.traceManager.web3 }) this.storageResolver = new StorageResolver({ web3: this.traceManager.web3 })
}).catch((error) => {
this.statusMessage = error ? error.message : 'Trace not loaded'
})
} }
} }

@ -100,9 +100,9 @@ export class Debugger {
} }
debug (blockNumber, txNumber, tx, loadingCb): Promise<void> { debug (blockNumber, txNumber, tx, loadingCb): Promise<void> {
return new Promise((resolve, reject) => {
const web3 = this.debugger.web3 const web3 = this.debugger.web3
return new Promise((resolve, reject) => {
if (this.debugger.traceManager.isLoading) { if (this.debugger.traceManager.isLoading) {
return resolve() return resolve()
} }
@ -111,8 +111,7 @@ export class Debugger {
if (!tx.to) { if (!tx.to) {
tx.to = contractCreationToken('0') tx.to = contractCreationToken('0')
} }
this.debugTx(tx, loadingCb) return this.debugTx(tx, loadingCb).then(resolve).catch(reject)
return resolve()
} }
try { try {
@ -120,23 +119,21 @@ export class Debugger {
return web3.eth.getTransaction(txNumber, (_error, tx) => { return web3.eth.getTransaction(txNumber, (_error, tx) => {
if (_error) return reject(_error) if (_error) return reject(_error)
if (!tx) return reject(new Error('cannot find transaction ' + txNumber)) if (!tx) return reject(new Error('cannot find transaction ' + txNumber))
this.debugTx(tx, loadingCb) return this.debugTx(tx, loadingCb).then(resolve).catch(reject)
return resolve()
}) })
} }
web3.eth.getTransactionFromBlock(blockNumber, txNumber, (_error, tx) => { web3.eth.getTransactionFromBlock(blockNumber, txNumber, (_error, tx) => {
if (_error) return reject(_error) if (_error) return reject(_error)
if (!tx) return reject(new Error('cannot find transaction ' + blockNumber + ' ' + txNumber)) if (!tx) return reject(new Error('cannot find transaction ' + blockNumber + ' ' + txNumber))
this.debugTx(tx, loadingCb) return this.debugTx(tx, loadingCb).then(resolve).catch(reject)
return resolve()
}) })
} catch (e) { } catch (e) {
return reject(e.message) return reject(e)
} }
}) })
} }
debugTx (tx, loadingCb) { async debugTx (tx, loadingCb) {
this.step_manager = new DebuggerStepManager(this.debugger, this.debugger.traceManager) this.step_manager = new DebuggerStepManager(this.debugger, this.debugger.traceManager)
this.debugger.codeManager.event.register('changed', this, (code, address, instIndex) => { this.debugger.codeManager.event.register('changed', this, (code, address, instIndex) => {
@ -162,7 +159,7 @@ export class Debugger {
}) })
loadingCb() loadingCb()
this.debugger.debug(tx) await this.debugger.debug(tx)
} }
unload () { unload () {

@ -30,9 +30,8 @@ export class TraceManager {
this.init() this.init()
if (!this.web3) throw new Error('web3 not loaded') if (!this.web3) throw new Error('web3 not loaded')
this.isLoading = true this.isLoading = true
try {
const result = await this.getTrace(tx.hash) const result = await this.getTrace(tx.hash)
try {
if (result['structLogs'].length > 0) { if (result['structLogs'].length > 0) {
this.trace = result['structLogs'] this.trace = result['structLogs']

@ -15,7 +15,6 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
const debuggerModule = props.debuggerAPI const debuggerModule = props.debuggerAPI
const [state, setState] = useState({ const [state, setState] = useState({
isActive: false, isActive: false,
statusMessage: '',
debugger: null, debugger: null,
currentReceipt: { currentReceipt: {
contractAddress: null, contractAddress: null,
@ -25,7 +24,8 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
txNumber: '', txNumber: '',
debugging: false, debugging: false,
opt: { opt: {
debugWithGeneratedSources: false debugWithGeneratedSources: false,
debugWithLocalNode: false
}, },
toastMessage: '', toastMessage: '',
validationError: '', validationError: '',
@ -132,7 +132,6 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
return { return {
...prevState, ...prevState,
isActive: false, isActive: false,
statusMessage: '',
debugger: null, debugger: null,
currentReceipt: { currentReceipt: {
contractAddress: null, contractAddress: null,
@ -166,7 +165,7 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
return return
} }
const web3 = await debuggerModule.getDebugWeb3() const web3 = state.opt.debugWithLocalNode ? await debuggerModule.web3() : await debuggerModule.getDebugWeb3()
try { try {
const networkId = await web3.eth.net.getId() const networkId = await web3.eth.net.getId()
_paq.push(['trackEvent', 'debugger', 'startDebugging', networkId]) _paq.push(['trackEvent', 'debugger', 'startDebugging', networkId])
@ -211,7 +210,8 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
debugWithGeneratedSources: state.opt.debugWithGeneratedSources debugWithGeneratedSources: state.opt.debugWithGeneratedSources
}) })
debuggerInstance.debug(blockNumber, txNumber, tx, () => { try {
await debuggerInstance.debug(blockNumber, txNumber, tx, () => {
listenToEvents(debuggerInstance, currentReceipt) listenToEvents(debuggerInstance, currentReceipt)
setState(prevState => { setState(prevState => {
return { return {
@ -225,19 +225,16 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
validationError: '' validationError: ''
} }
}) })
}).catch((error) => { })
if (JSON.stringify(error) !== '{}') { } catch (error) {
let message = 'Error: ' + JSON.stringify(error) unLoad()
message = message.split('\\"').join('\'')
setState(prevState => { setState(prevState => {
return { return {
...prevState, ...prevState,
validationError: message validationError: error.message || error
} }
}) })
} }
unLoad()
})
} }
const debug = (txHash) => { const debug = (txHash) => {
@ -277,18 +274,25 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
<div className="mt-2 mb-2 debuggerConfig custom-control custom-checkbox"> <div className="mt-2 mb-2 debuggerConfig custom-control custom-checkbox">
<input className="custom-control-input" id="debugGeneratedSourcesInput" onChange={({ target: { checked } }) => { <input className="custom-control-input" id="debugGeneratedSourcesInput" onChange={({ target: { checked } }) => {
setState(prevState => { setState(prevState => {
return { ...prevState, opt: { debugWithGeneratedSources: checked } } return { ...prevState, opt: { ...prevState.opt, debugWithGeneratedSources: checked } }
}) })
}} type="checkbox" title="Debug with generated sources" /> }} type="checkbox" title="Debug with generated sources" />
<label data-id="debugGeneratedSourcesLabel" className="form-check-label custom-control-label" htmlFor="debugGeneratedSourcesInput">Use generated sources (from Solidity v0.7.2)</label> <label data-id="debugGeneratedSourcesLabel" className="form-check-label custom-control-label" htmlFor="debugGeneratedSourcesInput">Use generated sources (from Solidity v0.7.2)</label>
</div> </div>
<div className="mt-2 mb-2 debuggerConfig custom-control custom-checkbox">
<input className="custom-control-input" id="debugWithLocalNodeInput" onChange={({ target: { checked } }) => {
setState(prevState => {
return { ...prevState, opt: { ...prevState.opt, debugWithLocalNode: checked } }
})
}} type="checkbox" title="Force the debugger to use the current local node" />
<label data-id="debugLocaNodeLabel" className="form-check-label custom-control-label" htmlFor="debugWithLocalNodeInput">Force using local node</label>
</div>
{ state.validationError && <span className="w-100 py-1 text-danger validationError">{state.validationError}</span> } { state.validationError && <span className="w-100 py-1 text-danger validationError">{state.validationError}</span> }
</div> </div>
<TxBrowser requestDebug={ requestDebug } unloadRequested={ unloadRequested } updateTxNumberFlag={ updateTxNumberFlag } transactionNumber={ state.txNumber } debugging={ state.debugging } /> <TxBrowser requestDebug={ requestDebug } unloadRequested={ unloadRequested } updateTxNumberFlag={ updateTxNumberFlag } transactionNumber={ state.txNumber } debugging={ state.debugging } />
{ state.debugging && <StepManager stepManager={ stepManager } /> } { state.debugging && <StepManager stepManager={ stepManager } /> }
{ state.debugging && <VmDebuggerHead vmDebugger={ vmDebugger } /> } { state.debugging && <VmDebuggerHead vmDebugger={ vmDebugger } /> }
</div> </div>
{ state.debugging && <div className="statusMessage">{ state.statusMessage }</div> }
{ state.debugging && <VmDebugger vmDebugger={ vmDebugger } /> } { state.debugging && <VmDebugger vmDebugger={ vmDebugger } /> }
</div> </div>
) )

@ -62,6 +62,7 @@ export interface IDebuggerApi {
fetchContractAndCompile: (address: string, currentReceipt: TransactionReceipt) => Promise<CompilationOutput> fetchContractAndCompile: (address: string, currentReceipt: TransactionReceipt) => Promise<CompilationOutput>
getFile: (path: string) => Promise<string> getFile: (path: string) => Promise<string>
setFile: (path: string, content: string) => Promise<void> setFile: (path: string, content: string) => Promise<void>
getDebugWeb3: () => any // returns an instance of web3.js getDebugWeb3: () => any // returns an instance of web3.js, if applicable (mainet, goerli, ...) it returns a reference to a node from devops (so we are sure debug endpoint is available)
web3: () => any // returns an instance of web3.js
showMessage (title: string, message: string): void showMessage (title: string, message: string): void
} }

Loading…
Cancel
Save