diff --git a/packages/web3-eth-accounts/src/index.js b/packages/web3-eth-accounts/src/index.js index 43f87bc5672..710b27983ba 100644 --- a/packages/web3-eth-accounts/src/index.js +++ b/packages/web3-eth-accounts/src/index.js @@ -297,14 +297,24 @@ function _validateTransactionForSigning(tx) { ); } - if (!tx.gas && !tx.gasLimit) { + if ( + (!tx.gas && !tx.gasLimit) && + (!tx.maxPriorityFeePerGas && !tx.maxFeePerGas) + ) { return new Error('"gas" is missing'); } - if (tx.nonce < 0 || - tx.gas < 0 || - tx.gasPrice < 0 || - tx.chainId < 0) { + if (tx.gas && tx.gasPrice) { + if (tx.gas < 0 || tx.gasPrice < 0) { + return new Error('Gas, gasPrice, nonce or chainId is lower than 0'); + } + } else { + if (tx.maxPriorityFeePerGas < 0 || tx.maxFeePerGas < 0) { + return new Error('maxPriorityFeePerGas or maxFeePerGas is lower than 0'); + } + } + + if (tx.nonce < 0 || tx.chainId < 0) { return new Error('Gas, gasPrice, nonce or chainId is lower than 0'); } diff --git a/scripts/e2e.geth.automine.sh b/scripts/e2e.geth.automine.sh index 3612ef682db..0282d15d4e7 100755 --- a/scripts/e2e.geth.automine.sh +++ b/scripts/e2e.geth.automine.sh @@ -24,7 +24,7 @@ echo " " # Launch client w/ two unlocked accounts. # + accounts[0] default geth unlocked bal = ~infinity # + accounts[1] unlocked, signing password = 'left-hand-of-darkness' -geth-dev-assistant --period 2 --accounts 1 --tag 'v1.10.3' +geth-dev-assistant --period 2 --accounts 1 --tag 'stable' # Test GETH_AUTOMINE=true nyc --no-clean --silent _mocha -- \ diff --git a/scripts/js/ens.js b/scripts/js/ens.js index e9c7e4a965c..8fad5d4e446 100644 --- a/scripts/js/ens.js +++ b/scripts/js/ens.js @@ -12,7 +12,7 @@ async function setupENS(web3) { const options = { bytecode: undefined, - gasPrice: '1', + gasPrice: 1000000000, // Default gasPrice set by Geth gas: 5500000 } diff --git a/test/e2e.contract.deploy.js b/test/e2e.contract.deploy.js index 3301555887b..51dd3868e50 100644 --- a/test/e2e.contract.deploy.js +++ b/test/e2e.contract.deploy.js @@ -19,19 +19,19 @@ describe('contract.deploy [ @E2E ]', function() { var basicOptions = { data: Basic.bytecode, - gasPrice: '1', + gasPrice: 1000000000, // Default gasPrice set by Geth gas: 4000000 }; var revertsOptions = { data: Reverts.bytecode, - gasPrice: '1', + gasPrice: 1000000000, // Default gasPrice set by Geth gas: 4000000 } var noBytecodeOptions = { data: '0x', - gasPrice: '1', + gasPrice: 1000000000, // Default gasPrice set by Geth gas: 4000000 } diff --git a/test/e2e.contract.events.js b/test/e2e.contract.events.js index 2b51a570694..21ff0aecade 100644 --- a/test/e2e.contract.events.js +++ b/test/e2e.contract.events.js @@ -17,7 +17,7 @@ describe('contract.events [ @E2E ]', function() { var basicOptions = { data: Basic.bytecode, - gasPrice: '1', + gasPrice: 1000000000,// Default gasPrice set by Geth gas: 4000000 }; @@ -289,7 +289,7 @@ describe('contract.events [ @E2E ]', function() { let contract; const options = { - gasPrice: '1', + gasPrice: 1000000000,// Default gasPrice set by Geth gas: 4000000 }; @@ -336,7 +336,7 @@ describe('contract.events [ @E2E ]', function() { // and geth instamine's websockets connection is too fragile for the tests in this file. it('backfills missed events when auto-reconnecting', function(){ if(!process.env.GANACHE) return; - this.timeout(10000); + this.timeout(20000); let counter = 0; const acc = accounts[0]; diff --git a/test/e2e.ens.js b/test/e2e.ens.js index 13b3cc4145d..d3c3eae6742 100644 --- a/test/e2e.ens.js +++ b/test/e2e.ens.js @@ -27,7 +27,7 @@ describe('ENS [ @E2E ]', function () { options = { from: account, gas: 4000000, - gasPrice: 1 + gasPrice: 1000000000 // Default gasPrice set by Geth } }); diff --git a/test/e2e.method.call.js b/test/e2e.method.call.js index c9641d13418..4aa67e719cd 100644 --- a/test/e2e.method.call.js +++ b/test/e2e.method.call.js @@ -13,13 +13,13 @@ describe('method.call [ @E2E ]', function () { var basicOptions = { data: Basic.bytecode, - gasPrice: '1', + gasPrice: 1000000000, // Default gasPrice set by Geth gas: 4000000 }; var miscOptions = { data: Misc.bytecode, - gasPrice: '1', + gasPrice: 1000000000, // Default gasPrice set by Geth gas: 4000000 }; diff --git a/test/e2e.method.send.js b/test/e2e.method.send.js index b17fb403484..2af7e727df2 100644 --- a/test/e2e.method.send.js +++ b/test/e2e.method.send.js @@ -12,24 +12,28 @@ describe('method.send [ @E2E ]', function () { var basicOptions = { data: Basic.bytecode, - gasPrice: '1', + gasPrice: 1000000000, // Default gasPrice set by Geth gas: 4000000 }; describe('http', function () { before(async function () { web3 = new Web3('http://localhost:8545'); - accounts = await web3.eth.getAccounts(); + accounts = await web3.eth.getAccounts(); basic = new web3.eth.Contract(Basic.abi, basicOptions); - instance = await basic.deploy().send({from: accounts[0]}); + + var nonceVal = await web3.eth.getTransactionCount(accounts[0]); + + instance = await basic.deploy().send({from: accounts[0], nonce: nonceVal}); }); it('returns a receipt', async function () { + var nonceVal = await web3.eth.getTransactionCount(accounts[0]); var receipt = await instance .methods .setValue('1') - .send({from: accounts[0]}); + .send({from: accounts[0], nonceVal}); assert(receipt.status === true); assert(web3.utils.isHexStrict(receipt.transactionHash)); @@ -37,10 +41,11 @@ describe('method.send [ @E2E ]', function () { it('errors on OOG', async function () { try { + var nonceVal = await web3.eth.getTransactionCount(accounts[0]); await instance .methods .setValue('1') - .send({from: accounts[0], gas: 100}); + .send({from: accounts[0], gas: 100, nonce: nonceVal}); assert.fail(); @@ -114,16 +119,19 @@ describe('method.send [ @E2E ]', function () { web3 = new Web3('ws://localhost:' + port); accounts = await web3.eth.getAccounts(); - + basic = new web3.eth.Contract(Basic.abi, basicOptions); - instance = await basic.deploy().send({from: accounts[0]}); + + var nonceVal = await web3.eth.getTransactionCount(accounts[0]); + instance = await basic.deploy().send({from: accounts[0], nonce: nonceVal }); }) it('returns a receipt', async function () { + var nonceVal = await web3.eth.getTransactionCount(accounts[0]); var receipt = await instance .methods .setValue('1') - .send({from: accounts[0]}); + .send({from: accounts[0], nonce: nonceVal}); assert(receipt.status === true); assert(web3.utils.isHexStrict(receipt.transactionHash)); @@ -131,10 +139,11 @@ describe('method.send [ @E2E ]', function () { it('errors on OOG', async function () { try { + var nonceVal = await web3.eth.getTransactionCount(accounts[0]); await instance .methods .setValue('1') - .send({from: accounts[0], gas: 100}); + .send({from: accounts[0], gas: 100, nonce: nonceVal}); assert.fail(); diff --git a/test/e2e.method.signing.js b/test/e2e.method.signing.js index 2646fa04195..4bfa2649812 100644 --- a/test/e2e.method.signing.js +++ b/test/e2e.method.signing.js @@ -12,7 +12,7 @@ describe('transaction and message signing [ @E2E ]', function() { const basicOptions = { data: Basic.bytecode, - gasPrice: '1', + gasPrice: 1000000000, // Default gasPrice set by Geth gas: 4000000 }; @@ -48,7 +48,7 @@ describe('transaction and message signing [ @E2E ]', function() { from: source, value: web3.utils.toHex(web3.utils.toWei('0.1', 'ether')), gasLimit: web3.utils.toHex(21000), - gasPrice: web3.utils.toHex(web3.utils.toWei('10', 'gwei')) + gasPrice: web3.utils.toHex('1000000000') }; const signed = await web3.eth.signTransaction(rawTx); @@ -58,6 +58,9 @@ describe('transaction and message signing [ @E2E ]', function() { }); it('sendSignedTransaction (accounts.signTransaction with signing options)', async function(){ + // ganache does not support eth_signTransaction + if (process.env.GANACHE || global.window ) return + const source = wallet[0].address; const destination = wallet[1].address; @@ -92,6 +95,9 @@ describe('transaction and message signing [ @E2E ]', function() { }); it('sendSignedTransaction (accounts.signTransaction / without signing options)', async function(){ + // ganache does not support eth_signTransaction + if (process.env.GANACHE || global.window ) return + const source = wallet[0].address; const destination = wallet[1].address; @@ -112,6 +118,12 @@ describe('transaction and message signing [ @E2E ]', function() { }); it('accounts.signTransaction, (with callback, nonce not specified)', function(done){ + // ganache does not support eth_signTransaction + if (process.env.GANACHE || global.window ) { + done(); + return + } + const source = wallet[0].address; const destination = wallet[1].address; @@ -129,7 +141,132 @@ describe('transaction and message signing [ @E2E ]', function() { }); }); + it('accounts.signTransaction, (EIP-2930, accessList specified)', function(done){ + // ganache does not support eth_signTransaction + if (process.env.GANACHE || global.window ) { + done(); + return + } + + const source = wallet[0].address; + const destination = wallet[1].address; + + const txObject = { + to: destination, + value: web3.utils.toHex(web3.utils.toWei('0.1', 'ether')), + gas: web3.utils.toHex(21000), + accessList: [] + }; + + web3.eth.accounts.signTransaction(txObject, wallet[0].privateKey, async function(err, signed){ + const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction); + assert(receipt.status === true); + done(); + }); + }); + + it('accounts.signTransaction, (EIP-2930, type 1 specified)', function(done){ + // ganache does not support eth_signTransaction + if (process.env.GANACHE || global.window ) { + done(); + return + } + + const source = wallet[0].address; + const destination = wallet[1].address; + + const txObject = { + to: destination, + value: web3.utils.toHex(web3.utils.toWei('0.1', 'ether')), + gas: web3.utils.toHex(21000), + type: 1 + }; + + web3.eth.accounts.signTransaction(txObject, wallet[0].privateKey, async function(err, signed){ + const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction); + assert(receipt.status === true); + done(); + }); + }); + + it('accounts.signTransaction, (EIP-1559, maxFeePerGas and maxPriorityFeePerGas specified)', function(done){ + // ganache does not support eth_signTransaction + if (process.env.GANACHE || global.window ) { + done(); + return + } + + const source = wallet[0].address; + const destination = wallet[1].address; + + const txObject = { + to: destination, + value: web3.utils.toHex(web3.utils.toWei('0.1', 'ether')), + gas: web3.utils.toHex(21000), + maxFeePerGas: '0x59682F00', // 1.5 Gwei + maxPriorityFeePerGas: '0x1DCD6500' // .5 Gwei + }; + + web3.eth.accounts.signTransaction(txObject, wallet[0].privateKey, async function(err, signed){ + const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction); + assert(receipt.status === true); + done(); + }); + }); + + it('accounts.signTransaction, (EIP-1559, type 2 specified)', function(done){ + // ganache does not support eth_signTransaction + if (process.env.GANACHE || global.window ) { + done(); + return + } + + const source = wallet[0].address; + const destination = wallet[1].address; + + const txObject = { + to: destination, + value: web3.utils.toHex(web3.utils.toWei('0.1', 'ether')), + gas: web3.utils.toHex(21000), + type: 2 + }; + + web3.eth.accounts.signTransaction(txObject, wallet[0].privateKey, async function(err, signed){ + const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction); + assert(receipt.status === true); + done(); + }); + }); + + it('accounts.signTransaction, (EIP-1559, maxFeePerGas and accessList specified)', function(done){ + // ganache does not support eth_signTransaction + if (process.env.GANACHE || global.window ) { + done(); + return + } + + const source = wallet[0].address; + const destination = wallet[1].address; + + const txObject = { + to: destination, + value: web3.utils.toHex(web3.utils.toWei('0.1', 'ether')), + gas: web3.utils.toHex(21000), + maxFeePerGas: '0x59682F00', // 1.5 Gwei + accessList: [] + }; + + web3.eth.accounts.signTransaction(txObject, wallet[0].privateKey, async function(err, signed){ + const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction); + assert(receipt.status === true); + done(); + }); + }); + it('accounts.signTransaction errors when common, chain and hardfork all defined', async function(){ + // ganache does not support eth_signTransaction + if (process.env.GANACHE || global.window ) return + const source = wallet[0].address; const destination = wallet[1].address; @@ -155,6 +292,9 @@ describe('transaction and message signing [ @E2E ]', function() { }); it('accounts.signTransaction errors when chain specified without hardfork', async function(){ + // ganache does not support eth_signTransaction + if (process.env.GANACHE || global.window ) return + const source = wallet[0].address; const destination = wallet[1].address; @@ -178,6 +318,9 @@ describe('transaction and message signing [ @E2E ]', function() { }); it('accounts.signTransaction errors when hardfork specified without chain', async function(){ + // ganache does not support eth_signTransaction + if (process.env.GANACHE || global.window ) return + const source = wallet[0].address; const destination = wallet[1].address; @@ -201,6 +344,9 @@ describe('transaction and message signing [ @E2E ]', function() { }); it('accounts.signTransaction errors when tx signing is invalid', async function(){ + // ganache does not support eth_signTransaction + if (process.env.GANACHE || global.window ) return + const source = wallet[0].address; const destination = wallet[1].address; @@ -226,6 +372,9 @@ describe('transaction and message signing [ @E2E ]', function() { }) it('accounts.signTransaction errors when no transaction is passed', async function(){ + // ganache does not support eth_signTransaction + if (process.env.GANACHE || global.window ) return + try { await web3.eth.accounts.signTransaction(undefined, wallet[0].privateKey); assert.fail() @@ -296,7 +445,7 @@ describe('transaction and message signing [ @E2E ]', function() { from: wallet[0], to: instance.options.address, data: data, - gasPrice: '1', + gasPrice: 1000000000, // Default gasPrice set by Geth gas: 4000000 } diff --git a/test/eth.accounts.signTransaction.js b/test/eth.accounts.signTransaction.js index 132c773100d..6d1331d9388 100644 --- a/test/eth.accounts.signTransaction.js +++ b/test/eth.accounts.signTransaction.js @@ -567,6 +567,7 @@ var tests = [ maxPriorityFeePerGas: '0x3B9ACA00', maxFeePerGas: '0xB2D05E00', gas: 27200, + gasLimit: '0x6A40', to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', toIban: 'XE04S1IRT2PR8A8422TPBL9SR6U0HODDCUT', // will be switched to "to" in the test value: "1000000000", @@ -588,19 +589,20 @@ var tests = [ transaction: { chainId: 1, nonce: 0, - gas: 27200, + maxPriorityFeePerGas: '0x3B9ACA00', + maxFeePerGas: '0xB2D05E00', + gasLimit: '0x6A40', to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', toIban: 'XE04S1IRT2PR8A8422TPBL9SR6U0HODDCUT', // will be switched to "to" in the test value: "1000000000", data: "", - common: commonLondon, - accessList: accessList + common: commonLondon }, // signature from eth_signTransaction - rawTransaction: "0x02f8ca0180843b9aca00843b9aca0e826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080f85bf859940000000000000000000000000000000000000101f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000060a780a0e3a2e10c7d3af3407ec2d38c64788d6673926e9b28d6d2e7df3c94cdf0548233a00ad3e5faafaf3a9350ab16c1be0198ce9ff3c6bef0b91e05488d757f07de9557", - oldSignature: "0x02f8ca0180843b9aca00843b9aca0e826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080f85bf859940000000000000000000000000000000000000101f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000060a780a0e3a2e10c7d3af3407ec2d38c64788d6673926e9b28d6d2e7df3c94cdf0548233a00ad3e5faafaf3a9350ab16c1be0198ce9ff3c6bef0b91e05488d757f07de9557", - transactionHash: "0xbc2c9edab3d4e3a795fa402b52d6149e874de15f0cc6c0858eb34e1fe1ef31fe", - messageHash: "0xa3a2cdc45e9cefb9a614ead90ce65f68bcf8a90dbe0ccbd84c1b62403bd05346" + rawTransaction: "0x02f86e0180843b9aca0084b2d05e00826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080c080a0d1290a118d51918c1ca17e3af0267c45efcd745cf42e78eabc444c424d6bcf37a003c81e1fda169575023a94200ee034128747f91020e704abaee30dbcfc785c36", + oldSignature: "0x02f86e0180843b9aca0084b2d05e00826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080c080a0d1290a118d51918c1ca17e3af0267c45efcd745cf42e78eabc444c424d6bcf37a003c81e1fda169575023a94200ee034128747f91020e704abaee30dbcfc785c36", + transactionHash: "0x82c19b39a6b7eaa0492863a8b236fad5018f267b4977c270ddd5228c4cbda60e", + messageHash: "0xe3beea0918f445c21eb2f42e3cbc3c5d54321ec642f47d12c473b2765df97f2b" }, { // test #26 @@ -611,6 +613,7 @@ var tests = [ chainId: 1, nonce: 0, gas: 27200, + gasLimit: '0x6A40', to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', toIban: 'XE04S1IRT2PR8A8422TPBL9SR6U0HODDCUT', // will be switched to "to" in the test value: "1000000000", @@ -623,6 +626,29 @@ var tests = [ transactionHash: "0x488a813f2286f7c015947aa13133bdae49ec75ae1c8f5eba80034d71a038dca8", messageHash: "0xcd6d6dee80ecc38f1b22f2d128bf6043dc41079fc913183a8995b5b3e187df61" }, + { + // test #27 + address: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + iban: 'XE0556YCRTEZ9JALZBSCXOK4UJ5F3HN03DV', + privateKey: '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + transaction: { + chainId: 1, + nonce: 0, + gas: 27200, + gasLimit: '0x6A40', + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + toIban: 'XE04S1IRT2PR8A8422TPBL9SR6U0HODDCUT', // will be switched to "to" in the test + value: "1000000000", + data: "", + common: commonLondon, + accessList: accessList + }, + // signature from eth_signTransaction + rawTransaction: "0x02f8ca0180843b9aca00843b9aca0e826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080f85bf859940000000000000000000000000000000000000101f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000060a780a0e3a2e10c7d3af3407ec2d38c64788d6673926e9b28d6d2e7df3c94cdf0548233a00ad3e5faafaf3a9350ab16c1be0198ce9ff3c6bef0b91e05488d757f07de9557", + oldSignature: "0x02f8ca0180843b9aca00843b9aca0e826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080f85bf859940000000000000000000000000000000000000101f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000060a780a0e3a2e10c7d3af3407ec2d38c64788d6673926e9b28d6d2e7df3c94cdf0548233a00ad3e5faafaf3a9350ab16c1be0198ce9ff3c6bef0b91e05488d757f07de9557", + transactionHash: "0xbc2c9edab3d4e3a795fa402b52d6149e874de15f0cc6c0858eb34e1fe1ef31fe", + messageHash: "0xa3a2cdc45e9cefb9a614ead90ce65f68bcf8a90dbe0ccbd84c1b62403bd05346" + }, ]; describe("eth", function () { @@ -688,7 +714,21 @@ describe("eth", function () { }); it("signTransaction using the iban as \"to\" must compare to eth_signTransaction", function(done) { - var ethAccounts = new Accounts(); + var provider = new FakeHttpProvider(); + var web3 = new Web3(provider); + + provider.injectResult( + test.transaction.common.hardfork === 'london' ? + postEip1559Block: + preEip1559Block + ); + provider.injectValidation(function (payload) { + assert.equal(payload.jsonrpc, '2.0'); + assert.equal(payload.method, 'eth_getBlockByNumber'); + assert.deepEqual(payload.params, ['latest', false]); + }); + + var ethAccounts = new Accounts(web3); var testAccount = ethAccounts.privateKeyToAccount(test.privateKey); assert.equal(testAccount.address, test.address); @@ -933,7 +973,21 @@ describe("eth", function () { }); it("recoverTransaction, must recover signature", function(done) { - var ethAccounts = new Accounts(); + var provider = new FakeHttpProvider(); + var web3 = new Web3(provider); + + provider.injectResult( + test.transaction.common.hardfork === 'london' ? + postEip1559Block: + preEip1559Block + ); + provider.injectValidation(function (payload) { + assert.equal(payload.jsonrpc, '2.0'); + assert.equal(payload.method, 'eth_getBlockByNumber'); + assert.deepEqual(payload.params, ['latest', false]); + }); + + var ethAccounts = new Accounts(web3); var testAccount = ethAccounts.privateKeyToAccount(test.privateKey); assert.equal(testAccount.address, test.address); diff --git a/test/helpers/test.utils.js b/test/helpers/test.utils.js index 67922e03aff..f8e99d8bf6e 100644 --- a/test/helpers/test.utils.js +++ b/test/helpers/test.utils.js @@ -25,7 +25,7 @@ var mine = async function(web3, account) { await web3.eth.sendTransaction({ from: account, to: account, - gasPrice: '1', + gasPrice: 1000000000, // Default gasPrice set by Geth gas: 4000000, value: web3.utils.toWei('0', 'ether'), });