Skip to content

Commit

Permalink
Nikos/5831/invalid from/to/ when sending transaction (#5946)
Browse files Browse the repository at this point in the history
* More explicit error message for invalid sender and receiver errors

* Update test error for new message

* Add test for getTransactionFromOrToAttr

* Add condition

* Add note in docs
  • Loading branch information
nikoulai authored Mar 27, 2023
1 parent 4cfd991 commit c019149
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 9 deletions.
4 changes: 2 additions & 2 deletions packages/web3-errors/src/errors/transaction_errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,14 +213,14 @@ export class InvalidTransactionWithSender extends InvalidValueError {
public code = ERR_TX_INVALID_SENDER;

public constructor(value: unknown) {
super(value, 'invalid transaction with sender');
super(value, 'invalid transaction with invalid sender');
}
}
export class InvalidTransactionWithReceiver extends InvalidValueError {
public code = ERR_TX_INVALID_RECEIVER;

public constructor(value: unknown) {
super(value, 'invalid transaction with receiver');
super(value, 'invalid transaction with invalid receiver');
}
}
export class InvalidTransactionCall extends InvalidValueError {
Expand Down
4 changes: 2 additions & 2 deletions packages/web3-eth/src/utils/transaction_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import {
import { Web3Context } from 'web3-core';
import { privateKeyToAddress } from 'web3-eth-accounts';
import { getId } from 'web3-net';
import { isNullish, isNumber } from 'web3-validator';
import { isNullish, isNumber, isHexStrict } from 'web3-validator';
import {
InvalidTransactionWithSender,
InvalidTransactionWithReceiver,
Expand Down Expand Up @@ -71,7 +71,7 @@ export const getTransactionFromOrToAttr = (
if (typeof transaction[attr] === 'string' && isAddress(transaction[attr] as string)) {
return transaction[attr] as Address;
}
if (isNumber(transaction[attr] as Numbers)) {
if (!isHexStrict(transaction[attr] as string) && isNumber(transaction[attr] as Numbers)) {
if (web3Context.wallet) {
const account = web3Context.wallet.get(
format({ eth: 'uint' }, transaction[attr] as Numbers, NUMBER_DATA_FORMAT),
Expand Down
2 changes: 1 addition & 1 deletion packages/web3-eth/src/web3_eth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,7 @@ export class Web3Eth extends Web3Context<Web3EthExecutionAPI, RegisteredSubscrip
}

/**
* @param transaction The {@link Transaction}, {@link TransactionWithFromLocalWalletIndex}, {@link TransactionWithToLocalWalletIndex} or {@link TransactionWithFromAndToLocalWalletIndex} to send.
* @param transaction The {@link Transaction}, {@link TransactionWithFromLocalWalletIndex}, {@link TransactionWithToLocalWalletIndex} or {@link TransactionWithFromAndToLocalWalletIndex} to send. __Note:__ In the `to` and `from` fields when hex strings are used, it is assumed they are addresses, for any other form (number, string number, etc.) it is assumed they are wallet indexes.
* @param returnFormat ({@link DataFormat} defaults to {@link DEFAULT_RETURN_FORMAT}) Specifies how the return data should be formatted.
* @param options A configuration object used to change the behavior of the `sendTransaction` method.
* @returns If `await`ed or `.then`d (i.e. the promise resolves), the transaction hash is returned.
Expand Down
11 changes: 7 additions & 4 deletions packages/web3-eth/test/fixtures/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
export const InvalidTransactionWithSenderData: [unknown, string][] = [
[
BigInt(9007199254740991),
'Invalid value given "9007199254740991". Error: invalid transaction with sender.',
'Invalid value given "9007199254740991". Error: invalid transaction with invalid sender.',
],
['Invalid data', 'Invalid value given "Invalid data". Error: invalid transaction with sender.'],
['0x0', 'Invalid value given "0x0". Error: invalid transaction with sender.'],
[0, 'Invalid value given "0". Error: invalid transaction with sender.'],
[
'Invalid data',
'Invalid value given "Invalid data". Error: invalid transaction with invalid sender.',
],
['0x0', 'Invalid value given "0x0". Error: invalid transaction with invalid sender.'],
[0, 'Invalid value given "0". Error: invalid transaction with invalid sender.'],
];

export const InvalidTransactionCallData: [unknown, string][] = [
Expand Down
90 changes: 90 additions & 0 deletions packages/web3-eth/test/fixtures/format_transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,3 +245,93 @@ export const numbersAsBigIntTransaction: FormatType<
r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d',
s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0',
};

const dummyTransaction: Transaction = {
from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0',
to: '0x3535353535353535353535353535353535353535',
value: '0x174876e800',
gas: '0x5208',
gasPrice: '0x4a817c800',
type: '0x0',
data: '0x0',
nonce: '0x4',
chainId: '0x1',
gasLimit: '0x5208',
};
export const validGetTransactionFromOrToAttrData: { input: any; output: any }[] = [
{
input: {
role: 'from',
transaction: {
...dummyTransaction,
from: '0x58422b64d0e95ab4e93a9d95b755d9b53545c9ef',
},
},
output: '0x58422b64d0e95ab4e93a9d95b755d9b53545c9ef',
},
];
export const invalidGetTransactionFromOrToAttrData: { input: any; output: any }[] = [
{
input: {
role: 'from',
transaction: {
...dummyTransaction,
from: '0x58422b64d0e95ab4e93a9d95b755d9b53545c9eff',
},
},
output: 'Invalid value given "0x58422b64d0e95ab4e93a9d95b755d9b53545c9eff". Error: invalid transaction with invalid sender',
},
{
input: {
role: 'to',
transaction: {
...dummyTransaction,
to: '0x58422b64d0e95ab4e93a9d95b755d9b53545c9eff',
},
},
output: 'Invalid value given "0x58422b64d0e95ab4e93a9d95b755d9b53545c9eff". Error: invalid transaction with invalid receiver',
},
{
input: {
role: 'from',
transaction: {
...dummyTransaction,
from: '0x1',
},
},
output: 'Invalid value given "0x1". Error: invalid transaction with invalid sender',
},
{
input: {
role: 'from',
transaction: {
...dummyTransaction,
from: 1,
},
},
output: 'Invalid value given "LocalWalletNotAvailableError". Error: Attempted to index account in local wallet, but no wallet is available.',
},
];

export const invalidGetTransactionFromOrToAttrDataForWallet: { input: any; output: any }[] = [
{
input: {
role: 'from',
transaction: {
...dummyTransaction,
from: 1,
},
},
output: 'Invalid value given "LocalWalletNotAvailableError". Error: Attempted to index account in local wallet, but no wallet is available.',
},
{
input: {
role: 'from',
transaction: {
...dummyTransaction,
from: 10,
},
},
output: 'Invalid value given "LocalWalletNotAvailableError". Error: Attempted to index account in local wallet, but no wallet is available.',
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
This file is part of web3.js.
web3.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
web3.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/

import { Web3Context } from 'web3-core';

import { Wallet } from 'web3-eth-accounts';
import { getTransactionFromOrToAttr } from '../../../src/utils/transaction_builder';
import {
validGetTransactionFromOrToAttrData,
invalidGetTransactionFromOrToAttrData,
invalidGetTransactionFromOrToAttrDataForWallet,
} from '../../fixtures/format_transaction';
import { createAccountProvider } from '../../fixtures/system_test_utils';

import Web3Eth from '../../../src';

describe('getTransactionFromOrToAttr', () => {
const web3Context = new Web3Context();

describe('valid data', () => {
it.each(validGetTransactionFromOrToAttrData)('$title', ({ input, output }) => {
const { role, transaction } = input;

expect(getTransactionFromOrToAttr(role, web3Context, transaction)).toEqual(output);
});
});

describe('invalid data', () => {
it.each(invalidGetTransactionFromOrToAttrData)('$title', ({ input, output }) => {
const { role, transaction } = input;
expect(() => getTransactionFromOrToAttr(role, web3Context, transaction)).toThrow(
output,
);
});

it.each(invalidGetTransactionFromOrToAttrDataForWallet)(
'$title with wallet',
({ input, output }) => {
const privateKey =
'0x348ce564d427a3311b6536bbcff9390d69395b06ed6c486954e971d960fe8709';

// setup wallet
const web3Eth = new Web3Eth('http://localhost:8545');
const accountProvider = createAccountProvider(web3Eth);
const wallet = new Wallet(accountProvider);
web3Eth.wallet?.add(privateKey);
web3Eth['_wallet'] = wallet;

const { role, transaction } = input;
expect(() => getTransactionFromOrToAttr(role, web3Eth, transaction)).toThrow(
output,
);
},
);
});
});

0 comments on commit c019149

Please sign in to comment.