Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Merge conflicts
  • Loading branch information
spacesailor24 committed Aug 26, 2021
commit 9c54634d76b55d0f120a5d09cb5ac38f4a39e030
5,598 changes: 5,561 additions & 37 deletions packages/web3-core-method/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/web3-core-method/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
},
"main": "lib/index.js",
"dependencies": {
"@ethereumjs/common": "^2.4.0",
"@ethersproject/transactions": "^5.0.0-beta.135",
"web3-core-helpers": "1.5.0",
"web3-core-promievent": "1.5.0",
Expand Down
145 changes: 131 additions & 14 deletions packages/web3-core-method/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var formatters = require('web3-core-helpers').formatters;
var utils = require('web3-utils');
var promiEvent = require('web3-core-promievent');
var Subscriptions = require('web3-core-subscriptions').subscriptions;
var HardForks = require('@ethereumjs/common').Hardfork;

var EthersTransactionUtils = require('@ethersproject/transactions');

Expand Down Expand Up @@ -770,18 +771,29 @@ Method.prototype.buildCall = function () {
};

// Send the actual transaction
if (isSendTx && !!payload.params[0] && typeof payload.params[0] === 'object' && typeof payload.params[0].gasPrice === 'undefined') {

var getGasPrice = (new Method({
name: 'getGasPrice',
call: 'eth_gasPrice',
params: 0
})).createFunction(method.requestManager);

getGasPrice(function (err, gasPrice) {

if (gasPrice) {
payload.params[0].gasPrice = gasPrice;
if (isSendTx
&& !!payload.params[0]
&& typeof payload.params[0] === 'object'
&& (
typeof payload.params[0].gasPrice === 'undefined'
&& (
typeof payload.params[0].maxPriorityFeePerGas === 'undefined'
|| typeof payload.params[0].maxFeePerGas === 'undefined'
)
)
) {
if (typeof payload.params[0].type === 'undefined')
payload.params[0].type = _handleTxType(payload.params[0]);

_handleTxPricing(method, payload.params[0]).then(txPricing => {
if (txPricing.gasPrice !== undefined) {
payload.params[0].gasPrice = txPricing.gasPrice;
} else if (
txPricing.maxPriorityFeePerGas !== undefined
&& txPricing.maxFeePerGas !== undefined
) {
payload.params[0].maxPriorityFeePerGas = txPricing.maxPriorityFeePerGas;
payload.params[0].maxFeePerGas = txPricing.maxFeePerGas;
}

if (isSendTx) {
Expand All @@ -791,8 +803,7 @@ Method.prototype.buildCall = function () {
}

sendRequest(payload, method);
});

})
} else {
if (isSendTx) {
setTimeout(() => {
Expand All @@ -819,6 +830,112 @@ Method.prototype.buildCall = function () {
return send;
};

function _handleTxType(tx) {
// Taken from https://github.com/ethers-io/ethers.js/blob/2a7ce0e72a1e0c9469e10392b0329e75e341cf18/packages/abstract-signer/src.ts/index.ts#L215
const hasEip1559 = (tx.maxFeePerGas !== undefined || tx.maxPriorityFeePerGas !== undefined);

let txType;

if (tx.type !== undefined) {
txType = utils.toHex(tx.type)
} else if (tx.type === undefined && hasEip1559) {
txType = '0x2'
} else {
txType = '0x0'
}

if (tx.gasPrice !== undefined && (txType === '0x2' || hasEip1559))
throw Error("eip-1559 transactions don't support gasPrice");
if ((txType === '0x1' || txType === '0x0') && hasEip1559)
throw Error("pre-eip-1559 transaction don't support maxFeePerGas/maxPriorityFeePerGas");

if (
hasEip1559 ||
(
(tx.common && tx.common.hardfork && tx.common.hardfork.toLowerCase() === HardForks.London) ||
(tx.hardfork && tx.hardfork.toLowerCase() === HardForks.London)
)
) {
txType = '0x2';
} else if (
tx.accessList ||
(
(tx.common && tx.common.hardfork && tx.common.hardfork.toLowerCase() === HardForks.Berlin) ||
(tx.hardfork && tx.hardfork.toLowerCase() === HardForks.Berlin)
)
) {
txType = '0x1';
}

return txType
}

function _handleTxPricing(method, tx) {
return new Promise((resolve, reject) => {
try {
var getBlockByNumber = (new Method({
name: 'getBlockByNumber',
call: 'eth_getBlockByNumber',
params: 2,
inputFormatter: [function(blockNumber) {
return blockNumber ? utils.toHex(blockNumber) : 'latest'
}, function() {
return false
}]
})).createFunction(method.requestManager);
var getGasPrice = (new Method({
name: 'getGasPrice',
call: 'eth_gasPrice',
params: 0
})).createFunction(method.requestManager);

if (tx.type < '0x2' && tx.gasPrice !== undefined) {
// Legacy transaction, return provided gasPrice
resolve({ gasPrice: tx.gasPrice })
} else {
Promise.all([
getBlockByNumber(),
getGasPrice()
]).then(responses => {
const [block, gasPrice] = responses;
if (
(tx.type === '0x2') &&
block && block.baseFeePerGas
) {
// The network supports EIP-1559

// Taken from https://github.com/ethers-io/ethers.js/blob/ba6854bdd5a912fe873d5da494cb5c62c190adde/packages/abstract-provider/src.ts/index.ts#L230
let maxPriorityFeePerGas, maxFeePerGas;

if (tx.gasPrice) {
// Using legacy gasPrice property on an eip-1559 network,
// so use gasPrice as both fee properties
maxPriorityFeePerGas = tx.gasPrice;
maxFeePerGas = tx.gasPrice;
delete tx.gasPrice;
} else {
maxPriorityFeePerGas = tx.maxPriorityFeePerGas || '0x3B9ACA00'; // 1 Gwei
maxFeePerGas = tx.maxFeePerGas ||
utils.toHex(
utils.toBN(block.baseFeePerGas)
.mul(utils.toBN(2))
.add(utils.toBN(maxPriorityFeePerGas))
);
}
resolve({ maxFeePerGas, maxPriorityFeePerGas });
} else {
if (tx.maxPriorityFeePerGas || tx.maxFeePerGas)
throw Error("Network doesn't support eip-1559")
resolve({ gasPrice });
}
})
}
} catch (error) {
reject(error)
}
})
}

/**
* Returns the revert reason string if existing or otherwise false.
*
Expand Down
3 changes: 2 additions & 1 deletion packages/web3-core-method/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./lib"
"outDir": "./lib",
"esModuleInterop": true
},
"include": [
"./src"
Expand Down
31 changes: 30 additions & 1 deletion test/contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -2634,6 +2634,34 @@ var runTests = function(contractFactory) {
var provider = new FakeIpcProvider();
var signature = 'mySend(address,uint256)';

provider.injectResult({
baseFeePerGas: "0x7",
difficulty: "0x6cd6be3a",
extraData: "0x796f75747562652e636f6d2f77617463683f763d6451773477395767586351",
gasLimit: "0x1c9c381",
gasUsed: "0x8dc073",
hash: "0x846880b1158f434884f3637802ed09bac77eafc35b5f03b881ac88ce38a54907",
logsBloom: "0x4020001000000000000000008000010000000000400200000001002140000008000000010000810020000840000204304000081000000b00400010000822200004200020020140000001000882000064000021303200020000400008800000000002202102000084010000090020a8000800002000000010000030300000000000000006001005000040080001010000010040018100004c0050004000000000420000000021000200000010020008100000004000080000000000000040000900080102004002000080210201081014004030200148101000002020108025000018020020102040000204240500010000002200048000401300080088000002",
miner: "0x86864f1edf10eaf105b1bdc6e9aa8232b4c6aa00",
mixHash: "0xa29afb1fa1aea9eeac72ff435a8fc420bbc1fa1be08223eb61f294ee32250bde",
nonce: "0x122af1a5ccd78f3b",
number: "0xa0d600",
parentHash: "0x28f49150e1fe6f245655925b290f59e707d1e5c646dadaa22937169433b30294",
receiptsRoot: "0xc97d4f9980d680053606318a5820261a1dccb556d1056b70f0d48fb384986be5",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: "0x2042",
stateRoot: "0x116981b10423133ade5bd44f03c54cc3c57f4467a1c3d4b0c6d8d33a76c361ad",
timestamp: "0x60dc24ec",
totalDifficulty: "0x78828f2d886cbb",
transactions: [],
transactionsRoot: "0x738f53f745d58169da93ebbd52cc49e0c979d6ca68a6513007b546b19ab78ba4",
uncles: []
});
provider.injectValidation(function (payload) {
assert.equal(payload.method, 'eth_getBlockByNumber');
assert.deepEqual(payload.params, ['latest', false]);
});

provider.injectValidation(function (payload) {
assert.equal(payload.method, 'eth_gasPrice');
assert.deepEqual(payload.params, []);
Expand All @@ -2650,7 +2678,8 @@ var runTests = function(contractFactory) {
'0000000000000000000000000000000000000000000000000000000000000011' ,
to: addressLowercase,
from: addressLowercase,
gasPrice: '0x45656456456456'
gasPrice: '0x45656456456456',
type: '0x0'
}]);

done();
Expand Down
40 changes: 40 additions & 0 deletions test/e2e.method.send.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,26 @@ describe('method.send [ @E2E ]', function () {
assert(web3.utils.isHexStrict(receipt.transactionHash));
});

it('returns a receipt (EIP-1559, maxFeePerGas and maxPriorityFeePerGas specified)', async function () {
// ganache does not support eth_signTransaction
if (process.env.GANACHE || global.window ) return

var nonceVal = await web3.eth.getTransactionCount(accounts[0]);
var receipt = await web3.eth.sendTransaction({
to: accounts[1],
from: accounts[0],
nonce: nonceVal,
value: web3.utils.toHex(web3.utils.toWei('0.1', 'ether')),
gas: web3.utils.toHex(21000),
maxFeePerGas: '0x59682F00', // 1.5 Gwei
maxPriorityFeePerGas: '0x1DCD6500', // .5 Gwei
type: '0x2'
})

assert(receipt.status === true);
assert(web3.utils.isHexStrict(receipt.transactionHash));
});

it('errors on OOG', async function () {
try {
var nonceVal = await web3.eth.getTransactionCount(accounts[0]);
Expand Down Expand Up @@ -137,6 +157,26 @@ describe('method.send [ @E2E ]', function () {
assert(web3.utils.isHexStrict(receipt.transactionHash));
});

it('returns a receipt (EIP-1559, maxFeePerGas and maxPriorityFeePerGas specified)', async function () {
// ganache does not support eth_signTransaction
if (process.env.GANACHE || global.window ) return

var nonceVal = await web3.eth.getTransactionCount(accounts[0]);
var receipt = await web3.eth.sendTransaction({
to: accounts[1],
from: accounts[0],
nonce: nonceVal,
value: web3.utils.toHex(web3.utils.toWei('0.1', 'ether')),
gas: web3.utils.toHex(21000),
maxFeePerGas: '0x59682F00', // 1.5 Gwei
maxPriorityFeePerGas: '0x1DCD6500', // .5 Gwei
type: '0x2'
})

assert(receipt.status === true);
assert(web3.utils.isHexStrict(receipt.transactionHash));
});

it('errors on OOG', async function () {
try {
var nonceVal = await web3.eth.getTransactionCount(accounts[0]);
Expand Down
38 changes: 31 additions & 7 deletions test/eth.sendTransaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,26 @@ var tests = [{
}
}
},
call: 'eth_gasPrice',
formattedArgs: [],
result: '0x1234567',
formattedResult: '0x1234567',

call2: 'eth_'+ method,
formattedArgs2: [{
call: 'eth_getBlockByNumber',
formattedArgs: ['latest', false],

call2: 'eth_gasPrice',
formattedArgs2: [],
result2: '0x1234567',
formattedResult2: '0x1234567',

call3: 'eth_'+ method,
formattedArgs3: [{
from: "0xdbdbdb2cbd23b783741e8d7fcf51e459b497e4a6",
to: "0xdbdbdb2cbd23b783741e8d7fcf51e459b497e4a6",
value: "0x11f71f76bb1",
gasPrice: "0x1234567"
gasPrice: "0x1234567",
type: "0x0"
}],
result2: '0x1234567'
result3: '0x1234567'
},{
args: [{
from: '0XDBDBDB2CBD23B783741E8D7FCF51E459B497E4A6',
Expand Down Expand Up @@ -249,6 +256,15 @@ describe(method, function () {
});
}

if (test.call3) {
provider.injectResult(clone(test.result3));
provider.injectValidation(function (payload) {
assert.equal(payload.jsonrpc, '2.0');
assert.equal(payload.method, test.call3);
assert.deepEqual(payload.params, test.formattedArgs3 || []);
});
}

provider.injectResult(null);
provider.injectValidation(function (payload) {
assert.equal(payload.method, 'eth_getTransactionReceipt');
Expand Down Expand Up @@ -331,7 +347,15 @@ describe(method, function () {
assert.deepEqual(payload.params, test.formattedArgs2 || []);
});
}


if (test.call3) {
provider.injectResult(clone(test.result3));
provider.injectValidation(function (payload) {
assert.equal(payload.jsonrpc, '2.0');
assert.equal(payload.method, test.call3);
assert.deepEqual(payload.params, test.formattedArgs3 || []);
});
}

provider.injectResult(null);
provider.injectValidation(function (payload) {
Expand Down
16 changes: 16 additions & 0 deletions test/helpers/test.method.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ var runTests = function (obj, method, tests) {
});
}

if (test.call3) {
provider.injectResult(clone(test.result3));
provider.injectValidation(function (payload) {
assert.equal(payload.jsonrpc, '2.0');
assert.equal(payload.method, test.call3);
assert.deepEqual(payload.params, test.formattedArgs3 || []);
});
}

// if notification its sendTransaction, which needs two more results, subscription and receipt
if(test.notification) {
Expand Down Expand Up @@ -198,6 +206,14 @@ var runTests = function (obj, method, tests) {
});
}

if (test.call3) {
provider.injectResult(clone(test.result3));
provider.injectValidation(function (payload) {
assert.equal(payload.jsonrpc, '2.0');
assert.equal(payload.method, test.call3);
assert.deepEqual(payload.params, test.formattedArgs3 || []);
});
}

var args = clone(test.args);

Expand Down
Loading