Skip to content

Commit

Permalink
Wyatt/4.x/4789 transaction rpc methods (#4792)
Browse files Browse the repository at this point in the history
* Add @ethereumjs/tx dependency

* Update Web3BaseProvider to SupportedProviders for Web3Eth constructor

* WIP eth-tx

* Add support for undefined values for convertToValidType

* Remove unused Web3BaseProvider

* WIP eth-tx utils

* Export privateKeyToAddress

* Add web3-eth-accounts dependency

* WIP web3-eth-tx util methods

* Replace inline errors with error constructors

* Change types for transaction r and s properties. Correct hardforks in detectTransactionType

* Init formatTransaction tests and fixture

* Init detectTransactionType and fixture

* Add more descriptive error messages

* Logic fixes for validateTransactionForSigning

* Init validateTransactionForSigning tests and fixtures

* Add esModuleInterop: true to tsconfig

* Small bug fixes and added TODOs

* Add parent describe to detect_transaction_type test

* Add parent describe to format_transaction test

* Add web3-providers-http as dev dependency for tests

* Init populate_transaction tests

* Move types from eth_tx.ts to types.ts

* Remove TODOs

* Add missing ,

* Remove TODO

* Remove TODO

* Fix transaction type import issues

* Update convertToValidType test data for undefined

* Update override method tests

* Update packages/web3-eth/src/eth_tx.ts

Co-authored-by: jdevcs <86780488+jdevcs@users.noreply.github.com>

* Move getBlock to after type check for populateTransaction

* Replace N/A with name of error for error.msg

* Assign formattedTransaction type Transaction<ReturnType>

* convertToValidType now throws error for value === undefined

* NumberType extends Numbers

* Transaction type related changes

* Refactor DesiredType logic

* Convert to deep copy for formatTransaction method

* skip override method test - needs to be refactored. General formatting

* Skip override method test - needs to be refactored. Set input.type > 0x7f

* Refactor formatTransaction

* Add error codes to web3-eth errors

* Refactor validateGate if statements into readable consts

* Update comment

* Add link to error message from 1.x

* Fix bug with is gas consts in validateGas

* Init InvalidConvertibleValueError

* Replace error with InvalidConvertibleValueError

* Update tests for formatting undefined

* Update expected errors for validateGas tests

* No longer default tx.type if undefined

* Refactor detectTransactionType

* Fix type error for return in detectTransactionType

* Init rpc_method_wrappers.ts

* Remove Web3Eth import

* Refactor use of web3Context.defaults

* Restore Formatted transaction types

* Init web3_rpc_method_wrappers tests

* Refactor web3_eth_methods_with_parameters test

* Replace if X === undefined checks with ?

* Un-export consts that aren't used

* Add defaultTransactionType and defaultMaxPriorityFeePerGas

* Update defaults for chain and hardfork to mainnet and london

* Update to use web3Context.default chain and hardfork. Init tests for defaults

* Update test to account for added defaults

* Refactor validateGas to use helper methods

* remove TODO

* Init error TransactionGasMismatchError

* Fix tests and refactor transaction validator helper methods

* Move validation methods to validation.ts

* Add input to Transaction type

* Add @ethereumjs/common dependency

* yarn format

* Remove null for defaultTransactionType

* Add default for defaultTransactionType

* Update default for defaultTransactionType

* Bug fixes, refactors, and init prepareTransactionForSigning and tests

* Remove unused test code

* revert transaction data and value to default to 0x

* Fix failing populate_transaction tests

* Add defaultNetworkId to web3_config

* Add TODO for failing prepare_transaction_for_signing test

* Remove TODO

* Init TransactionDataAndInputError

* Add else if to populateTransaction - data

* Refactor populateTransaction - chainId

* Comment out unused ifs

* Remove populateTransaction - gas

* Remove populateTransaction - hexTxType

* Replace use of ValidReturnTypes[ValidTypes.HexString] with HexString

* Remove toHex import

* Remove | null for Web3ConfigOptions defaultChain and defaultHardfork

* Refactor getEthereumjsTransactionOptions

* Remove no longer needed populateTransaction - gas test

* Update packages/web3-eth/src/validation.ts

* Remove unnecessary rpc method wrappers

* Web3Eth now extends Web3Context instead of instantiating it

* Init getPendingTransactions

* Init requestAccounts

* Add EIP-1102 as a comment for requestAccounts

* Init getChainId

* Init getProof

* Init Web3EthExecutionAPI

* Fix imports for AccountObject in fixtures

* Add formatting to getPendingTransactions. Move formatTransaction to seperate file

* Add TODO to investigate transaction.data

* Add formatting to getChainId response

* Init getNodeInfo

* Revert esModuleInterop change

* Combine networkId and chainId if statements

* yarn format

* Add Partial to type of transaction for eth_sendTransaction

* Init transactionReceiptPollingInterval and transactionConfirmationPollingInterval

* Add TODO and Partial to transaction type for sendTransaction

* WIP sendTransaction and PromiEvent integration

* Add eslint-disable-next-line

* Add eslint-disable-next-line

* Move TransactionEvents

* eslint fixes

* Update sendSignedTransaction to use PromiEvent

* Init signTransaction

* Refactor TransactionCall

* Comment out validation for call

* Init TransactionCall type for web3-eth types

* Remove as BaseTransaction from isTransactionCall

* Implement call for rpc_method_wrappers

* Uncomment sendTransaction, signTransaction, and call

* Replace inline errors with error constructors

* Validate transaction.to for Call method in web3-eth

* Add transactionPollingInterval to Web3Context

* Fix bug for updating transactionPollingInterval and fix webConfig tests

* Temporarily disable sendSignedTransaction test

Co-authored-by: jdevcs <86780488+jdevcs@users.noreply.github.com>
Co-authored-by: Nazar Hussain <nazarhussain@gmail.com>
  • Loading branch information
3 people authored Mar 3, 2022
1 parent fc8acc1 commit 46746fc
Show file tree
Hide file tree
Showing 14 changed files with 424 additions and 71 deletions.
3 changes: 3 additions & 0 deletions packages/web3-common/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ export const ERR_TX_UNABLE_TO_POPULATE_NONCE = 422;
export const ERR_TX_UNSUPPORTED_EIP_1559 = 423;
export const ERR_TX_UNSUPPORTED_TYPE = 424;
export const ERR_TX_DATA_AND_INPUT = 425;
export const ERR_TX_POLLING_TIMEOUT = 426;
export const ERR_TX_RECEIPT_MISSING_OR_BLOCKHASH_NULL = 427;
export const ERR_TX_RECEIPT_MISSING_BLOCK_NUMBER = 428;

// Connection error codes
export const ERR_CONN = 500;
Expand Down
17 changes: 12 additions & 5 deletions packages/web3-common/src/eth_execution_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,17 @@ export type AccessList = AccessListEntry[];
export type TransactionHash = HexString;
export type Uncles = HexString32Bytes[];

// TODO Should probably support EIP-2930 and EIP-1559
export interface TransactionCall {
readonly from?: Address;
readonly to: Address;
readonly gas?: Uint;
readonly gasPrice?: Uint;
readonly value?: Uint;
readonly data?: HexString;
readonly data?: HexStringBytes;
readonly type?: HexStringSingleByte;
readonly maxFeePerGas?: Uint;
readonly maxPriorityFeePerGas?: Uint;
readonly accessList?: AccessList;
}

export interface BaseTransaction {
Expand All @@ -42,7 +45,7 @@ export interface BaseTransaction {
readonly value: Uint;
// TODO - Investigate if this should actually be data instead of input
readonly input: HexStringBytes;
chainId?: Uint;
readonly chainId?: Uint;
}

export interface Transaction1559Unsigned extends BaseTransaction {
Expand Down Expand Up @@ -257,7 +260,9 @@ export type EthExecutionAPI = {

// https://github.com/ethereum/execution-apis/blob/main/src/eth/sign.json
eth_sign: (address: Address, message: HexStringBytes) => HexString256Bytes;
eth_signTransaction: (transaction: TransactionWithSender) => HexStringBytes;
eth_signTransaction: (
transaction: TransactionWithSender | Partial<TransactionWithSender>,
) => HexStringBytes;

// https://github.com/ethereum/execution-apis/blob/main/src/eth/state.json
eth_getBalance: (address: Address, blockNumber: BlockNumberOrTag) => Uint;
Expand All @@ -270,7 +275,9 @@ export type EthExecutionAPI = {
eth_getCode: (address: Address, blockNumber: BlockNumberOrTag) => HexStringBytes;

// https://github.com/ethereum/execution-apis/blob/main/src/eth/submit.json
eth_sendTransaction: (transaction: TransactionWithSender) => HexString32Bytes;
eth_sendTransaction: (
transaction: TransactionWithSender | Partial<TransactionWithSender>,
) => HexString32Bytes;
eth_sendRawTransaction: (transaction: HexStringBytes) => HexString32Bytes;

// https://geth.ethereum.org/docs/rpc/pubsub
Expand Down
3 changes: 3 additions & 0 deletions packages/web3-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ export interface Web3ConfigOptions {
defaultBlock: HexString;
transactionBlockTimeout: number;
transactionConfirmationBlocks: number;
transactionPollingInterval: number;
transactionPollingTimeout: number;
transactionReceiptPollingInterval: number | null;
transactionConfirmationPollingInterval: number | null;
blockHeaderTimeout: number;
maxListenersWarningThreshold: number;
defaultNetworkId: Numbers | null;
Expand Down
48 changes: 48 additions & 0 deletions packages/web3-core/src/web3_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ export abstract class Web3Config
defaultBlock: 'latest',
transactionBlockTimeout: 50,
transactionConfirmationBlocks: 24,
transactionPollingInterval: 1000,
transactionPollingTimeout: 750,
transactionReceiptPollingInterval: null,
transactionConfirmationPollingInterval: null,
blockHeaderTimeout: 10,
maxListenersWarningThreshold: 100,
defaultNetworkId: null,
Expand Down Expand Up @@ -104,6 +107,23 @@ export abstract class Web3Config
this._config.transactionConfirmationBlocks = val;
}

public get transactionPollingInterval() {
return this._config.transactionPollingInterval;
}

public set transactionPollingInterval(val) {
this.emit(Web3ConfigEvent.CONFIG_CHANGE, {
name: 'transactionPollingInterval',
oldValue: this._config.transactionPollingInterval,
newValue: val,
});

this._config.transactionPollingInterval = val;

this.transactionReceiptPollingInterval = val;
this.transactionConfirmationPollingInterval = val;
}

public get transactionPollingTimeout() {
return this._config.transactionPollingTimeout;
}
Expand All @@ -118,6 +138,34 @@ export abstract class Web3Config
this._config.transactionPollingTimeout = val;
}

public get transactionReceiptPollingInterval() {
return this._config.transactionReceiptPollingInterval;
}

public set transactionReceiptPollingInterval(val) {
this.emit(Web3ConfigEvent.CONFIG_CHANGE, {
name: 'transactionReceiptPollingInterval',
oldValue: this._config.transactionReceiptPollingInterval,
newValue: val,
});

this._config.transactionReceiptPollingInterval = val;
}

public get transactionConfirmationPollingInterval() {
return this._config.transactionConfirmationPollingInterval;
}

public set transactionConfirmationPollingInterval(val) {
this.emit(Web3ConfigEvent.CONFIG_CHANGE, {
name: 'transactionConfirmationPollingInterval',
oldValue: this._config.transactionConfirmationPollingInterval,
newValue: val,
});

this._config.transactionConfirmationPollingInterval = val;
}

public get blockHeaderTimeout() {
return this._config.blockHeaderTimeout;
}
Expand Down
1 change: 1 addition & 0 deletions packages/web3-core/src/web3_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export class Web3Context<
API extends Web3APISpec,
RegisteredSubs extends {
[key: string]: Web3SubscriptionConstructor<API>;
// eslint-disable-next-line @typescript-eslint/ban-types
} = {},
> extends Web3Config {
public static readonly providers = Web3RequestManager.providers;
Expand Down
1 change: 1 addition & 0 deletions packages/web3-core/src/web3_subscriptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export abstract class Web3Subscription<

export type Web3SubscriptionConstructor<
API extends Web3APISpec,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
SubscriptionType extends Web3Subscription<any, any, API> = Web3Subscription<any, any, API>,
> = new (
// We accept any type of arguments here and don't deal with this type internally
Expand Down
30 changes: 30 additions & 0 deletions packages/web3-core/test/unit/web3_config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ const defaultConfig = {
maxListenersWarningThreshold: 100,
transactionBlockTimeout: 50,
transactionConfirmationBlocks: 24,
transactionPollingInterval: 1000,
transactionPollingTimeout: 750,
transactionReceiptPollingInterval: null,
transactionConfirmationPollingInterval: null,
defaultTransactionType: '0x0',
defaultMaxPriorityFeePerGas: toHex(2500000000),
};
Expand Down Expand Up @@ -64,6 +67,8 @@ describe('Web3Config', () => {

obj[key as never] = 'newValue' as never;

if (key === 'transactionPollingInterval') return;

expect(configChange).toHaveBeenCalledTimes(1);
expect(configChange).toHaveBeenCalledWith({
name: key,
Expand All @@ -72,4 +77,29 @@ describe('Web3Config', () => {
});
},
);

it('Updating transactionPollingInterval should update transactionReceiptPollingInterval and transactionConfirmationPollingInterval', () => {
const obj = new MyConfigObject();
const configChange = jest.fn();
obj.on(Web3ConfigEvent.CONFIG_CHANGE, configChange);

obj.transactionPollingInterval = 1500;

expect(configChange).toHaveBeenCalledTimes(3);
expect(configChange).toHaveBeenCalledWith({
name: 'transactionPollingInterval',
oldValue: defaultConfig.transactionPollingInterval,
newValue: 1500,
});
expect(configChange).toHaveBeenCalledWith({
name: 'transactionReceiptPollingInterval',
oldValue: defaultConfig.transactionReceiptPollingInterval,
newValue: 1500,
});
expect(configChange).toHaveBeenCalledWith({
name: 'transactionConfirmationPollingInterval',
oldValue: defaultConfig.transactionConfirmationPollingInterval,
newValue: 1500,
});
});
});
36 changes: 35 additions & 1 deletion packages/web3-eth/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ import {
ERR_TX_INVALID_FEE_MARKET_GAS_PRICE,
ERR_TX_INVALID_LEGACY_GAS,
ERR_TX_DATA_AND_INPUT,
ERR_TX_POLLING_TIMEOUT,
ERR_TX_RECEIPT_MISSING_OR_BLOCKHASH_NULL,
ERR_TX_RECEIPT_MISSING_BLOCK_NUMBER,
ReceiptInfo,
} from 'web3-common';
import { HexString, Numbers, Web3Error } from 'web3-utils';
import { HexString, HexString32Bytes, Numbers, Web3Error } from 'web3-utils';

export class InvalidTransactionWithSender extends Web3Error {
public code = ERR_TX_INVALID_SENDER;
Expand Down Expand Up @@ -241,3 +245,33 @@ export class TransactionDataAndInputError extends Web3Error {
);
}
}

export class TransactionPollingTimeoutError extends Web3Error {
public code = ERR_TX_POLLING_TIMEOUT;

public constructor(value: { numberOfSeconds: number; transactionHash: HexString32Bytes }) {
super(
`transactionHash: ${value.transactionHash}`,
`Transaction was not mined within ${value.numberOfSeconds} seconds, please make sure your transaction was properly sent. Be aware that it might still be mined!`,
);
}
}

export class TransactionMissingReceiptOrBlockHashError extends Web3Error {
public code = ERR_TX_RECEIPT_MISSING_OR_BLOCKHASH_NULL;

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

export class TransactionReceiptMissingBlockNumberError extends Web3Error {
public code = ERR_TX_RECEIPT_MISSING_BLOCK_NUMBER;

public constructor(value: { receipt: ReceiptInfo }) {
super(`receipt: ${JSON.stringify(value.receipt)}`, `Receipt missing block number`);
}
}
28 changes: 13 additions & 15 deletions packages/web3-eth/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
Filter,
} from 'web3-utils';

import { BlockFormatted } from './types';
import { BlockFormatted, Transaction, TransactionCall } from './types';
import * as rpcMethods from './rpc_methods';
import * as rpcMethodsWrappers from './rpc_method_wrappers';
import { Web3EthExecutionAPI } from './web3_eth_execution_api';
Expand Down Expand Up @@ -150,10 +150,9 @@ export default class Web3Eth extends Web3Context<Web3EthExecutionAPI> {
return rpcMethodsWrappers.getTransactionCount(this, address, blockNumber, returnType);
}

// TODO Needs to convert input to hex string
// public async sendTransaction(transaction: Transaction) {
// return rpcMethodsWrappers.sendTransaction(this, transaction);
// }
public async sendTransaction(transaction: Transaction) {
return rpcMethodsWrappers.sendTransaction(this, transaction);
}

public async sendSignedTransaction(transaction: HexStringBytes) {
return rpcMethods.sendRawTransaction(this.requestManager, transaction);
Expand All @@ -165,19 +164,18 @@ export default class Web3Eth extends Web3Context<Web3EthExecutionAPI> {
return rpcMethods.sign(this.requestManager, message, address);
}

// TODO Needs to convert input to hex string
// public async signTransaction(transaction: Transaction) {
// return rpcMethodsWrappers.signTransaction(this, transaction);
// }
public async signTransaction(transaction: Transaction) {
return rpcMethodsWrappers.signTransaction(this, transaction);
}

// TODO Decide what to do with transaction.to
// https://github.com/ChainSafe/web3.js/pull/4525#issuecomment-982330076
// public async call(
// transaction: Transaction & { to: Address },
// blockNumber: BlockNumberOrTag = this.defaultBlock,
// ) {
// return rpcMethodsWrappers.call(this, transaction, blockNumber);
// }
public async call(
transaction: TransactionCall,
blockNumber: BlockNumberOrTag = this.defaultBlock,
) {
return rpcMethodsWrappers.call(this, transaction, blockNumber);
}

// TODO Missing param
public async estimateGas<ReturnType extends ValidTypes = ValidTypes.HexString>(
Expand Down
Loading

0 comments on commit 46746fc

Please sign in to comment.