Skip to content
This repository was archived by the owner on Mar 11, 2024. It is now read-only.

Commit 4fe251e

Browse files
authored
Include disableFetchExternal flag to avoid debugging with fetching external sources (#255)
* feat: add `disableFetchExternal` debugger flag * docs: improve description and comments * refactor: remove unnecessary casts * refactor: remove unnecessary constants & module * refactor: refine `const`s scope * refactor: refine more `const`s scope * refactor: continue to merge def and usages * docs: improve note formatting * refactor: refine function scope * refactor: remove unused `export` * refactor: simplify tests
1 parent da33314 commit 4fe251e

21 files changed

+177
-122
lines changed

package.json

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,11 @@
567567
"runtime": "node",
568568
"configurationAttributes": {
569569
"launch": {
570-
"required": [],
570+
"required": [
571+
"txHash",
572+
"workingDirectory",
573+
"providerUrl"
574+
],
571575
"properties": {
572576
"stopOnEntry": {
573577
"type": "boolean",
@@ -581,23 +585,28 @@
581585
},
582586
"txHash": {
583587
"type": "string",
584-
"description": "Transaction hash to debug",
588+
"description": "The transaction hash to debug.",
585589
"default": "0x"
586590
},
587591
"files": {
588592
"type": "string[]",
589-
"description": "Array of file paths of solidity files to debug",
593+
"description": "Array of file paths of solidity files to debug.",
590594
"default": []
591595
},
592596
"workingDirectory": {
593597
"type": "string",
594-
"description": "Directory of truffle project",
598+
"description": "Directory of the Truffle project where to find the Truffle config file.",
595599
"default": "${workspaceFolder}"
596600
},
597601
"providerUrl": {
598602
"type": "string",
599-
"description": "URL of provider",
603+
"description": "Provider's URL of the Ethereum network to connect to.",
600604
"default": "http://127.0.0.1:8545"
605+
},
606+
"disableFetchExternal": {
607+
"type": "boolean",
608+
"description": "When set, do not try to fetch external contract sources when debugging a forked network instance. When the network is not being forked, this flag is ignored.",
609+
"default": false
601610
}
602611
}
603612
}
@@ -611,7 +620,8 @@
611620
"txHash": "0x",
612621
"files": [],
613622
"workingDirectory": "${workspaceFolder}",
614-
"providerUrl": "http://127.0.0.1:8545"
623+
"providerUrl": "http://127.0.0.1:8545",
624+
"disableFetchExternal": false
615625
}
616626
],
617627
"configurationSnippets": [
@@ -625,8 +635,9 @@
625635
"stopOnEntry": false,
626636
"txHash": "0x",
627637
"files": [],
628-
"workingDirectory": "^\"\\${workspaceFolder}/",
629-
"providerUrl": "http://127.0.0.1:8545"
638+
"workingDirectory": "^\"\\${workspaceFolder}\"",
639+
"providerUrl": "http://127.0.0.1:8545",
640+
"disableFetchExternal": false
630641
}
631642
}
632643
],

src/commands/DebuggerCommands.ts

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import {debug, DebugConfiguration, QuickPickItem, Uri, QuickPickItemKind, worksp
66

77
import {DEBUG_TYPE} from '@/debugAdapter/constants/debugAdapter';
88
import {DebugNetwork} from '@/debugAdapter/debugNetwork';
9-
import {shortenHash} from '@/debugAdapter/functions';
109
import {TransactionProvider} from '@/debugAdapter/transaction/transactionProvider';
1110
import {Web3Wrapper} from '@/debugAdapter/web3Wrapper';
1211
import {getTruffleWorkspace, getPathByPlatform} from '@/helpers/workspace';
1312
import {showInputBox, showQuickPick} from '@/helpers/userInteraction';
1413
import {Telemetry} from '@/TelemetryClient';
14+
import {DebuggerTypes} from '@/debugAdapter/models/debuggerTypes';
1515

1616
const TX_REGEX = /^(?:0x)?[0-9a-fA-F]{64}$/;
1717

@@ -68,7 +68,7 @@ export namespace DebuggerCommands {
6868
txHash = txHashSelection.detail || txHashSelection.label;
6969
}
7070

71-
await startDebugging(txHash, workingDirectory, providerUrl);
71+
await startDebugging({txHash, workingDirectory, providerUrl, disableFetchExternal: false});
7272
}
7373
}
7474

@@ -85,30 +85,23 @@ async function getQuickPickItems(txProvider: TransactionProvider) {
8585
}
8686

