From 771fef4c1bc0d42a2029056c8eba77407ab4d2f8 Mon Sep 17 00:00:00 2001 From: morgansliman Date: Fri, 29 Oct 2021 12:59:39 -0400 Subject: [PATCH 1/9] extra tests for privkey validation --- .../src/internal/core/errors-list.ts | 13 ++ .../internal/core/config/config-validation.ts | 195 ++++++++++++++++++ 2 files changed, 208 insertions(+) diff --git a/packages/hardhat-core/src/internal/core/errors-list.ts b/packages/hardhat-core/src/internal/core/errors-list.ts index 15bfe4474a..a77466ad82 100644 --- a/packages/hardhat-core/src/internal/core/errors-list.ts +++ b/packages/hardhat-core/src/internal/core/errors-list.ts @@ -201,6 +201,19 @@ Please run: npm install --save-dev typescript`, Please run this and try again: \`npm install --save-dev typescript\``, shouldBeReported: false, }, + INVALID_PRIVATE_KEY: { + number: 15, + message: `There's one or more invalid private keys in your config file: + +%keys% + +To learn more about Hardhat's configuration, please go to https://hardhat.org/config/`, + title: "Invalid private key", + description: `You have one or more errors in your config file. + +Check the error message for details, or go to the [documentation](https://hardhat.org/config/) to learn more.`, + shouldBeReported: false, + }, }, NETWORK: { CONFIG_NOT_FOUND: { diff --git a/packages/hardhat-core/test/internal/core/config/config-validation.ts b/packages/hardhat-core/test/internal/core/config/config-validation.ts index df1386c3a7..41992bf8cb 100644 --- a/packages/hardhat-core/test/internal/core/config/config-validation.ts +++ b/packages/hardhat-core/test/internal/core/config/config-validation.ts @@ -257,6 +257,201 @@ describe("Config validation", function () { }); }); + /** + * networkConfig.accounts + if string => must === "remote" + if object => ~ + if array => + if network === hardhat => + each => isValidHexString(each.privateKey) + && isValidBalance?(each.balance) + else (network === http) => + each => isValidHexString(each) + */ + + /** + * This describe block will encompass all private key tests + * for both Hardhat and HTTP networks + */ + describe("Private key config", function () { + describe("HTTP network accounts", function () { + it("Should allow an array of valid private keys", function () { + validateConfig({ + networks: { + custom: { + url: "http://localhost", + accounts: [ + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + ], + }, + }, + }); + }); + + it("Should allow valid private keys with missing hex prefix", function () { + validateConfig({ + networks: { + custom: { + url: "http://localhost", + accounts: [ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + ], + }, + }, + }); + }); + + it("Should not allow hex literals", function () { + expectHardhatError( + () => + validateConfig({ + networks: { + custom: { + url: "http://localhost", + accounts: [ + 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + ], + }, + }, + }), + ERRORS.GENERAL.INVALID_PRIVATE_KEY + ); + }); + + it("Should not allow private keys of incorrect length", function () { + expectHardhatError( + () => + validateConfig({ + networks: { + custom: { + url: "http://localhost", + accounts: ["0xaaaa"], + }, + }, + }), + ERRORS.GENERAL.INVALID_PRIVATE_KEY + ); + + expectHardhatError( + () => + validateConfig({ + networks: { + custom: { + url: "http://localhost", + accounts: [ + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb", + ], + }, + }, + }), + ERRORS.GENERAL.INVALID_PRIVATE_KEY + ); + }); + }); + + describe("Hardhat Network accounts", function () { + it("Should allow an array of account objects with valid private keys", function () { + validateConfig({ + networks: { + [HARDHAT_NETWORK_NAME]: { + accounts: [ + { + balance: "123", + privateKey: + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + }, + { + balance: "123", + privateKey: + "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + }, + { + balance: "123", + privateKey: + "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + }, + ], + }, + }, + }); + }); + + it("Should allow valid private keys with missing hex prefix", function () { + validateConfig({ + networks: { + [HARDHAT_NETWORK_NAME]: { + accounts: [ + { + balance: "123", + privateKey: + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + }, + ], + }, + }, + }); + }); + + it("Should not allow hex literals", function () { + expectHardhatError( + () => + validateConfig({ + networks: { + [HARDHAT_NETWORK_NAME]: { + accounts: [ + { + balance: "123", + privateKey: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + }, + ], + }, + }, + }), + ERRORS.GENERAL.INVALID_PRIVATE_KEY + ); + }); + + it("Should not allow private keys of incorrect length", function () { + expectHardhatError( + () => + validateConfig({ + networks: { + [HARDHAT_NETWORK_NAME]: { + accounts: [ + { + balance: "123", + privateKey: "0xaaaa", + }, + ], + }, + }, + }), + ERRORS.GENERAL.INVALID_PRIVATE_KEY + ); + + expectHardhatError( + () => + validateConfig({ + networks: { + [HARDHAT_NETWORK_NAME]: { + accounts: [ + { + balance: "123", + privateKey: + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbb", + }, + ], + }, + }, + }), + ERRORS.GENERAL.INVALID_PRIVATE_KEY + ); + }); + }); + }); + describe("Hardhat Network config", function () { it("Should fail with invalid types", function () { expectHardhatError( From f1912f5f6aae218337787ad663efb85b3ba008fe Mon Sep 17 00:00:00 2001 From: morgansliman Date: Mon, 1 Nov 2021 15:47:30 -0400 Subject: [PATCH 2/9] implement better privkey validation with tests --- .../internal/core/config/config-validation.ts | 128 ++++++++++++++++-- .../src/internal/core/errors-list.ts | 13 -- .../internal/core/config/config-validation.ts | 61 ++++++--- 3 files changed, 156 insertions(+), 46 deletions(-) diff --git a/packages/hardhat-core/src/internal/core/config/config-validation.ts b/packages/hardhat-core/src/internal/core/config/config-validation.ts index 2ff610e474..f8fa00767b 100644 --- a/packages/hardhat-core/src/internal/core/config/config-validation.ts +++ b/packages/hardhat-core/src/internal/core/config/config-validation.ts @@ -2,6 +2,11 @@ import * as t from "io-ts"; import { Context, getFunctionName, ValidationError } from "io-ts/lib"; import { Reporter } from "io-ts/lib/Reporter"; +import { + HardhatConfig, + HardhatNetworkAccountsUserConfig, + HardhatNetworkAccountUserConfig, +} from "../../../types"; import { HARDHAT_NETWORK_NAME, HARDHAT_NETWORK_SUPPORTED_HARDFORKS, @@ -53,6 +58,58 @@ function getErrorMessage(path: string, value: any, expectedType: string) { )} for ${path} - Expected a value of type ${expectedType}.`; } +function getPrivateKeyError(account: any, network: string, message: string) { + return `Invalid account: ${account} for network: ${network} - ${message}`; +} + +function validatePrivateKey( + privateKey: any, + network: string, + errors: string[] +) { + if (typeof privateKey !== "string") { + errors.push( + getPrivateKeyError( + privateKey, + network, + `Expected string, received ${typeof privateKey}` + ) + ); + } else { + // private key validation + const pkWithPrefix = /^0x/.test(privateKey) + ? privateKey + : `0x${privateKey}`; + + // 32 bytes = 64 characters + 2 char prefix = 66 + if (pkWithPrefix.length < 66) { + errors.push( + getPrivateKeyError( + privateKey, + network, + "privateKey too short, expected 32 bytes" + ) + ); + } else if (pkWithPrefix.length > 66) { + errors.push( + getPrivateKeyError( + privateKey, + network, + "privateKey too long, expected 32 bytes" + ) + ); + } else if (hexString.decode(pkWithPrefix).isLeft()) { + errors.push( + getPrivateKeyError( + privateKey, + network, + "invalid hex character(s) found in string" + ) + ); + } + } +} + export function failure(es: ValidationError[]): string[] { return es.map(getMessage); } @@ -224,7 +281,7 @@ export function validateConfig(config: any) { } export function getValidationErrors(config: any): string[] { - const errors = []; + const errors: string[] = []; // These can't be validated with io-ts if (config !== undefined && typeof config.networks === "object") { @@ -237,8 +294,7 @@ export function getValidationErrors(config: any): string[] { } // Validating the accounts with io-ts leads to very confusing errors messages - const configExceptAccounts = { ...hardhatNetwork }; - delete configExceptAccounts.accounts; + const { accounts, ...configExceptAccounts } = hardhatNetwork; const netConfigResult = HardhatNetworkConfig.decode(configExceptAccounts); if (netConfigResult.isLeft()) { @@ -251,31 +307,37 @@ export function getValidationErrors(config: any): string[] { ); } - if (Array.isArray(hardhatNetwork.accounts)) { - for (const account of hardhatNetwork.accounts) { - if (typeof account.privateKey !== "string") { + // manual validation of accounts + if (Array.isArray(accounts)) { + for (const account of accounts) { + if (typeof account !== "object") { errors.push( - getErrorMessage( - `HardhatConfig.networks.${HARDHAT_NETWORK_NAME}.accounts[].privateKey`, - account.privateKey, - "string" + getPrivateKeyError( + account, + HARDHAT_NETWORK_NAME, + `Expected object, received ${typeof account}` ) ); + continue; } - if (typeof account.balance !== "string") { + const { privateKey, balance } = account; + + validatePrivateKey(privateKey, HARDHAT_NETWORK_NAME, errors); + + if (typeof balance !== "string") { errors.push( getErrorMessage( `HardhatConfig.networks.${HARDHAT_NETWORK_NAME}.accounts[].balance`, - account.balance, + balance, "string" ) ); - } else if (decimalString.decode(account.balance).isLeft()) { + } else if (decimalString.decode(balance).isLeft()) { errors.push( getErrorMessage( `HardhatConfig.networks.${HARDHAT_NETWORK_NAME}.accounts[].balance`, - account.balance, + balance, "decimal(wei)" ) ); @@ -340,7 +402,9 @@ export function getValidationErrors(config: any): string[] { } } - const netConfigResult = HttpNetworkConfig.decode(netConfig); + const { accounts, ...configExceptAccounts } = netConfig; + + const netConfigResult = HttpNetworkConfig.decode(configExceptAccounts); if (netConfigResult.isLeft()) { errors.push( getErrorMessage( @@ -350,6 +414,40 @@ export function getValidationErrors(config: any): string[] { ) ); } + + // manual validation of accounts + if (typeof accounts === "string" && accounts !== "remote") { + errors.push( + getPrivateKeyError( + accounts, + networkName, + `Expected "remote", received ${accounts}` + ) + ); + } else if (Array.isArray(accounts)) { + accounts.forEach((privateKey) => + validatePrivateKey(privateKey, networkName, errors) + ); + } else if (typeof accounts === "object") { + const hdConfigResult = HDAccountsConfig.decode(accounts); + if (hdConfigResult.isLeft()) { + errors.push( + getErrorMessage( + `HardhatConfig.networks.${networkName}`, + accounts, + "HttpNetworkHDAccountsConfig" + ) + ); + } + } else if (accounts !== undefined) { + errors.push( + getErrorMessage( + `HardhatConfig.networks.${networkName}.accounts`, + accounts, + '"remote" | string[] | HttpNetworkHDAccountsConfig | undefined' + ) + ); + } } } diff --git a/packages/hardhat-core/src/internal/core/errors-list.ts b/packages/hardhat-core/src/internal/core/errors-list.ts index a77466ad82..15bfe4474a 100644 --- a/packages/hardhat-core/src/internal/core/errors-list.ts +++ b/packages/hardhat-core/src/internal/core/errors-list.ts @@ -201,19 +201,6 @@ Please run: npm install --save-dev typescript`, Please run this and try again: \`npm install --save-dev typescript\``, shouldBeReported: false, }, - INVALID_PRIVATE_KEY: { - number: 15, - message: `There's one or more invalid private keys in your config file: - -%keys% - -To learn more about Hardhat's configuration, please go to https://hardhat.org/config/`, - title: "Invalid private key", - description: `You have one or more errors in your config file. - -Check the error message for details, or go to the [documentation](https://hardhat.org/config/) to learn more.`, - shouldBeReported: false, - }, }, NETWORK: { CONFIG_NOT_FOUND: { diff --git a/packages/hardhat-core/test/internal/core/config/config-validation.ts b/packages/hardhat-core/test/internal/core/config/config-validation.ts index 41992bf8cb..6276434e9e 100644 --- a/packages/hardhat-core/test/internal/core/config/config-validation.ts +++ b/packages/hardhat-core/test/internal/core/config/config-validation.ts @@ -257,18 +257,6 @@ describe("Config validation", function () { }); }); - /** - * networkConfig.accounts - if string => must === "remote" - if object => ~ - if array => - if network === hardhat => - each => isValidHexString(each.privateKey) - && isValidBalance?(each.balance) - else (network === http) => - each => isValidHexString(each) - */ - /** * This describe block will encompass all private key tests * for both Hardhat and HTTP networks @@ -316,7 +304,7 @@ describe("Config validation", function () { }, }, }), - ERRORS.GENERAL.INVALID_PRIVATE_KEY + ERRORS.GENERAL.INVALID_CONFIG ); }); @@ -331,7 +319,7 @@ describe("Config validation", function () { }, }, }), - ERRORS.GENERAL.INVALID_PRIVATE_KEY + ERRORS.GENERAL.INVALID_CONFIG ); expectHardhatError( @@ -346,7 +334,24 @@ describe("Config validation", function () { }, }, }), - ERRORS.GENERAL.INVALID_PRIVATE_KEY + ERRORS.GENERAL.INVALID_CONFIG + ); + }); + + it("Should not allow invalid private keys", function () { + expectHardhatError( + () => + validateConfig({ + networks: { + custom: { + url: "http://localhost", + accounts: [ + "0xgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg", + ], + }, + }, + }), + ERRORS.GENERAL.INVALID_CONFIG ); }); }); @@ -409,7 +414,7 @@ describe("Config validation", function () { }, }, }), - ERRORS.GENERAL.INVALID_PRIVATE_KEY + ERRORS.GENERAL.INVALID_CONFIG ); }); @@ -428,7 +433,7 @@ describe("Config validation", function () { }, }, }), - ERRORS.GENERAL.INVALID_PRIVATE_KEY + ERRORS.GENERAL.INVALID_CONFIG ); expectHardhatError( @@ -446,7 +451,27 @@ describe("Config validation", function () { }, }, }), - ERRORS.GENERAL.INVALID_PRIVATE_KEY + ERRORS.GENERAL.INVALID_CONFIG + ); + }); + + it("Should not allow invalid private keys", function () { + expectHardhatError( + () => + validateConfig({ + networks: { + [HARDHAT_NETWORK_NAME]: { + accounts: [ + { + balance: "123", + privateKey: + "0xgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg", + }, + ], + }, + }, + }), + ERRORS.GENERAL.INVALID_CONFIG ); }); }); From 74ee5d9c3eced3963a6ac283dc003d0dd9de68b2 Mon Sep 17 00:00:00 2001 From: morgansliman Date: Mon, 1 Nov 2021 15:54:23 -0400 Subject: [PATCH 3/9] remove excess imports --- .../src/internal/core/config/config-validation.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/hardhat-core/src/internal/core/config/config-validation.ts b/packages/hardhat-core/src/internal/core/config/config-validation.ts index f8fa00767b..b14ca59428 100644 --- a/packages/hardhat-core/src/internal/core/config/config-validation.ts +++ b/packages/hardhat-core/src/internal/core/config/config-validation.ts @@ -2,11 +2,6 @@ import * as t from "io-ts"; import { Context, getFunctionName, ValidationError } from "io-ts/lib"; import { Reporter } from "io-ts/lib/Reporter"; -import { - HardhatConfig, - HardhatNetworkAccountsUserConfig, - HardhatNetworkAccountUserConfig, -} from "../../../types"; import { HARDHAT_NETWORK_NAME, HARDHAT_NETWORK_SUPPORTED_HARDFORKS, From e087bd0b8444418dac6fbc011b9b2944ffdf6797 Mon Sep 17 00:00:00 2001 From: Morgan Date: Mon, 1 Nov 2021 15:54:35 -0400 Subject: [PATCH 4/9] Create rude-lemons-turn.md --- .changeset/rude-lemons-turn.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/rude-lemons-turn.md diff --git a/.changeset/rude-lemons-turn.md b/.changeset/rude-lemons-turn.md new file mode 100644 index 0000000000..6a4d9e30eb --- /dev/null +++ b/.changeset/rude-lemons-turn.md @@ -0,0 +1,5 @@ +--- +"hardhat": patch +--- + +extra tests for privkey validation From cae998da6f63d07b4d3c5c6f462eb38bbd9d9ca5 Mon Sep 17 00:00:00 2001 From: morgansliman Date: Mon, 1 Nov 2021 16:13:13 -0400 Subject: [PATCH 5/9] fixing existing tests for new validation --- .../internal/core/config/config-validation.ts | 20 +++++---- .../internal/core/config/config-validation.ts | 45 ++++++++++++++++--- 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/packages/hardhat-core/src/internal/core/config/config-validation.ts b/packages/hardhat-core/src/internal/core/config/config-validation.ts index b14ca59428..b43cdd6938 100644 --- a/packages/hardhat-core/src/internal/core/config/config-validation.ts +++ b/packages/hardhat-core/src/internal/core/config/config-validation.ts @@ -411,15 +411,7 @@ export function getValidationErrors(config: any): string[] { } // manual validation of accounts - if (typeof accounts === "string" && accounts !== "remote") { - errors.push( - getPrivateKeyError( - accounts, - networkName, - `Expected "remote", received ${accounts}` - ) - ); - } else if (Array.isArray(accounts)) { + if (Array.isArray(accounts)) { accounts.forEach((privateKey) => validatePrivateKey(privateKey, networkName, errors) ); @@ -434,6 +426,16 @@ export function getValidationErrors(config: any): string[] { ) ); } + } else if (typeof accounts === "string") { + if (accounts !== "remote") { + errors.push( + getPrivateKeyError( + accounts, + networkName, + `Expected "remote", received ${accounts}` + ) + ); + } } else if (accounts !== undefined) { errors.push( getErrorMessage( diff --git a/packages/hardhat-core/test/internal/core/config/config-validation.ts b/packages/hardhat-core/test/internal/core/config/config-validation.ts index 6276434e9e..55a83ebf41 100644 --- a/packages/hardhat-core/test/internal/core/config/config-validation.ts +++ b/packages/hardhat-core/test/internal/core/config/config-validation.ts @@ -1391,7 +1391,13 @@ describe("Config validation", function () { gas: 678, gasPrice: 123, blockGasLimit: 8000, - accounts: [{ privateKey: "0xaaaa", balance: "123" }], + accounts: [ + { + balance: "123", + privateKey: + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + }, + ], forking: { url: "asd", blockNumber: 123, @@ -1407,7 +1413,10 @@ describe("Config validation", function () { url: "", }, withPrivateKeys: { - accounts: ["0x00", "0x11"], + accounts: [ + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + ], url: "", }, withHdKeys: { @@ -1427,7 +1436,13 @@ describe("Config validation", function () { getValidationErrors({ networks: { [HARDHAT_NETWORK_NAME]: { - accounts: [{ privateKey: "0x1111", balance: "0" }], + accounts: [ + { + privateKey: + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + balance: "0", + }, + ], }, }, }), @@ -1437,7 +1452,13 @@ describe("Config validation", function () { getValidationErrors({ networks: { [HARDHAT_NETWORK_NAME]: { - accounts: [{ privateKey: "0x1111", balance: "1" }], + accounts: [ + { + privateKey: + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + balance: "1", + }, + ], }, }, }), @@ -1447,7 +1468,13 @@ describe("Config validation", function () { getValidationErrors({ networks: { [HARDHAT_NETWORK_NAME]: { - accounts: [{ privateKey: "0x1111", balance: "100123" }], + accounts: [ + { + privateKey: + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + balance: "100123", + }, + ], }, }, }), @@ -1457,7 +1484,13 @@ describe("Config validation", function () { getValidationErrors({ networks: { [HARDHAT_NETWORK_NAME]: { - accounts: [{ privateKey: "0x1111", balance: "12300000000123" }], + accounts: [ + { + privateKey: + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + balance: "12300000000123", + }, + ], }, }, }), From 3fa238e9bb71464972719c8637ed63327f0748bc Mon Sep 17 00:00:00 2001 From: Morgan Date: Tue, 2 Nov 2021 13:55:47 -0400 Subject: [PATCH 6/9] Update .changeset/rude-lemons-turn.md Co-authored-by: Franco Victorio --- .changeset/rude-lemons-turn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/rude-lemons-turn.md b/.changeset/rude-lemons-turn.md index 6a4d9e30eb..ab83ae73bc 100644 --- a/.changeset/rude-lemons-turn.md +++ b/.changeset/rude-lemons-turn.md @@ -2,4 +2,4 @@ "hardhat": patch --- -extra tests for privkey validation +Improve validation of private keys in the Hardhat config From b06f5f59f3ecc992bb50a57f6267b897514d0a2e Mon Sep 17 00:00:00 2001 From: morgansliman Date: Tue, 2 Nov 2021 14:26:47 -0400 Subject: [PATCH 7/9] reformatted error message and added a test case --- .../internal/core/config/config-validation.ts | 25 +++++++++--------- .../internal/core/config/config-validation.ts | 26 +++++++++++++++++++ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/packages/hardhat-core/src/internal/core/config/config-validation.ts b/packages/hardhat-core/src/internal/core/config/config-validation.ts index b43cdd6938..13a7257cfd 100644 --- a/packages/hardhat-core/src/internal/core/config/config-validation.ts +++ b/packages/hardhat-core/src/internal/core/config/config-validation.ts @@ -53,19 +53,20 @@ function getErrorMessage(path: string, value: any, expectedType: string) { )} for ${path} - Expected a value of type ${expectedType}.`; } -function getPrivateKeyError(account: any, network: string, message: string) { - return `Invalid account: ${account} for network: ${network} - ${message}`; +function getPrivateKeyError(index: any, network: string, message: string) { + return `Invalid account: #${index} for network: ${network} - ${message}`; } function validatePrivateKey( privateKey: any, + index: number, network: string, errors: string[] ) { if (typeof privateKey !== "string") { errors.push( getPrivateKeyError( - privateKey, + index, network, `Expected string, received ${typeof privateKey}` ) @@ -80,7 +81,7 @@ function validatePrivateKey( if (pkWithPrefix.length < 66) { errors.push( getPrivateKeyError( - privateKey, + index, network, "privateKey too short, expected 32 bytes" ) @@ -88,7 +89,7 @@ function validatePrivateKey( } else if (pkWithPrefix.length > 66) { errors.push( getPrivateKeyError( - privateKey, + index, network, "privateKey too long, expected 32 bytes" ) @@ -96,7 +97,7 @@ function validatePrivateKey( } else if (hexString.decode(pkWithPrefix).isLeft()) { errors.push( getPrivateKeyError( - privateKey, + index, network, "invalid hex character(s) found in string" ) @@ -304,11 +305,11 @@ export function getValidationErrors(config: any): string[] { // manual validation of accounts if (Array.isArray(accounts)) { - for (const account of accounts) { + for (const [index, account] of Object.entries(accounts)) { if (typeof account !== "object") { errors.push( getPrivateKeyError( - account, + index, HARDHAT_NETWORK_NAME, `Expected object, received ${typeof account}` ) @@ -318,7 +319,7 @@ export function getValidationErrors(config: any): string[] { const { privateKey, balance } = account; - validatePrivateKey(privateKey, HARDHAT_NETWORK_NAME, errors); + validatePrivateKey(privateKey, +index, HARDHAT_NETWORK_NAME, errors); if (typeof balance !== "string") { errors.push( @@ -412,8 +413,8 @@ export function getValidationErrors(config: any): string[] { // manual validation of accounts if (Array.isArray(accounts)) { - accounts.forEach((privateKey) => - validatePrivateKey(privateKey, networkName, errors) + accounts.forEach((privateKey, index) => + validatePrivateKey(privateKey, index, networkName, errors) ); } else if (typeof accounts === "object") { const hdConfigResult = HDAccountsConfig.decode(accounts); @@ -430,7 +431,7 @@ export function getValidationErrors(config: any): string[] { if (accounts !== "remote") { errors.push( getPrivateKeyError( - accounts, + 0, networkName, `Expected "remote", received ${accounts}` ) diff --git a/packages/hardhat-core/test/internal/core/config/config-validation.ts b/packages/hardhat-core/test/internal/core/config/config-validation.ts index 55a83ebf41..630b921268 100644 --- a/packages/hardhat-core/test/internal/core/config/config-validation.ts +++ b/packages/hardhat-core/test/internal/core/config/config-validation.ts @@ -399,6 +399,32 @@ describe("Config validation", function () { }); }); + it("Should not allow an array that contains a value that is not an object", function () { + expectHardhatError( + () => + validateConfig({ + networks: { + [HARDHAT_NETWORK_NAME]: { + accounts: [ + { + balance: "123", + privateKey: + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + }, + "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + { + balance: "123", + privateKey: + "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + }, + ], + }, + }, + }), + ERRORS.GENERAL.INVALID_CONFIG + ); + }); + it("Should not allow hex literals", function () { expectHardhatError( () => From f0f1fa307a283deb9c433c598239375fd6682b7d Mon Sep 17 00:00:00 2001 From: morgansliman Date: Tue, 2 Nov 2021 17:52:54 -0400 Subject: [PATCH 8/9] remove cast to number and clarify error --- .../src/internal/core/config/config-validation.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/hardhat-core/src/internal/core/config/config-validation.ts b/packages/hardhat-core/src/internal/core/config/config-validation.ts index 13a7257cfd..9afc151676 100644 --- a/packages/hardhat-core/src/internal/core/config/config-validation.ts +++ b/packages/hardhat-core/src/internal/core/config/config-validation.ts @@ -305,7 +305,7 @@ export function getValidationErrors(config: any): string[] { // manual validation of accounts if (Array.isArray(accounts)) { - for (const [index, account] of Object.entries(accounts)) { + for (const [index, account] of accounts.entries()) { if (typeof account !== "object") { errors.push( getPrivateKeyError( @@ -319,7 +319,7 @@ export function getValidationErrors(config: any): string[] { const { privateKey, balance } = account; - validatePrivateKey(privateKey, +index, HARDHAT_NETWORK_NAME, errors); + validatePrivateKey(privateKey, index, HARDHAT_NETWORK_NAME, errors); if (typeof balance !== "string") { errors.push( @@ -430,11 +430,7 @@ export function getValidationErrors(config: any): string[] { } else if (typeof accounts === "string") { if (accounts !== "remote") { errors.push( - getPrivateKeyError( - 0, - networkName, - `Expected "remote", received ${accounts}` - ) + `Invalid 'accounts' entry for network '${networkName}': expected an array of accounts or the string 'remote', but got the string '${accounts}'` ); } } else if (accounts !== undefined) { From e4efcaf969718bcd32fd02de96f8cbb4bfe093f1 Mon Sep 17 00:00:00 2001 From: morgansliman Date: Thu, 4 Nov 2021 13:41:34 -0400 Subject: [PATCH 9/9] small fixes --- .../src/internal/core/config/config-validation.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/hardhat-core/src/internal/core/config/config-validation.ts b/packages/hardhat-core/src/internal/core/config/config-validation.ts index 9afc151676..ba00ae0366 100644 --- a/packages/hardhat-core/src/internal/core/config/config-validation.ts +++ b/packages/hardhat-core/src/internal/core/config/config-validation.ts @@ -53,12 +53,12 @@ function getErrorMessage(path: string, value: any, expectedType: string) { )} for ${path} - Expected a value of type ${expectedType}.`; } -function getPrivateKeyError(index: any, network: string, message: string) { +function getPrivateKeyError(index: number, network: string, message: string) { return `Invalid account: #${index} for network: ${network} - ${message}`; } function validatePrivateKey( - privateKey: any, + privateKey: unknown, index: number, network: string, errors: string[] @@ -83,7 +83,7 @@ function validatePrivateKey( getPrivateKeyError( index, network, - "privateKey too short, expected 32 bytes" + "private key too short, expected 32 bytes" ) ); } else if (pkWithPrefix.length > 66) { @@ -91,7 +91,7 @@ function validatePrivateKey( getPrivateKeyError( index, network, - "privateKey too long, expected 32 bytes" + "private key too long, expected 32 bytes" ) ); } else if (hexString.decode(pkWithPrefix).isLeft()) {