diff --git a/packages/web3-core/CHANGELOG.md b/packages/web3-core/CHANGELOG.md
index 67ef64ece5b..8f61b018479 100644
--- a/packages/web3-core/CHANGELOG.md
+++ b/packages/web3-core/CHANGELOG.md
@@ -227,4 +227,8 @@ Documentation:
- Now when existing packages are added in web3, will be avalible for plugins via context. (#7088)
-## [Unreleased]
\ No newline at end of file
+## [Unreleased]
+
+### Fixed
+
+- `setConfig()` fix for `setMaxListenerWarningThreshold` fix (#5079)
diff --git a/packages/web3-core/src/web3_config.ts b/packages/web3-core/src/web3_config.ts
index 3c335292c4a..03e478e9ecd 100644
--- a/packages/web3-core/src/web3_config.ts
+++ b/packages/web3-core/src/web3_config.ts
@@ -114,6 +114,14 @@ export abstract class Web3Config
const keys = Object.keys(options) as (keyof Web3ConfigOptions)[];
for (const key of keys) {
this._triggerConfigChange(key, options[key]);
+
+ if(!isNullish(options[key]) &&
+ typeof options[key] === 'number' &&
+ key === 'maxListenersWarningThreshold' )
+ {
+ // additionally set in event emitter
+ this.setMaxListenerWarningThreshold(Number(options[key]));
+ }
}
Object.assign(this.config, options);
}
diff --git a/packages/web3-eth-contract/test/integration/setup.js b/packages/web3-eth-contract/test/integration/setup.js
index 6170e9ca349..26ba888e0cf 100644
--- a/packages/web3-eth-contract/test/integration/setup.js
+++ b/packages/web3-eth-contract/test/integration/setup.js
@@ -19,6 +19,6 @@ along with web3.js. If not, see .
// eslint-disable-next-line @typescript-eslint/no-require-imports
require('../config/setup');
-const jestTimeout = String(process.env.WEB3_SYSTEM_TEST_PROVIDER).includes('ipc') ? 35000 : 15000;
+const jestTimeout = String(process.env.WEB3_SYSTEM_TEST_PROVIDER).includes('ipc') ? 35000 : 25000;
jest.setTimeout(jestTimeout);
diff --git a/packages/web3-eth-contract/test/unit/contract.test.ts b/packages/web3-eth-contract/test/unit/contract.test.ts
index 449280c41a7..6ae5f055904 100644
--- a/packages/web3-eth-contract/test/unit/contract.test.ts
+++ b/packages/web3-eth-contract/test/unit/contract.test.ts
@@ -38,7 +38,6 @@ import {
GreeterWithOverloadingBytecode,
} from '../shared_fixtures/build/GreeterWithOverloading';
import { AllGetPastEventsData, getLogsData, getPastEventsData } from '../fixtures/unitTestFixtures';
-import { getSystemTestProvider } from '../fixtures/system_test_utils';
import { erc721Abi } from '../fixtures/erc721';
import { ERC20TokenAbi } from '../shared_fixtures/build/ERC20Token';
import { processAsync } from '../shared_fixtures/utils';
@@ -150,7 +149,7 @@ describe('Contract', () => {
});
it('should set the provider, from options, upon instantiation', () => {
- const provider = getSystemTestProvider();
+ const provider = "http://127.0.0.1:4545";
const contract = new Contract([], '', {
provider,
});
@@ -162,7 +161,7 @@ describe('Contract', () => {
});
it('should set the provider, from context, upon instantiation', () => {
- const provider = getSystemTestProvider();
+ const provider = "http://127.0.0.1:4545";
const contract = new Contract(
[],
'',
@@ -816,9 +815,9 @@ describe('Contract', () => {
'0x00000000219ab540356cBB839Cbe05303d7705Fa',
{ gas: '0x97254' },
);
-
+ contract.maxListenersWarningThreshold = 1000;
+
const clonnedContract = contract.clone();
-
expect(stringify(contract)).toStrictEqual(stringify(clonnedContract));
contract.options.jsonInterface = GreeterAbi;
@@ -826,7 +825,8 @@ describe('Contract', () => {
it('should clone new contract', () => {
const contract = new Contract(sampleStorageContractABI);
-
+ contract.maxListenersWarningThreshold = 1000;
+
const clonnedContract = contract.clone();
expect(stringify(contract)).toStrictEqual(stringify(clonnedContract));
});
diff --git a/packages/web3-eth/package.json b/packages/web3-eth/package.json
index 75b35059356..3f18fcd83d5 100644
--- a/packages/web3-eth/package.json
+++ b/packages/web3-eth/package.json
@@ -40,7 +40,7 @@
"test:e2e:sepolia": "jest --config=./test/e2e/jest.config.js --forceExit",
"test:watch": "npm test -- --watch",
"test:unit": "jest --config=./test/unit/jest.config.js",
- "test:integration": "jest --config=./test/integration/jest.config.js --runInBand --forceExit",
+ "test:integration": "jest --config=./test/integration/jest.config.js --runInBand",
"test:coverage:integration": "jest --config=./test/integration/jest.config.js --runInBand --forceExit --coverage=true --coverage-reporters=text",
"test:e2e:electron": "npx cypress run --headless --browser electron",
"test:e2e:chrome": "npx cypress run --headless --browser chrome",
diff --git a/packages/web3-eth/test/integration/defaults.test.ts b/packages/web3-eth/test/integration/defaults.test.ts
index a9651fa20e3..351152158b4 100644
--- a/packages/web3-eth/test/integration/defaults.test.ts
+++ b/packages/web3-eth/test/integration/defaults.test.ts
@@ -41,6 +41,7 @@ import {
getSystemTestProvider,
isIpc,
sendFewSampleTxs,
+ waitForCondition
} from '../fixtures/system_test_utils';
import {
@@ -51,11 +52,10 @@ import {
import { BasicAbi, BasicBytecode } from '../shared_fixtures/build/Basic';
import { MsgSenderAbi, MsgSenderBytecode } from '../shared_fixtures/build/MsgSender';
import { getTransactionGasPricing } from '../../src/utils/get_transaction_gas_pricing';
-import { Resolve, sendFewTxes } from './helper';
+import { sendFewTxes } from './helper';
describe('defaults', () => {
let web3Eth: Web3Eth;
- let eth2: Web3Eth;
let clientUrl: string | SupportedProviders;
let contract: Contract;
let deployOptions: Record;
@@ -76,10 +76,8 @@ describe('defaults', () => {
afterEach(async () => {
await closeOpenConnection(web3Eth);
- await closeOpenConnection(eth2);
+ await closeOpenConnection(contract);
});
-
- describe('defaults', () => {
it('defaultAccount', async () => {
const tempAcc2 = await createTempAccount();
const tempAcc3 = await createTempAccount();
@@ -102,7 +100,7 @@ describe('defaults', () => {
expect(web3Eth.defaultAccount).toBe(tempAcc.address);
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
config: {
defaultAccount: tempAcc3.address,
},
@@ -152,6 +150,8 @@ describe('defaults', () => {
expect((fromPass2 as unknown as string).toLowerCase()).toBe(
tempAcc2.address.toLowerCase(),
);
+ await closeOpenConnection(eth2);
+ await closeOpenConnection(contractMsgFrom);
});
it('handleRevert', () => {
/*
@@ -174,7 +174,7 @@ describe('defaults', () => {
expect(web3Eth.handleRevert).toBe(true);
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
config: {
handleRevert: true,
},
@@ -203,7 +203,7 @@ describe('defaults', () => {
expect(web3Eth.defaultBlock).toBe('earliest');
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
provider: web3Eth.provider,
config: {
defaultBlock: 'earliest',
@@ -266,8 +266,10 @@ describe('defaults', () => {
expect(Number(hexToNumber(storageLatest))).toBe(10);
expect(transactionCountLatest).toBe(BigInt(1));
expect(Number(balanceLatest)).toBeGreaterThan(0);
+ await closeOpenConnection(eth2);
+ await closeOpenConnection(contractDeployed);
});
- it('transactionSendTimeout', () => {
+ it('transactionSendTimeout', async () => {
// default
expect(web3Eth.transactionSendTimeout).toBe(750 * 1000);
@@ -278,13 +280,14 @@ describe('defaults', () => {
expect(web3Eth.transactionSendTimeout).toBe(1);
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
provider: web3Eth.provider,
config: {
transactionSendTimeout: 120,
},
});
expect(eth2.transactionSendTimeout).toBe(120);
+ await closeOpenConnection(eth2);
});
it('transactionBlockTimeout', () => {
// default
@@ -297,14 +300,14 @@ describe('defaults', () => {
expect(web3Eth.transactionBlockTimeout).toBe(1);
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
config: {
transactionBlockTimeout: 120,
},
});
expect(eth2.transactionBlockTimeout).toBe(120);
});
- it('transactionConfirmationBlocks', () => {
+ it('transactionConfirmationBlocks default change should work', async () => {
// default
// eslint-disable-next-line jest/no-standalone-expect
expect(web3Eth.transactionConfirmationBlocks).toBe(24);
@@ -317,23 +320,28 @@ describe('defaults', () => {
expect(web3Eth.transactionConfirmationBlocks).toBe(3);
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
config: {
transactionConfirmationBlocks: 4,
},
});
// eslint-disable-next-line jest/no-standalone-expect
expect(eth2.transactionConfirmationBlocks).toBe(4);
+
});
+
it('transactionConfirmationBlocks implementation', async () => {
const tempAcc2 = await createTempAccount();
const waitConfirmations = 1;
- const eth = new Web3Eth(web3Eth.provider);
+ const eth = new Web3Eth(getSystemTestProvider());
eth.setConfig({ transactionConfirmationBlocks: waitConfirmations });
-
+
const from = tempAcc.address;
const to = tempAcc2.address;
const value = `0x1`;
+
+ let confirmationCount = 0;
+
const sentTx: Web3PromiEvent<
TransactionReceipt,
SendTransactionEvents
@@ -341,35 +349,29 @@ describe('defaults', () => {
to,
value,
from,
+ }).on('confirmation', (_data) => {
+ confirmationCount += 1;
+ if (confirmationCount >= waitConfirmations) {
+ sentTx.removeAllListeners(); // Clean up listeners
+ }
});
- const receiptPromise = new Promise((resolve: Resolve) => {
- // Tx promise is handled separately
- // eslint-disable-next-line no-void
- void sentTx.on('receipt', (params: TransactionReceipt) => {
- expect(Number(params.status)).toBe(1);
- resolve();
- });
- });
- let shouldBe = 1;
- const confirmationPromise = new Promise((resolve: Resolve) => {
- // Tx promise is handled separately
- // eslint-disable-next-line no-void
- void sentTx.on('confirmation', ({ confirmations }) => {
- expect(Number(confirmations)).toBeGreaterThanOrEqual(shouldBe);
- shouldBe += 1;
- if (shouldBe > waitConfirmations) {
- resolve();
- }
- });
- });
- await sentTx;
- await receiptPromise;
- await sendFewSampleTxs(isIpc ? 2 * waitConfirmations : waitConfirmations);
- await confirmationPromise;
- await closeOpenConnection(eth);
+ const receipt = await sentTx;
+ expect(Number(receipt.status)).toBe(1);
+
+ // Optionally send a few sample transactions
+ await sendFewSampleTxs(isIpc ? 5 * waitConfirmations : 2 * waitConfirmations);
+
+ expect(confirmationCount).toBe(waitConfirmations);
+
+ await waitForCondition(
+ () => confirmationCount >= waitConfirmations,
+ async () => { await closeOpenConnection(eth)},
+ 10,
+ 5000);
});
- it('transactionPollingInterval and transactionPollingTimeout', () => {
+
+ it('transactionPollingInterval and transactionPollingTimeout', async () => {
// default
expect(web3Eth.transactionPollingInterval).toBe(1000);
expect(web3Eth.transactionPollingTimeout).toBe(750 * 1000);
@@ -383,7 +385,7 @@ describe('defaults', () => {
expect(web3Eth.transactionPollingTimeout).toBe(10);
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
config: {
transactionPollingInterval: 400,
transactionPollingTimeout: 10,
@@ -451,7 +453,7 @@ describe('defaults', () => {
expect(web3Eth.transactionConfirmationPollingInterval).toBe(10);
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
config: {
transactionReceiptPollingInterval: 400,
transactionConfirmationPollingInterval: 10,
@@ -471,7 +473,7 @@ describe('defaults', () => {
expect(web3Eth.blockHeaderTimeout).toBe(3);
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
config: {
blockHeaderTimeout: 4,
},
@@ -497,7 +499,7 @@ describe('defaults', () => {
);
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
config: {
enableExperimentalFeatures: {
useSubscriptionWhenCheckingBlockTimeout: true,
@@ -524,7 +526,7 @@ describe('defaults', () => {
expect(web3Eth.enableExperimentalFeatures.useRpcCallSpecification).toBe(true);
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
config: {
enableExperimentalFeatures: {
useSubscriptionWhenCheckingBlockTimeout: false,
@@ -533,6 +535,7 @@ describe('defaults', () => {
},
});
expect(eth2.enableExperimentalFeatures.useRpcCallSpecification).toBe(true);
+
});
it('should fallback to polling if provider support `on` but `newBlockHeaders` does not arrive in `blockHeaderTimeout` seconds', async () => {
@@ -572,6 +575,7 @@ describe('defaults', () => {
value,
});
+ let confirmationCount = 0;
const confirmationPromise = new Promise((resolve: (status: bigint) => void) => {
// Tx promise is handled separately
// eslint-disable-next-line no-void
@@ -584,45 +588,47 @@ describe('defaults', () => {
confirmations: bigint;
receipt: { status: bigint };
}) => {
+ confirmationCount = Number(confirmations);
// Being able to get 2 confirmations means the polling for new blocks works
if (confirmations >= 2) {
sentTx.removeAllListeners();
resolve(status);
} else {
- // Send a transaction to cause dev providers creating new blocks to fire the 'confirmation' event again.
- await tempEth.sendTransaction({
- from,
- to,
- value,
- });
+ // Send few transaction to cause dev providers creating new blocks to fire the 'confirmation' event again.
+ await sendFewSampleTxs(5);
}
},
);
});
- await sentTx;
+ const receipt = await sentTx;
+ expect(Number(receipt.status)).toBe(1);
// Ensure the promise the get the confirmations resolves with no error
const status = await confirmationPromise;
expect(status).toBe(BigInt(1));
- await closeOpenConnection(tempEth);
+
+ await waitForCondition(
+ () => confirmationCount >= 2,
+ async () => { await closeOpenConnection(tempEth)});
});
+
it('maxListenersWarningThreshold test default config', () => {
// default
expect(web3Eth.maxListenersWarningThreshold).toBe(100);
});
it('maxListenersWarningThreshold set maxListeners through variable', () => {
- eth2 = new Web3Eth({});
+ const eth2 = new Web3Eth({});
eth2.maxListenersWarningThreshold = 3;
expect(eth2.maxListenersWarningThreshold).toBe(3);
expect(eth2.getMaxListeners()).toBe(3);
});
it('maxListenersWarningThreshold set config', () => {
- const eth = new Web3Eth({});
- eth.setConfig({
+ const eth3 = new Web3Eth({});
+ eth3.setConfig({
maxListenersWarningThreshold: 3,
});
- expect(eth2.maxListenersWarningThreshold).toBe(3);
- expect(eth2.getMaxListeners()).toBe(3);
+ expect(eth3.maxListenersWarningThreshold).toBe(3);
+ expect(eth3.getMaxListeners()).toBe(3);
});
it('defaultNetworkId', async () => {
// default
@@ -635,7 +641,7 @@ describe('defaults', () => {
expect(web3Eth.defaultNetworkId).toBe(3);
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
provider: web3Eth.provider,
config: {
defaultNetworkId: 4,
@@ -666,6 +672,8 @@ describe('defaults', () => {
});
expect(resWithPassNetworkId.networkId).toBe(BigInt(5));
+
+ await closeOpenConnection(eth2);
});
it('defaultChain', async () => {
// default
@@ -678,7 +686,7 @@ describe('defaults', () => {
expect(web3Eth.defaultChain).toBe('ropsten');
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
provider: web3Eth.provider,
config: {
defaultChain: 'rinkeby',
@@ -695,6 +703,7 @@ describe('defaults', () => {
web3Context: eth2 as Web3Context,
});
expect(res.chain).toBe('rinkeby');
+ await closeOpenConnection(eth2);
});
it('defaultHardfork', async () => {
// default
@@ -707,7 +716,7 @@ describe('defaults', () => {
expect(web3Eth.defaultHardfork).toBe('dao');
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
provider: web3Eth.provider,
config: {
defaultHardfork: 'istanbul',
@@ -732,6 +741,7 @@ describe('defaults', () => {
eth2,
);
expect(res.common.hardfork()).toBe('istanbul');
+ await closeOpenConnection(eth2);
});
it('defaultCommon', () => {
// default
@@ -754,13 +764,14 @@ describe('defaults', () => {
expect(web3Eth.defaultCommon).toBe(common);
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
config: {
defaultCommon: common,
},
});
expect(eth2.defaultCommon).toBe(common);
});
+
it('defaultTransactionType', async () => {
// default
expect(web3Eth.defaultTransactionType).toBe('0x2');
@@ -770,15 +781,20 @@ describe('defaults', () => {
});
expect(web3Eth.defaultTransactionType).toBe('0x3');
+ // revert back to default
+ web3Eth.setConfig({
+ defaultTransactionType: '0x2',
+ });
+
// set by create new instance
- eth2 = new Web3Eth({
- provider: clientUrl,
+ const eth = new Web3Eth({
+ provider: web3Eth.provider,
config: {
defaultTransactionType: '0x4444',
},
});
- expect(eth2.defaultTransactionType).toBe('0x4444');
+ expect(eth.defaultTransactionType).toBe('0x4444');
const res = getTransactionType(
{
@@ -791,7 +807,7 @@ describe('defaults', () => {
chainId: '0x1',
gasLimit: '0x5208',
},
- eth2,
+ eth,
);
expect(res).toBe('0x4444');
@@ -812,7 +828,7 @@ describe('defaults', () => {
gasLimit: '0x5208',
maxFeePerGas: '0x32',
},
- eth2,
+ eth,
);
expect(maxFeePerGasOverride).toBe('0x2');
const maxPriorityFeePerGasOverride = getTransactionType(
@@ -827,7 +843,7 @@ describe('defaults', () => {
gasLimit: '0x5208',
maxPriorityFeePerGas: '0x32',
},
- eth2,
+ eth,
);
expect(maxPriorityFeePerGasOverride).toBe('0x2');
const hardforkOverride = getTransactionType(
@@ -842,7 +858,7 @@ describe('defaults', () => {
gasLimit: '0x5208',
hardfork: 'london',
},
- eth2,
+ eth,
);
expect(hardforkOverride).toBe('0x2');
const commonOverride = getTransactionType(
@@ -860,7 +876,7 @@ describe('defaults', () => {
hardfork: 'london',
},
},
- eth2,
+ eth,
);
expect(commonOverride).toBe('0x2');
@@ -884,7 +900,7 @@ describe('defaults', () => {
},
],
},
- eth2,
+ eth,
);
expect(accessListOverride).toBe('0x1');
@@ -900,7 +916,7 @@ describe('defaults', () => {
gasLimit: '0x5208',
hardfork: 'berlin',
},
- eth2,
+ eth,
);
expect(hardforkBerlinOverride).toBe('0x0');
@@ -919,9 +935,10 @@ describe('defaults', () => {
hardfork: 'berlin',
},
},
- eth2,
+ eth,
);
expect(commonBerlinOverride).toBe('0x0');
+ await closeOpenConnection(eth);
});
it('defaultMaxPriorityFeePerGas', async () => {
// default
@@ -933,7 +950,7 @@ describe('defaults', () => {
expect(web3Eth.defaultMaxPriorityFeePerGas).toBe(numberToHex(2100000000));
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
provider: web3Eth.provider,
config: {
defaultMaxPriorityFeePerGas: numberToHex(1200000000),
@@ -976,6 +993,7 @@ describe('defaults', () => {
DEFAULT_RETURN_FORMAT,
);
expect(resOverride?.maxPriorityFeePerGas).toBe(BigInt('4883362083'));
+ await closeOpenConnection(eth2);
});
it('transactionBuilder', async () => {
// default
@@ -992,7 +1010,7 @@ describe('defaults', () => {
expect(web3Eth.transactionBuilder).toBe(newBuilderMock);
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
config: {
transactionBuilder: newBuilderMock,
},
@@ -1027,7 +1045,7 @@ describe('defaults', () => {
expect(web3Eth.transactionTypeParser).toBe(newParserMock);
// set by create new instance
- eth2 = new Web3Eth({
+ const eth2 = new Web3Eth({
config: {
transactionTypeParser: newParserMock,
},
@@ -1049,5 +1067,4 @@ describe('defaults', () => {
);
expect(newParserMock).toHaveBeenCalled();
});
- });
-});
+});
\ No newline at end of file
diff --git a/packages/web3-eth/test/integration/defaults.transactionBlockTimeout.test.ts b/packages/web3-eth/test/integration/defaults.transactionBlockTimeout.test.ts
index fe679bb0dbe..ba7fd5f15e0 100644
--- a/packages/web3-eth/test/integration/defaults.transactionBlockTimeout.test.ts
+++ b/packages/web3-eth/test/integration/defaults.transactionBlockTimeout.test.ts
@@ -28,12 +28,12 @@ import {
getSystemTestProvider,
isSocket,
itIf,
- waitForOpenConnection,
createLocalAccount,
sendFewSampleTxs,
getSystemTestBackend,
describeIf,
BACKEND
+
} from '../fixtures/system_test_utils';
const MAX_32_SIGNED_INTEGER = 2147483647;
@@ -45,28 +45,72 @@ describeIf(getSystemTestBackend() !== BACKEND.HARDHAT)('defaults', () => {
let clientUrl: string | SupportedProviders;
let account1: Web3Account;
let account2: Web3Account;
+ let transactionBlockTimeout: number;
+ let transactionSendTimeout: number;
+ let transactionPollingTimeout: number;
+ let blockHeaderTimeout: number;
beforeEach(() => {
clientUrl = getSystemTestProvider();
web3 = new Web3(clientUrl);
+ transactionBlockTimeout = web3.eth.transactionBlockTimeout;
+ transactionSendTimeout = web3.eth.transactionSendTimeout;
+ transactionPollingTimeout = web3.eth.transactionPollingTimeout;
+ blockHeaderTimeout = web3.eth.blockHeaderTimeout;
+ });
+
+ afterEach(async () => {
+ web3.eth.transactionBlockTimeout = transactionBlockTimeout;
+ web3.eth.transactionSendTimeout = transactionSendTimeout ;
+ web3.eth.transactionPollingTimeout = transactionPollingTimeout;
+ web3.eth.blockHeaderTimeout = blockHeaderTimeout;
+ await closeOpenConnection(web3);
+ });
+
+ test('should fail if transaction was not mined within `transactionBlockTimeout` blocks', async () => {
+ account1 = await createLocalAccount(web3);
+ account2 = await createLocalAccount(web3);
+
+ const sentTx: Web3PromiEvent<
+ TransactionReceipt,
+ SendTransactionEvents
+ > = web3.eth.sendTransaction({
+ from: account1.address,
+ to: account2.address,
+ gas,
+ value: '0x1',
+ // Give a high nonce so the transaction stuck forever.
+ // However, make this random to be able to run the test many times without receiving an error that indicate submitting the same transaction twice.
+ nonce: Number.MAX_SAFE_INTEGER,
+ });
+
+ // Some providers (mostly used for development) will make blocks only when there are new transactions
+ // So, send 2 transactions, one after another, because in this test `transactionBlockTimeout = 2`.
+ // eslint-disable-next-line no-void
+ await sendFewSampleTxs(2);
+
// Increase other timeouts so only `transactionBlockTimeout` would be reached
web3.eth.transactionSendTimeout = MAX_32_SIGNED_INTEGER;
web3.eth.transactionPollingTimeout = MAX_32_SIGNED_INTEGER;
web3.eth.blockHeaderTimeout = MAX_32_SIGNED_INTEGER / 1000;
- });
+ web3.eth.transactionBlockTimeout = 2;
+
+ await expect(sentTx).rejects.toThrow(/was not mined within [0-9]+ blocks/);
+
+ await expect(sentTx).rejects.toThrow(TransactionBlockTimeoutError);
- afterEach(async () => {
- web3.eth.transactionBlockTimeout = 50;
- await closeOpenConnection(web3.eth);
});
- describe('defaults', () => {
- it('should fail if transaction was not mined within `transactionBlockTimeout` blocks', async () => {
+ // The code of this test case is identical to the pervious one except for `eth.enableExperimentalFeatures = true`
+ // TODO: And this test case will be removed once https://github.com/web3/web3.js/issues/5521 is implemented.
+ itIf(isSocket)(
+ 'should fail if transaction was not mined within `transactionBlockTimeout` blocks - when subscription is used',
+ async () => {
account1 = await createLocalAccount(web3);
account2 = await createLocalAccount(web3);
- // Setting a high `nonce` when sending a transaction, to cause the RPC call to stuck at the Node
+ // Setting a high `nonce` when sending a transaction, to cause the RPC call to stuck at the Node
const sentTx: Web3PromiEvent<
TransactionReceipt,
SendTransactionEvents
@@ -75,6 +119,7 @@ describeIf(getSystemTestBackend() !== BACKEND.HARDHAT)('defaults', () => {
to: account2.address,
gas,
value: '0x1',
+ type: '0x1',
// Give a high nonce so the transaction stuck forever.
// However, make this random to be able to run the test many times without receiving an error that indicate submitting the same transaction twice.
nonce: Number.MAX_SAFE_INTEGER,
@@ -82,58 +127,19 @@ describeIf(getSystemTestBackend() !== BACKEND.HARDHAT)('defaults', () => {
// Some providers (mostly used for development) will make blocks only when there are new transactions
// So, send 2 transactions, one after another, because in this test `transactionBlockTimeout = 2`.
- // eslint-disable-next-line no-void
+ // eslint-disable-next-line no-void, @typescript-eslint/no-unsafe-call
await sendFewSampleTxs(2);
-
+
web3.eth.transactionBlockTimeout = 2;
+ // using subscription to get the new blocks and fire `TransactionBlockTimeoutError` is currently supported only
+ // with `enableExperimentalFeatures.useSubscriptionWhenCheckingBlockTimeout` equal true.
+ web3.eth.enableExperimentalFeatures.useSubscriptionWhenCheckingBlockTimeout = true;
+
await expect(sentTx).rejects.toThrow(/was not mined within [0-9]+ blocks/);
await expect(sentTx).rejects.toThrow(TransactionBlockTimeoutError);
- await closeOpenConnection(web3.eth);
- });
-
- // The code of this test case is identical to the pervious one except for `eth.enableExperimentalFeatures = true`
- // TODO: And this test case will be removed once https://github.com/web3/web3.js/issues/5521 is implemented.
- itIf(isSocket)(
- 'should fail if transaction was not mined within `transactionBlockTimeout` blocks - when subscription is used',
- async () => {
- account1 = await createLocalAccount(web3);
- account2 = await createLocalAccount(web3);
- await waitForOpenConnection(web3.eth);
- // using subscription to get the new blocks and fire `TransactionBlockTimeoutError` is currently supported only
- // with `enableExperimentalFeatures.useSubscriptionWhenCheckingBlockTimeout` equal true.
- web3.eth.enableExperimentalFeatures.useSubscriptionWhenCheckingBlockTimeout = true;
-
- // Setting a high `nonce` when sending a transaction, to cause the RPC call to stuck at the Node
- const sentTx: Web3PromiEvent<
- TransactionReceipt,
- SendTransactionEvents
- > = web3.eth.sendTransaction({
- from: account1.address,
- to: account2.address,
- gas,
- value: '0x1',
- type: '0x1',
- // Give a high nonce so the transaction stuck forever.
- // However, make this random to be able to run the test many times without receiving an error that indicate submitting the same transaction twice.
- nonce: Number.MAX_SAFE_INTEGER,
- });
-
- // Some providers (mostly used for development) will make blocks only when there are new transactions
- // So, send 2 transactions, one after another, because in this test `transactionBlockTimeout = 2`.
- // eslint-disable-next-line no-void, @typescript-eslint/no-unsafe-call
- void sendFewSampleTxs(2);
-
- web3.eth.transactionBlockTimeout = 2;
-
- await expect(sentTx).rejects.toThrow(/was not mined within [0-9]+ blocks/);
-
- await expect(sentTx).rejects.toThrow(TransactionBlockTimeoutError);
-
- await closeOpenConnection(web3.eth);
- },
- );
- });
+ },
+ );
});
diff --git a/packages/web3-eth/test/integration/get_revert_reason.test.ts b/packages/web3-eth/test/integration/get_revert_reason.test.ts
index 5318b06400c..4180742a21b 100644
--- a/packages/web3-eth/test/integration/get_revert_reason.test.ts
+++ b/packages/web3-eth/test/integration/get_revert_reason.test.ts
@@ -26,7 +26,8 @@ import {
createTempAccount,
getSystemTestBackend,
getSystemTestProvider,
- BACKEND
+ BACKEND,
+ closeOpenConnection
} from '../fixtures/system_test_utils';
describe('Web3Eth.getRevertReason', () => {
@@ -49,6 +50,10 @@ describe('Web3Eth.getRevertReason', () => {
.contractAddress as Address;
});
+ afterAll(async () => {
+ await closeOpenConnection(web3Eth);
+ });
+
it('should return reason for a contract call', async () => {
const transaction: TransactionCall = {
from: tempAccount.address,
diff --git a/packages/web3-eth/test/integration/watch_transaction.test.ts b/packages/web3-eth/test/integration/watch_transaction.test.ts
index 4aa607c8fdd..733b64a089b 100644
--- a/packages/web3-eth/test/integration/watch_transaction.test.ts
+++ b/packages/web3-eth/test/integration/watch_transaction.test.ts
@@ -25,11 +25,11 @@ import {
describeIf,
closeOpenConnection,
isSocket,
- waitForOpenConnection,
createLocalAccount,
isIpc,
sendFewSampleTxs,
createAccount,
+ waitForCondition,
} from '../fixtures/system_test_utils';
const waitConfirmations = 2;
@@ -46,7 +46,6 @@ describeIf(isSocket)('watch subscription transaction', () => {
web3 = new Web3(clientUrl);
account1 = await createLocalAccount(web3);
account2 = createAccount();
- await waitForOpenConnection(web3.eth);
});
describe('wait for confirmation subscription', () => {
it('subscription to heads', async () => {
@@ -83,10 +82,18 @@ describeIf(isSocket)('watch subscription transaction', () => {
}
});
});
+
await receiptPromise;
await sendFewSampleTxs(isIpc ? 2 * waitConfirmations : waitConfirmations);
- await confirmationPromise;
- await closeOpenConnection(web3.eth);
+
+ const resourcePromise = waitForCondition(
+ () => shouldBe >= waitConfirmations,
+ async () => {
+ sentTx.removeAllListeners();
+ await closeOpenConnection(web3);}
+ );
+
+ await Promise.all([confirmationPromise,resourcePromise]);
});
});
});
diff --git a/packages/web3-eth/test/integration/web3_eth/send_transaction.test.ts b/packages/web3-eth/test/integration/web3_eth/send_transaction.test.ts
index 9b0eda360dc..b16479d886b 100644
--- a/packages/web3-eth/test/integration/web3_eth/send_transaction.test.ts
+++ b/packages/web3-eth/test/integration/web3_eth/send_transaction.test.ts
@@ -99,6 +99,8 @@ describe('Web3Eth.sendTransaction', () => {
to: '0x0000000000000000000000000000000000000000',
value: BigInt(1),
});
+
+ await closeOpenConnection(web3EthWithWallet);
});
it('should make a simple value transfer - with local wallet indexed receiver', async () => {
@@ -130,6 +132,8 @@ describe('Web3Eth.sendTransaction', () => {
to: wallet.get(0)?.address.toLowerCase(),
value: BigInt(1),
});
+
+ await closeOpenConnection(web3EthWithWallet);
});
it('should make a simple value transfer - with local wallet indexed sender and receiver', async () => {
@@ -165,6 +169,8 @@ describe('Web3Eth.sendTransaction', () => {
to: wallet.get(1)?.address.toLowerCase(),
value: BigInt(1),
});
+
+ await closeOpenConnection(web3EthWithWallet);
});
it('should make a transaction with no value transfer', async () => {
const transaction: Transaction = {
diff --git a/scripts/system_tests_utils.ts b/scripts/system_tests_utils.ts
index 48ea2129c06..11f9bcef717 100644
--- a/scripts/system_tests_utils.ts
+++ b/scripts/system_tests_utils.ts
@@ -50,16 +50,16 @@ import {
Web3EthExecutionAPI,
FMT_NUMBER,
FMT_BYTES,
+ TransactionReceipt,
} from 'web3-types';
// eslint-disable-next-line import/no-extraneous-dependencies
import { Personal } from 'web3-eth-personal';
// eslint-disable-next-line import/no-extraneous-dependencies
-import Web3 from 'web3';
+import {Web3, WebSocketProvider } from 'web3';
// eslint-disable-next-line import/no-extraneous-dependencies
import { NonPayableMethodObject } from 'web3-eth-contract';
-// eslint-disable-next-line import/no-extraneous-dependencies
-import HttpProvider from 'web3-providers-http';
+
// eslint-disable-next-line import/no-extraneous-dependencies
import { IpcProvider } from 'web3-providers-ipc';
import accountsString from './accounts.json';
@@ -83,13 +83,14 @@ export const BACKEND = {
MAINNET: 'mainnet',
};
-export const getSystemTestProviderUrl = (): string =>
+export const getSystemTestProviderUrl = (): string =>
getEnvVar('WEB3_SYSTEM_TEST_PROVIDER') ?? DEFAULT_SYSTEM_PROVIDER;
export const getSystemTestProvider = ():
| string
| SupportedProviders => {
const url = getSystemTestProviderUrl();
+
if (url.includes('ipc')) {
return new IpcProvider(url);
}
@@ -155,37 +156,21 @@ export const waitForOpenConnection = async (
export const closeOpenConnection = async (web3Context: Web3Context) => {
if (
- !isSocket ||
- web3Context?.provider instanceof HttpProvider ||
- (web3Context?.provider?.supportsSubscriptions &&
- !web3Context.provider?.supportsSubscriptions())
- ) {
- return;
- }
- // make sure we try to close the connection after it is established
- if (
- web3Context?.provider &&
- (web3Context.provider as unknown as Web3BaseProvider).getStatus() === 'connecting'
- ) {
- await waitForOpenConnection(web3Context);
- }
- // If an error happened during closing, that is acceptable at tests, just print a 'warn'.
- if (web3Context?.provider) {
- (web3Context.provider as unknown as Web3BaseProvider).on('error', (err: any) => {
- console.warn('error while trying to close the connection', err);
- });
- }
- // Wait a bit to ensure the connection does not have a pending data that
- // could cause an error if written after closing the connection.
- await new Promise(resolve => {
- setTimeout(resolve, 500);
- });
- if (
- web3Context?.provider &&
+ web3Context?.provider && (
+ web3Context?.provider instanceof WebSocketProvider ||
+ web3Context?.provider instanceof IpcProvider
+
+ ) &&
'disconnect' in (web3Context.provider as unknown as Web3BaseProvider)
) {
- (web3Context.provider as unknown as Web3BaseProvider).disconnect(1000, '');
- }
+
+ (web3Context.provider as unknown as Web3BaseProvider).reset();
+ (web3Context.provider as unknown as Web3BaseProvider).disconnect();
+
+ await new Promise(resolve => {
+ setTimeout(resolve, 1000);
+ });
+ }
};
export const createAccountProvider = (context: Web3Context) => {
@@ -241,11 +226,16 @@ export const createAccountProvider = (context: Web3Context) =>
export const refillAccount = async (from: string, to: string, value: string | number) => {
const web3Eth = new Web3Eth(DEFAULT_SYSTEM_PROVIDER);
- await web3Eth.sendTransaction({
+ const receipt = await web3Eth.sendTransaction({
from,
to,
value,
});
+
+ if(receipt.status !== BigInt(1))
+ throw new Error("refillAccount failed");
+
+ await closeOpenConnection(web3Eth);
};
let mainAcc: string;
@@ -256,6 +246,7 @@ export const createNewAccount = async (config?: {
password?: string;
doNotImport?: boolean;
}): Promise<{ address: string; privateKey: string }> => {
+
const acc = config?.privateKey ? privateKeyToAccount(config?.privateKey) : _createAccount();
const clientUrl = DEFAULT_SYSTEM_PROVIDER;
@@ -267,6 +258,7 @@ export const createNewAccount = async (config?: {
await web3.hardhat.impersonateAccount(acc.address);
// await impersonateAccount(acc.address);
await web3.hardhat.setBalance(acc.address, web3.utils.toHex('100000000'));
+ await closeOpenConnection(web3);
} else {
const web3Personal = new Personal(clientUrl);
if (!config?.doNotImport) {
@@ -279,6 +271,7 @@ export const createNewAccount = async (config?: {
}
await web3Personal.unlockAccount(acc.address, config.password ?? '123456', 100000000);
+ await closeOpenConnection(web3Personal);
}
}
@@ -288,17 +281,21 @@ export const createNewAccount = async (config?: {
const web3 = new Web3(url);
web3.registerPlugin(new HardhatPlugin());
await web3.hardhat.setBalance(acc.address, web3.utils.toHex('100000000'));
+ await closeOpenConnection(web3);
} else {
const web3Personal = new Personal(clientUrl);
if (!mainAcc) {
[mainAcc] = await web3Personal.getAccounts();
}
await refillAccount(mainAcc, acc.address, '100000000000000000');
+ await closeOpenConnection(web3Personal);
}
}
return { address: acc.address.toLowerCase(), privateKey: acc.privateKey };
};
+
+
let tempAccountList: { address: string; privateKey: string }[] = [];
const walletsOnWorker = 20;
@@ -485,16 +482,21 @@ export const sendFewSampleTxs = async (cnt = 1) => {
const web3 = new Web3(DEFAULT_SYSTEM_PROVIDER);
const fromAcc = await createLocalAccount(web3);
const toAcc = createAccount();
- const res = [];
+ const res: TransactionReceipt[]= [];
for (let i = 0; i < cnt; i += 1) {
+ // eslint-disable-next-line no-await-in-loop
+ const receipt = await web3.eth.sendTransaction({
+ to: toAcc.address,
+ value: '0x1',
+ from: fromAcc.address,
+ gas: '300000',
+ });
+
+ if(receipt.status !== BigInt(1))
+ throw new Error("sendFewSampleTxs failed ");
+
res.push(
- // eslint-disable-next-line no-await-in-loop
- await web3.eth.sendTransaction({
- to: toAcc.address,
- value: '0x1',
- from: fromAcc.address,
- gas: '300000',
- }),
+ receipt
);
}
await closeOpenConnection(web3);
@@ -516,3 +518,34 @@ export const mapFormatToType: { [key: string]: string } = {
[FMT_BYTES.HEX]: 'string',
[FMT_BYTES.UINT8ARRAY]: 'object',
};
+
+export const waitForCondition = async (
+ conditionFunc: () => boolean,
+ logicFunc: () => Promise | void,
+ maxIterations = 10, // 10 times
+ duration = 8000, // check after each 8 seconds
+): Promise => {
+ return new Promise((resolve, reject) => {
+ let iterations = 0;
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
+ const interval = setInterval(async () => {
+ try {
+ if (iterations > 0 && conditionFunc()) { // wait duration before first check
+ clearInterval(interval);
+ await logicFunc();
+ resolve();
+ } else {
+ iterations += 1;
+ if (iterations >= maxIterations) {
+ clearInterval(interval);
+ await logicFunc();
+ reject(new Error('Condition not met after 10 iterations.'));
+ }
+ }
+ } catch (error) {
+ clearInterval(interval);
+ reject(error);
+ }
+ }, duration);
+ });
+};
\ No newline at end of file
diff --git a/templates/cypress.config.js b/templates/cypress.config.js
index 95874902d93..977e51c90db 100644
--- a/templates/cypress.config.js
+++ b/templates/cypress.config.js
@@ -25,6 +25,7 @@ const config = {
},
specPattern: 'test/integration/**/**/*.test.ts',
excludeSpecPattern: ['**/contract_defaults_extra.test.ts'],
+ defaultCommandTimeout: 120000
},
};