Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eth_feeHistory (EIP 1559) #4191

Merged
merged 11 commits into from
Jul 24, 2021
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ Released with 1.0.0-beta.37 code base.
### Added

- London transaction support (#4155)
- RPC support `eth_feehistory` call

### Changed
- Grammar fix (#4088) and updated Swarm (#4151)and Whisper doc links (#4170)
Expand Down
37 changes: 37 additions & 0 deletions docs/web3-eth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,43 @@ Example

------------------------------------------------------------------------------

.. _eth-feehistory:


getFeeHistory
=====================

.. code-block:: javascript

web3.eth.getFeeHistory(blockCount, newestBlock, rewardPercentiles, [callback])

Transaction fee history
Returns base fee per gas and transaction effective priority fee per gas history for the requested block range if available.
The range between headBlock-4 and headBlock is guaranteed to be available while retrieving data from the pending block and older
history are optional to support. For pre-EIP-1559 blocks the gas prices are returned as rewards and zeroes are returned for the base fee per gas.

----------
Parameters
----------

1. ``String|Number|BN|BigNumber`` - Number of blocks in the requested range. Between 1 and 1024 blocks can be requested in a single query. Less than requested may be returned if not all blocks are available.
2. ``String|Number|BN|BigNumber`` - Highest number block of the requested range.
3. ``Array of numbers`` - A monotonically increasing list of percentile values to sample from each block's effective priority fees per gas in ascending order, weighted by gas used. Example: `["0", "25", "50", "75", "100"]` or `["0", "0.5", "1", "1.5", "3", "80"]`
4. ``Function`` - (optional) Optional callback, returns an error object as first parameter and the result as second.

-------
Returns
-------

``Promise`` returns ``Object`` - Fee history for the returned block range. The object:

- ``Number`` oldestBlock - Lowest number block of the returned range.
- ``Array of strings`` baseFeePerGas - An array of block base fees per gas. This includes the next block after the newest of the returned range, because this value can be derived from the newest block. Zeroes are returned for pre-EIP-1559 blocks.
- ``Array of numbers`` gasUsedRatio - An array of block gas used ratios. These are calculated as the ratio of gasUsed and gasLimit.
- ``Array of string arrays`` reward - An array of effective priority fee per gas data points from a single block. All zeroes are returned if the block is empty.

------------------------------------------------------------------------------


getAccounts
=====================
Expand Down
6 changes: 6 additions & 0 deletions packages/web3-eth/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,12 @@ var Eth = function Eth() {
params: 0,
outputFormatter: formatter.outputBigNumberFormatter
}),
new Method({
name: 'getFeeHistory',
call: 'eth_feeHistory',
params: 3,
spacesailor24 marked this conversation as resolved.
Show resolved Hide resolved
inputFormatter: [utils.toNumber, utils.toHex, function(value) {return value}]
}),
new Method({
name: 'getAccounts',
call: 'eth_accounts',
Expand Down
14 changes: 14 additions & 0 deletions packages/web3-eth/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ export class Eth {
callback?: (error: Error, gasPrice: string) => void
): Promise<string>;

getFeeHistory(
blockCount: number | BigNumber | BN | string,
lastBlock: number | BigNumber | BN | string,
rewardPercentiles: number[],
callback?: (error: Error, feeHistory: FeeHistoryResult) => void
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should contain blockCount, newestBlock and rewardPercentiles?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you mixed up getGasPrice and getFeeHistory?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also rewardPercentiles should be marked as optional

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I think the docs here are misleading https://github.com/ChainSafe/web3.js/pull/4190/files#diff-b1b5b8a010cd61ad800e528887f49730db04064d59d3ee5ed14de0f49f2ba11cR740

Looks like you still have to pass an empty array so I'm not sure if web3 should just do that as the default if that param isn't set? Would be more user friendly than having to pass an empty array.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GregTheGreek Whoops, forgot to push, thank you

@corymsmith I think web3 defaulting an empty array would be nice for the user, but we can't have two optional arguments in typescript, so I'm not sure how we could do this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I suppose the only way to do it would be to add a formatter that formats null into []

): Promise<FeeHistoryResult>;

getAccounts(
callback?: (error: Error, accounts: string[]) => void
): Promise<string[]>;
Expand Down Expand Up @@ -439,3 +446,10 @@ export interface StorageProof {
value: string;
proof: string[];
}

export interface FeeHistoryResult {
baseFeePerGas: string[];
gasUsedRatio: number[];
oldestBlock: number;
reward: string[][];
}
12 changes: 11 additions & 1 deletion packages/web3-eth/types/tests/eth.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ import {
TransactionConfig,
hardfork,
Common,
chain
chain,
FeeHistoryResult
} from 'web3-eth';
import BN = require('bn.js');
import BigNumber from 'bignumber.js';
Expand Down Expand Up @@ -178,6 +179,15 @@ eth.getGasPrice();
// $ExpectType Promise<string>
eth.getGasPrice((error: Error, gasPrice: string) => {});

// $ExpectType Promise<FeeHistoryResult>
eth.getFeeHistory(
4, "0xA30953", []
);
// $ExpectType Promise<FeeHistoryResult>
eth.getFeeHistory(
4, "0xA30953", [],
(error: Error, feeHistory: FeeHistoryResult) => {});

// $ExpectType Promise<string[]>
eth.getAccounts();
// $ExpectType Promise<string[]>
Expand Down
4 changes: 3 additions & 1 deletion packages/web3-utils/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -436,5 +436,7 @@ module.exports = {
isTopicInBloom: utils.isTopicInBloom,
isInBloom: utils.isInBloom,

compareBlockNumbers: compareBlockNumbers
compareBlockNumbers: compareBlockNumbers,

toNumber: utils.toNumber
};
14 changes: 13 additions & 1 deletion packages/web3-utils/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,17 @@ var sha3Raw = function(value) {
return value;
};

/**
* Auto converts any given value into it's hex representation,
* then converts hex to number.
*
* @method toNumber
* @param {String|Number|BN} value
* @return {Number}
*/
var toNumber = function(value) {
return typeof value === 'number' ? value : hexToNumber(toHex(value));
}

module.exports = {
BN: BN,
Expand Down Expand Up @@ -550,5 +561,6 @@ module.exports = {
rightPad: rightPad,
toTwosComplement: toTwosComplement,
sha3: sha3,
sha3Raw: sha3Raw
sha3Raw: sha3Raw,
toNumber: toNumber
};
2 changes: 2 additions & 0 deletions packages/web3-utils/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export function testAddress(bloom: string, address: string): boolean;
export function testTopic(bloom: string, topic: string): boolean;
export function getSignatureParameters(signature: string): {r: string; s: string; v: number};
export function stripHexPrefix(str: string): string;
export function toNumber(value: number | string | BN): number;

// interfaces
export interface Utils {
Expand Down Expand Up @@ -178,6 +179,7 @@ export interface Utils {
testTopic(bloom: string, topic: string): boolean;
getSignatureParameters(signature: string): {r: string; s: string; v: number};
stripHexPrefix(str: string): string;
toNumber(value: number | string | BN): number;
}

export interface Units {
Expand Down
44 changes: 44 additions & 0 deletions packages/web3-utils/types/tests/to-number-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
This file is part of web3.js.

web3.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

web3.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file to-number-test.ts
* @author Josh Stevens <joshstevens19@hotmail.co.uk>
* @date 2018
*/

import BN = require('bn.js');
import {toNumber} from 'web3-utils';

// $ExpectType number
toNumber('234');
// $ExpectType number
toNumber(234);
// $ExpectType number
toNumber(new BN(3));

// $ExpectError
toNumber(['string']);
// $ExpectError
toNumber(true);
// $ExpectError
toNumber([4]);
// $ExpectError
toNumber({});
// $ExpectError
toNumber(null);
// $ExpectError
toNumber(undefined);
124 changes: 124 additions & 0 deletions test/eth.feeHistory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
var BigNumber = require('bignumber.js');

var testMethod = require('./helpers/test.method.js');

var method = 'getFeeHistory';
var methodCall = 'eth_feeHistory';

var tests = [
{
args: [4, "0xA30953", []],
formattedArgs: [4, "0xA30953", []],
result: {
"baseFeePerGas": [
"0xa",
"0x9",
"0x8",
"0x9",
"0x9"
],
"gasUsedRatio": [
0.003920375,
0.002625,
0.904999125,
0.348347625
],
"oldestBlock": 10684752
},
formattedResult: {
"baseFeePerGas": [
"0xa",
"0x9",
"0x8",
"0x9",
"0x9"
],
"gasUsedRatio": [
0.003920375,
0.002625,
0.904999125,
0.348347625
],
"oldestBlock": 10684752
},
call: methodCall
},
{
args: ['0x4', 10684755, []],
formattedArgs: [4, "0xa30953", []],
result: {
"baseFeePerGas": [
"0xa",
"0x9",
"0x8",
"0x9",
"0x9"
],
"gasUsedRatio": [
0.003920375,
0.002625,
0.904999125,
0.348347625
],
"oldestBlock": 10684752
},
formattedResult: {
"baseFeePerGas": [
"0xa",
"0x9",
"0x8",
"0x9",
"0x9"
],
"gasUsedRatio": [
0.003920375,
0.002625,
0.904999125,
0.348347625
],
"oldestBlock": 10684752
},
call: methodCall
},
{
args: [new BigNumber(4), '10684755', []],
formattedArgs: [4, "0xa30953", []],
result: {
"baseFeePerGas": [
"0xa",
"0x9",
"0x8",
"0x9",
"0x9"
],
"gasUsedRatio": [
0.003920375,
0.002625,
0.904999125,
0.348347625
],
"oldestBlock": 10684752
},
formattedResult: {
"baseFeePerGas": [
"0xa",
"0x9",
"0x8",
"0x9",
"0x9"
],
"gasUsedRatio": [
0.003920375,
0.002625,
0.904999125,
0.348347625
],
"oldestBlock": 10684752
},
call: methodCall
}
];


testMethod.runTests('eth', method, tests);

1 change: 1 addition & 0 deletions test/eth_methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ describe('eth', function() {
u.methodExists(eth, 'isMining');
u.methodExists(eth, 'getCoinbase');
u.methodExists(eth, 'getGasPrice');
u.methodExists(eth, 'getFeeHistory');
u.methodExists(eth, 'getHashrate');
u.methodExists(eth, 'getAccounts');
u.methodExists(eth, 'getBlockNumber');
Expand Down
23 changes: 23 additions & 0 deletions test/utils.hexToNumber.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
var assert = require('assert');
var utils = require('../packages/web3-utils');

describe('lib/utils/utils', function () {
describe('hexToNumber', function () {
it('should return the correct value', function () {

assert.equal(utils.hexToNumber("0x3e8"), 1000);
assert.equal(utils.hexToNumber('0x1f0fe294a36'), 2134567897654);
// allow compatiblity
assert.equal(utils.hexToNumber(100000), 100000);
});

it('should validate hex strings', function() {
try {
utils.hexToNumber('100000');
assert.fail();
} catch (error){
assert(error.message.includes('is not a valid hex string'))
}
})
});
});
Loading