Skip to content

Commit

Permalink
Merge branch 'wyatt/4.x/4810-web3-eth-promievent-tests' into 4811/inv…
Browse files Browse the repository at this point in the history
…estigate-eslint-errors-in-web3-eth
  • Loading branch information
nikoulai committed Apr 6, 2022
2 parents 3626900 + 4681e83 commit af1e4a5
Show file tree
Hide file tree
Showing 16 changed files with 309 additions and 128 deletions.
3 changes: 2 additions & 1 deletion packages/web3-common/src/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ export const convertScalarValue = (value: unknown, ethType: string, format: Data
}
}
} catch (error) {
// TODO: Add debugging to verify the error is thrown by the correct function
// If someone did't used `eth` keyword we can return original value
// as the scope of this code is formatting not validation
return value;
}

Expand Down
2 changes: 0 additions & 2 deletions packages/web3-eth-abi/src/api/parameters_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export const encodeParameters = (abi: ReadonlyArray<AbiInput>, params: unknown[]
Array.isArray(abi) ? (abi as AbiInput[]) : ([abi] as unknown as AbiInput[]),
);
const modifiedParams: Array<unknown> = [];

for (const [index, param] of params.entries()) {
const item = modifiedTypes[index];
let type: string;
Expand All @@ -58,7 +57,6 @@ export const encodeParameters = (abi: ReadonlyArray<AbiInput>, params: unknown[]

modifiedParams.push(newParam);
}

return ethersAbiCoder.encode(
modifiedTypes.map(p => ParamType.from(p)),
modifiedParams,
Expand Down
41 changes: 26 additions & 15 deletions packages/web3-eth-abi/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,26 @@ export const mapTypes = (
return mappedTypes;
};

/**
* returns true if input is a hexstring and is odd-lengthed
*/
export const isOddHexstring = (param: unknown): boolean =>
typeof param === 'string' && /^(-)?0x[0-9a-f]*$/i.test(param) && param.length % 2 === 1;

/**
* format odd-length bytes to even-length
*/
export const formatOddHexstrings = (param: string): string =>
isOddHexstring(param) ? `0x0${param.substring(2)}` : param;

/**
* Handle some formatting of params for backwards compatibility with Ethers V4
*/
export const formatParam = (type: string, _param: unknown): unknown => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
let param = _param;

// clone if _param is an object
const param = typeof _param === 'object' && !Array.isArray(_param) ? { ..._param } : _param;
const paramTypeBytes = /^bytes([0-9]*)$/;
const paramTypeBytesArray = /^bytes([0-9]*)\[\]$/;
const paramTypeNumber = /^(u?int)([0-9]*)$/;
Expand All @@ -141,7 +155,8 @@ export const formatParam = (type: string, _param: unknown): unknown => {

if (paramTypeBytesArray.exec(type) || paramTypeNumberArray.exec(type)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return (param as Array<unknown>).map(p => formatParam(type.replace('[]', ''), p));
const paramClone = [...(param as Array<unknown>)];
return paramClone.map(p => formatParam(type.replace('[]', ''), p));
}

// Format correct width for u?int[0-9]*
Expand All @@ -150,16 +165,14 @@ export const formatParam = (type: string, _param: unknown): unknown => {
const size = parseInt(match[2] ?? '256', 10);
if (size / 8 < (param as { length: number }).length) {
// pad to correct bit width
param = leftPad(param as string, size);
return leftPad(param as string, size);
}
}

// Format correct length for bytes[0-9]+
match = paramTypeBytes.exec(type);
if (match) {
if (Buffer.isBuffer(param)) {
param = toHex(param);
}
const hexParam = Buffer.isBuffer(param) ? toHex(param) : param;

// format to correct length
const size = parseInt(match[1], 10);
Expand All @@ -169,18 +182,16 @@ export const formatParam = (type: string, _param: unknown): unknown => {
if ((param as string).startsWith('0x')) {
maxSize += 2;
}
if ((param as string).length < maxSize) {
// pad to correct length
param = rightPad(param as string, size * 2);
}
// pad to correct length
const paddedParam =
(hexParam as string).length < maxSize
? rightPad(param as string, size * 2)
: hexParam;
return formatOddHexstrings(paddedParam as string);
}

// format odd-length bytes to even-length
if ((param as string).length % 2 === 1) {
param = `0x0${(param as string).substring(2)}`;
}
return formatOddHexstrings(hexParam as string);
}

return param;
};

Expand Down
48 changes: 48 additions & 0 deletions packages/web3-eth-abi/test/fixtures/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,54 @@ export const validEncodeDecodeParametersData: {
},
];

export const validEncodeDoesNotMutateData: {
expectedInput: unknown[];
input: Parameters<typeof encodeParameters>;
output: ReturnType<typeof encodeParameters>;
}[] = [
{
expectedInput: [
['34', '255'],
{
propertyOne: ['78', '124'],
propertyTwo: '56',
ChildStruct: {
propertyOne: ['16'],
propertyTwo: '78',
},
},
],

input: [
[
'uint8[]',
{
ParentStruct: {
propertyOne: 'uint8[]',
propertyTwo: 'uint256',
ChildStruct: {
propertyOne: 'uint8[]',
propertyTwo: 'uint256',
},
},
},
],
[
['34', '255'],
{
propertyOne: ['78', '124'],
propertyTwo: '56',
ChildStruct: {
propertyOne: ['16'],
propertyTwo: '78',
},
},
],
],
output: '0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000007c0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000010',
},
];

export const validEncodeParametersData: {
input: Parameters<typeof encodeParameters>;
output: ReturnType<typeof encodeParameters>;
Expand Down
16 changes: 16 additions & 0 deletions packages/web3-eth-abi/test/unit/api/parameters_api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
validDecodeParametersData,
validEncodeParametersData,
validEncodeDecodeParametersData,
validEncodeDoesNotMutateData,
} from '../../fixtures/data';
import { AbiInput } from '../../../src/types';

Expand All @@ -29,6 +30,21 @@ describe('parameters_api', () => {
});
});

