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

Commit 6c075db

Browse files
Increase Unit test coverage for web3-eth above 90% (#6663)
* fix issues in Common config and add a test to accounts * add test cases * update CHAGELOG.md
1 parent 6b2dbe3 commit 6c075db

File tree

6 files changed

+440
-79
lines changed

6 files changed

+440
-79
lines changed

packages/web3-eth-accounts/CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,8 @@ Documentation:
149149

150150
- Fixed `recover` function, `v` will be normalized to value 0,1 (#6344)
151151

152-
## [Unreleased]
152+
## [Unreleased]
153+
154+
### Fixed
155+
156+
- Send Transaction config used to be ignored if the passed `common` did not have a `copy()` and the `chainId` was not provided (#6663)

packages/web3-eth-accounts/src/tx/baseTransaction.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ You should have received a copy of the GNU Lesser General Public License
1515
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
1616
*/
1717

18-
import { Numbers } from 'web3-types';
18+
import { Common as CommonType, Numbers } from 'web3-types';
1919
import { bytesToHex } from 'web3-utils';
2020
import { MAX_INTEGER, MAX_UINT64, SECP256K1_ORDER_DIV_2, secp256k1 } from './constants.js';
2121
import { toUint8Array, uint8ArrayToBigInt, unpadUint8Array } from '../common/utils.js';
@@ -389,6 +389,8 @@ export abstract class BaseTransaction<TransactionObject> {
389389
* @param chainId - Chain ID from tx options (typed txs) or signature (legacy tx)
390390
*/
391391
protected _getCommon(common?: Common, chainId?: Numbers) {
392+
// TODO: this function needs to be reviewed and the code to be more clean
393+
// check issue https://github.com/web3/web3.js/issues/6666
392394
// Chain ID provided
393395
if (chainId !== undefined) {
394396
const chainIdBigInt = uint8ArrayToBigInt(toUint8Array(chainId));
@@ -425,6 +427,34 @@ export abstract class BaseTransaction<TransactionObject> {
425427
if (common?.copy && typeof common?.copy === 'function') {
426428
return common.copy();
427429
}
430+
// TODO: Recheck this next block when working on https://github.com/web3/web3.js/issues/6666
431+
// This block is to handle when `chainId` was not passed and the `common` object does not have `copy()`
432+
// If it was meant to be unsupported to process `common` in this case, an exception should be thrown instead of the following block
433+
if (common) {
434+
const hardfork =
435+
typeof common.hardfork === 'function'
436+
? common.hardfork()
437+
: // eslint-disable-next-line @typescript-eslint/unbound-method
438+
(common.hardfork as unknown as string);
439+
440+
return Common.custom(
441+
{
442+
name: 'custom-chain',
443+
networkId: common.networkId
444+
? common.networkId()
445+
: BigInt((common as unknown as CommonType).customChain?.networkId) ??
446+
undefined,
447+
chainId: common.chainId
448+
? common.chainId()
449+
: BigInt((common as unknown as CommonType).customChain?.chainId) ??
450+
undefined,
451+
},
452+
{
453+
baseChain: this.DEFAULT_CHAIN,
454+
hardfork: hardfork || this.DEFAULT_HARDFORK,
455+
},
456+
);
457+
}
428458

429459
return new Common({ chain: this.DEFAULT_CHAIN, hardfork: this.DEFAULT_HARDFORK });
430460
}

packages/web3-eth/src/utils/prepare_transaction_for_signing.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ const getEthereumjsTransactionOptions = (
6868
if (!hasTransactionSigningOptions) {
6969
// if defaultcommon is specified, use that.
7070
if (web3Context.defaultCommon) {
71-
common = web3Context.defaultCommon;
71+
common = { ...web3Context.defaultCommon };
7272

7373
if (isNullish(common.hardfork))
7474
common.hardfork = transaction.hardfork ?? web3Context.defaultHardfork;

packages/web3-eth/test/unit/prepare_transaction_for_signing.test.ts

Lines changed: 149 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
1616
*/
1717

1818
import {
19-
Common,
2019
EthExecutionAPI,
2120
HexString,
2221
Web3NetAPI,
@@ -33,6 +32,7 @@ import {
3332
AccessListEIP2930Transaction,
3433
FeeMarketEIP1559Transaction,
3534
Transaction,
35+
Hardfork,
3636
} from 'web3-eth-accounts';
3737
import { prepareTransactionForSigning } from '../../src/utils/prepare_transaction_for_signing';
3838
import { validTransactions } from '../fixtures/prepare_transaction_for_signing';
@@ -70,7 +70,7 @@ describe('prepareTransactionForSigning', () => {
7070

7171
if (isNullish(tx.common)) {
7272
if (options.web3Context.defaultCommon) {
73-
const common = options.web3Context.defaultCommon as unknown as Common;
73+
const common = options.web3Context.defaultCommon;
7474
const chainId = common.customChain.chainId as string;
7575
const networkId = common.customChain.networkId as string;
7676
const name = common.customChain.name as string;
@@ -102,6 +102,153 @@ describe('prepareTransactionForSigning', () => {
102102
expect(ethereumjsTx.common.chainName()).toBe('test');
103103
});
104104
});
105+
106+
it('should be able to read Hardfork from context.defaultHardfork', async () => {
107+
const context = new Web3Context<EthExecutionAPI>({
108+
provider: new HttpProvider('http://127.0.0.1'),
109+
config: { defaultNetworkId: '0x9' },
110+
});
111+
context.defaultChain = 'mainnet';
112+
context.defaultHardfork = Hardfork.Istanbul;
113+
114+
async function transactionBuilder<ReturnType = TransactionType>(options: {
115+
transaction: TransactionType;
116+
web3Context: Web3Context<EthExecutionAPI & Web3NetAPI>;
117+
privateKey?: HexString | Uint8Array;
118+
fillGasPrice?: boolean;
119+
fillGasLimit?: boolean;
120+
}): Promise<ReturnType> {
121+
const tx = { ...options.transaction };
122+
return tx as unknown as ReturnType;
123+
}
124+
125+
context.transactionBuilder = transactionBuilder;
126+
127+
const ethereumjsTx = await prepareTransactionForSigning(
128+
{
129+
chainId: 1458,
130+
nonce: 1,
131+
gasPrice: BigInt(20000000000),
132+
gas: BigInt(21000),
133+
to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55',
134+
from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23',
135+
value: '1000000000',
136+
input: '',
137+
networkId: 999,
138+
},
139+
context,
140+
);
141+
expect(ethereumjsTx.common.hardfork()).toBe(Hardfork.Istanbul);
142+
expect(ethereumjsTx.common.networkId().toString()).toBe('999');
143+
});
144+
145+
it('should be able to read Hardfork from context.config.defaultHardfork and context.defaultCommon.hardfork', async () => {
146+
const context = new Web3Context<EthExecutionAPI>({
147+
provider: new HttpProvider('http://127.0.0.1'),
148+
config: { defaultNetworkId: '0x9' },
149+
});
150+
context.defaultChain = 'mainnet';
151+
152+
// if the value here is different from the one in context.defaultCommon.hardfork
153+
// Then an error will be thrown:
154+
// "ConfigHardforkMismatchError: Web3Config hardfork doesnt match in defaultHardfork london and common.hardfork istanbul"
155+
context.config.defaultHardfork = Hardfork.Istanbul;
156+
context.defaultCommon = {
157+
customChain: {
158+
name: 'test',
159+
networkId: 111,
160+
chainId: 1458,
161+
},
162+
hardfork: Hardfork.Istanbul,
163+
baseChain: 'mainnet',
164+
} as any;
165+
166+
async function transactionBuilder<ReturnType = TransactionType>(options: {
167+
transaction: TransactionType;
168+
web3Context: Web3Context<EthExecutionAPI & Web3NetAPI>;
169+
privateKey?: HexString | Uint8Array;
170+
fillGasPrice?: boolean;
171+
fillGasLimit?: boolean;
172+
}): Promise<ReturnType> {
173+
const tx = { ...options.transaction };
174+
return tx as unknown as ReturnType;
175+
}
176+
177+
context.transactionBuilder = transactionBuilder;
178+
179+
const ethereumjsTx = await prepareTransactionForSigning(
180+
{
181+
chainId: 1458,
182+
nonce: 1,
183+
gasPrice: BigInt(20000000000),
184+
gas: BigInt(21000),
185+
to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55',
186+
from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23',
187+
value: '1000000000',
188+
input: '',
189+
},
190+
context,
191+
);
192+
expect(ethereumjsTx.common.hardfork()).toBe(Hardfork.Istanbul);
193+
expect(ethereumjsTx.common.networkId().toString()).toBe('111');
194+
});
195+
196+
it('should give priorities to tx.hardfork and tx.networkId over values from context', async () => {
197+
const context = new Web3Context<EthExecutionAPI>({
198+
provider: new HttpProvider('http://127.0.0.1'),
199+
config: { defaultNetworkId: '0x9' },
200+
});
201+
context.defaultChain = 'mainnet';
202+
203+
// if the value here is different from the one in context.defaultCommon.hardfork
204+
// Then an error will be thrown:
205+
// "ConfigHardforkMismatchError: Web3Config hardfork doesnt match in defaultHardfork london and common.hardfork istanbul"
206+
context.config.defaultHardfork = Hardfork.Istanbul;
207+
context.defaultCommon = {
208+
customChain: {
209+
name: 'test',
210+
networkId: 111,
211+
chainId: 1458,
212+
},
213+
hardfork: Hardfork.Istanbul,
214+
baseChain: 'mainnet',
215+
} as any;
216+
217+
async function transactionBuilder<ReturnType = TransactionType>(options: {
218+
transaction: TransactionType;
219+
web3Context: Web3Context<EthExecutionAPI & Web3NetAPI>;
220+
privateKey?: HexString | Uint8Array;
221+
fillGasPrice?: boolean;
222+
fillGasLimit?: boolean;
223+
}): Promise<ReturnType> {
224+
const tx = { ...options.transaction };
225+
return tx as unknown as ReturnType;
226+
}
227+
228+
context.transactionBuilder = transactionBuilder;
229+
230+
// context.transactionBuilder = defaultTransactionBuilder;
231+
232+
const ethereumjsTx = await prepareTransactionForSigning(
233+
{
234+
chainId: 1458,
235+
nonce: 1,
236+
gasPrice: BigInt(20000000000),
237+
gas: BigInt(21000),
238+
to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55',
239+
from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23',
240+
value: '1000000000',
241+
input: '',
242+
networkId: 999,
243+
hardfork: Hardfork.Chainstart,
244+
chain: 'mainnet',
245+
},
246+
context,
247+
);
248+
expect(ethereumjsTx.common.hardfork()).toBe(Hardfork.Chainstart);
249+
expect(ethereumjsTx.common.networkId().toString()).toBe('999');
250+
});
251+
105252
describe('should return an web3-utils/tx instance with expected properties', () => {
106253
it.each(validTransactions)(
107254
'mockBlock: %s\nexpectedTransaction: %s\nexpectedPrivateKey: %s\nexpectedAddress: %s\nexpectedRlpEncodedTransaction: %s\nexpectedTransactionHash: %s\nexpectedMessageToSign: %s\nexpectedV: %s\nexpectedR: %s\nexpectedS: %s',

0 commit comments

Comments
 (0)