8787
/**
88-
* This functions is responsible for starting the solidity debugger with the given parameters.
89-
*
90-
* @param txHash A transaction hash.
91-
* @param workingDirectory The working directory of the project.
92-
* @param providerUrl The network provider url.
93-
* @param fetchExternal Indicates if the debugger should fetch external contracts.
88+
* Responsible for starting the Solidity debugger with the given arguments.
89+
*
90+
@param args The `DebugArgs` to initialize the `DebugSession`.
9491
*/
95-
export async function startDebugging(
96-
txHash: string,
97-
workingDirectory: string,
98-
providerUrl: string,
99-
fetchExternal?: boolean
100-
): Promise<void> {
101-
const workspaceFolder = workspace.getWorkspaceFolder(Uri.parse(workingDirectory));
102-
const config: DebugConfiguration = {
103-
files: [],
92+
export async function startDebugging(args: DebuggerTypes.DebugArgs): Promise<void> {
93+
const workspaceFolder =
94+
args.workingDirectory === undefined ? undefined : workspace.getWorkspaceFolder(Uri.parse(args.workingDirectory));
95+
const config: DebugConfiguration & DebuggerTypes.ILaunchRequestArguments = {
96+
type: DEBUG_TYPE,
10497
name: 'Debug Transactions',
105-
providerUrl,
10698
request: 'launch',
107-
txHash,
108-
type: DEBUG_TYPE,
109-
workingDirectory,
99+
100+
// TODO: are these `timeout` and `files` properties used?
110101
timeout: 30000,
111-
fetchExternal,
102+
files: [],
103+
104+
...args,
112105
};
113106

114107
debug.startDebugging(workspaceFolder, config).then(() => {
@@ -121,3 +114,22 @@ function generateDescription(contractName?: string, methodName?: string) {
121114
const contractNameWithoutExt = path.basename(contractName || '', '.json');
122115
return `${contractNameWithoutExt}.${methodName}()`;
123116
}
117+
118+
/**
119+
* Shorten the checksummed version of the input `hash` to have `0x + chars ... chars` characters.
120+
* It assumes that `hash` starts with the prefix `0x`.
121+
*
122+
* > **NOTE**. _This is only `export`ed to be used in tests._
123+
*
124+
* @param hash the hash to shorten.
125+
* @param chars the desired length to append both at the start and at the end.
126+
* @returns the shortened `hash`.
127+
*/
128+
export function shortenHash(hash: string, chars = 4): string {
129+
try {
130+
const parsed = hash;
131+
return `${parsed.substring(0, chars + 2)}...${parsed.substring(parsed.length - chars)}`;
132+
} catch (error) {
133+
throw Error(`Invalid 'address' parameter '${hash}'.`);
134+
}
135+
}

src/debugAdapter/constants/contractJson.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/debugAdapter/constants/transaction.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/debugAdapter/constants/truffleConfig.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

src/debugAdapter/constants/variablesView.ts

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/debugAdapter/contracts/contractJsonsProvider.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@
33

44
import fs from 'fs-extra';
55
import path from 'path';
6-
import {CONTRACT_JSON_ENCODING} from '../constants/contractJson';
76
import {IContractJsonModel} from '../models/IContractJsonModel';
87

98
export class ContractJsonsProvider {
109
private contractBuildDirectory: string;
1110
private contractJsonEncoding: string;
1211
private _cachedContractJsons: {[fileName: string]: IContractJsonModel} | undefined;
1312

14-
constructor(contractBuildDirectory: string, contractJsonEncoding = CONTRACT_JSON_ENCODING) {
13+
constructor(contractBuildDirectory: string, contractJsonEncoding = 'utf-8') {
1514
this.contractBuildDirectory = contractBuildDirectory;
1615
this.contractJsonEncoding = contractJsonEncoding;
1716
}

src/debugAdapter/debugNetwork.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
import path from 'path';
55
import {IConfiguration, INetwork, INetworkOption} from '@/helpers/ConfigurationReader';
6-
import {TRUFFLE_CONFIG_NAME} from './constants/truffleConfig';
76
import {TreeManager} from '@/services/tree/TreeManager';
87
import {ItemType} from '@/Models/ItemType';
98
import {Constants} from '@/Constants';
@@ -14,6 +13,11 @@ import {LocalProject} from '@/Models/TreeItems/LocalProject';
1413
import {LocalNetworkNode} from '@/Models/TreeItems';
1514
import {ConfigurationReader} from '../helpers/debugConfigurationReader';
1615

16+
/**
17+
* TODO: We should removed this hardcoded name since there might be multiple Truffle config files in the same workspace.
18+
*/
19+
const TRUFFLE_CONFIG_NAME = 'truffle-config.js';
20+
1721
export class DebugNetwork {
1822
public workingDirectory: string;
1923
private _basedConfig: ConfigurationReader.TruffleConfig | undefined;

src/debugAdapter/debugSession.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,18 +101,33 @@ export class SolidityDebugSession extends LoggingDebugSession {
101101
args: DebuggerTypes.ILaunchRequestArguments
102102
): Promise<void> {
103103
await this.sendErrorIfFailed(response, async () => {
104+
validateRequiredArg(args.txHash, `txHash`);
105+
validateRequiredArg(args.workingDirectory, `workingDirectory`);
106+
validateRequiredArg(args.providerUrl, `providerUrl`);
107+
108+
if (args.disableFetchExternal === undefined) {
109+
args.disableFetchExternal = false;
110+
}
111+
104112
// make sure to 'Stop' the buffered logging if 'trace' is not set
105113
// logger.setup enable logs in client
106114
logger.setup(args.noDebug ? Logger.LogLevel.Verbose : Logger.LogLevel.Stop, false);
107115

108116
// start the program in the runtime
109-
await this._runtime.attach(args.txHash, args.workingDirectory, args.providerUrl);
117+
// This cast is only necessary because TypeScript does not narrow types in properties
118+
await this._runtime.attach(<Required<DebuggerTypes.DebugArgs>>args);
110119
await this._runtime.processInitialBreakPoints();
111120

112121
// Events order is important
113122
this.sendEvent(new DebuggerTypes.LaunchedEvent());
114123
this.sendEvent(new StoppedEvent(EVENT_REASONS.breakpoint, MAIN_THREAD.id));
115124
});
125+
126+
function validateRequiredArg(arg: string | undefined, name: string) {
127+
if (!arg) {
128+
throw new Error(`\`${name}\` must be specified to initiate the Truffle Debugger`);
129+
}
130+
}
116131
}
117132

118133
protected async disconnectRequest(

src/debugAdapter/functions.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)