describe('encodeParametersDoesNotMutate', () => {
describe('valid data', () => {
it.each(validEncodeDoesNotMutateData)(
'%#: should pass for valid values: %j',
({ input: [abi, params], output, expectedInput }) => {
expect(encodeParameters(abi, params)).toEqual(output);
// check that params has not been mutated
expect(JSON.parse(JSON.stringify(params))).toEqual(
JSON.parse(JSON.stringify(expectedInput)),
);
},
);
});
});

describe('decodeParameters', () => {
describe('valid data', () => {
it.each(validDecodeParametersData)(
Expand Down
3 changes: 1 addition & 2 deletions packages/web3-eth-ens/src/ens.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { getBlock } from 'web3-eth';
import { getBlock, ReceiptInfo } from 'web3-eth';
import { Web3Context, SupportedProviders, Web3ContextObject } from 'web3-core';
import { getId, Web3NetAPI } from 'web3-net';
import { Address } from 'web3-utils';
import {
ReceiptInfo,
RevertInstructionError,
EthExecutionAPI,
ENSUnsupportedNetworkError,
Expand Down
21 changes: 9 additions & 12 deletions packages/web3-eth/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ import {
ERR_TX_POLLING_TIMEOUT,
ERR_TX_RECEIPT_MISSING_OR_BLOCKHASH_NULL,
ERR_TX_RECEIPT_MISSING_BLOCK_NUMBER,
ReceiptInfo,
} from 'web3-common';
import { HexString, HexString32Bytes, Numbers, Web3Error } from 'web3-utils';
import { Bytes, HexString, Numbers, Web3Error } from 'web3-utils';

import { ReceiptInfo } from './types';

export class InvalidTransactionWithSender extends Web3Error {
public code = ERR_TX_INVALID_SENDER;
Expand Down Expand Up @@ -249,9 +250,9 @@ export class TransactionDataAndInputError extends Web3Error {
export class TransactionPollingTimeoutError extends Web3Error {
public code = ERR_TX_POLLING_TIMEOUT;

public constructor(value: { numberOfSeconds: number; transactionHash: HexString32Bytes }) {
public constructor(value: { numberOfSeconds: number; transactionHash: Bytes }) {
super(
`transactionHash: ${value.transactionHash}`,
`transactionHash: ${value.transactionHash.toString()}`,
`Transaction was not mined within ${value.numberOfSeconds} seconds, please make sure your transaction was properly sent. Be aware that it might still be mined!`,
);
}
Expand All @@ -260,15 +261,11 @@ export class TransactionPollingTimeoutError extends Web3Error {
export class TransactionMissingReceiptOrBlockHashError extends Web3Error {
public code = ERR_TX_RECEIPT_MISSING_OR_BLOCKHASH_NULL;

public constructor(value: {
receipt: ReceiptInfo;
blockHash: HexString32Bytes;
transactionHash: HexString32Bytes;
}) {
public constructor(value: { receipt: ReceiptInfo; blockHash: Bytes; transactionHash: Bytes }) {
super(
`receipt: ${JSON.stringify(value.receipt)}, blockHash: ${
value.blockHash
}, transactionHash: ${value.transactionHash}`,
`receipt: ${JSON.stringify(
value.receipt,
)}, blockHash: ${value.blockHash.toString()}, transactionHash: ${value.transactionHash.toString()}`,
`Receipt missing or blockHash null`,
);
}
Expand Down
Loading

0 comments on commit af1e4a5

Please sign in to comment.