Adds eth_maxPriorityFeePerGas implementaiton (#570)
* added eth_maxPriorityFeePerGas rpc call * cargo fmt * moved block_base_fee implementation into the trait * added basic test for eth_maxPriorityFeePerGas * added test for eth_maxPriorityFeePerGas calculation * Added support for zero-cost transactions * Added 'eip1559_not_activated' error * Fixes 'chain::supplier::test::return_nodes' test * cargo fmt * cargo fmt * made calculation of fallback priority fee to ignore zero-cost transactions * cargo fmt * made use of 'saturating_sub' instead of minus
This commit is contained in:
parent
64a1614769
commit
3b19a79c37
@ -666,6 +666,20 @@ impl TransactionQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns effective priority fee gas price of currently the worst transaction in the pool.
|
||||||
|
/// If the worst transaction has zero gas price, the minimal gas price is returned.
|
||||||
|
pub fn current_worst_effective_priority_fee(&self) -> U256 {
|
||||||
|
self.pool
|
||||||
|
.read()
|
||||||
|
.worst_transaction()
|
||||||
|
.filter(|tx| !tx.signed().has_zero_gas_price())
|
||||||
|
.map(|tx| {
|
||||||
|
tx.signed()
|
||||||
|
.effective_priority_fee(self.options.read().block_base_fee)
|
||||||
|
})
|
||||||
|
.unwrap_or(self.options.read().minimal_gas_price)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a status of the queue.
|
/// Returns a status of the queue.
|
||||||
pub fn status(&self) -> Status {
|
pub fn status(&self) -> Status {
|
||||||
let pool = self.pool.read();
|
let pool = self.pool.read();
|
||||||
|
@ -1090,6 +1090,10 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_aura(&self) -> bool {
|
||||||
|
self.engine().name() == "AuthorityRound"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IoClient for TestBlockChainClient {
|
impl IoClient for TestBlockChainClient {
|
||||||
|
@ -416,6 +416,40 @@ pub trait BlockChainClient:
|
|||||||
corpus.into()
|
corpus.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sorted list of transaction priority gas prices from at least last sample_size blocks.
|
||||||
|
fn priority_gas_price_corpus(
|
||||||
|
&self,
|
||||||
|
sample_size: usize,
|
||||||
|
eip1559_transition: BlockNumber,
|
||||||
|
) -> ::stats::Corpus<U256> {
|
||||||
|
let mut h = self.chain_info().best_block_hash;
|
||||||
|
let mut corpus = Vec::new();
|
||||||
|
while corpus.is_empty() {
|
||||||
|
for _ in 0..sample_size {
|
||||||
|
let block = match self.block(BlockId::Hash(h)) {
|
||||||
|
Some(block) => block,
|
||||||
|
None => return corpus.into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if block.number() == 0 || block.number() < eip1559_transition {
|
||||||
|
return corpus.into();
|
||||||
|
}
|
||||||
|
block
|
||||||
|
.transaction_views()
|
||||||
|
.iter()
|
||||||
|
.filter(
|
||||||
|
|t| t.gas_price() > 0.into(), /* filter zero cost transactions */
|
||||||
|
)
|
||||||
|
.foreach(|t| {
|
||||||
|
// As block.number() >= eip_1559_transition, the base_fee should exist
|
||||||
|
corpus.push(t.effective_priority_gas_price(Some(block.header().base_fee())))
|
||||||
|
});
|
||||||
|
h = block.parent_hash().clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
corpus.into()
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the preferred chain ID to sign on
|
/// Get the preferred chain ID to sign on
|
||||||
fn signing_chain_id(&self) -> Option<u64>;
|
fn signing_chain_id(&self) -> Option<u64>;
|
||||||
|
|
||||||
|
@ -1006,6 +1006,14 @@ impl miner::MinerService for Miner {
|
|||||||
self.transaction_queue.current_worst_gas_price() * 110u32 / 100
|
self.transaction_queue.current_worst_gas_price() * 110u32 / 100
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sensible_max_priority_fee(&self) -> U256 {
|
||||||
|
// 10% above our minimum.
|
||||||
|
self.transaction_queue
|
||||||
|
.current_worst_effective_priority_fee()
|
||||||
|
* 110u32
|
||||||
|
/ 100
|
||||||
|
}
|
||||||
|
|
||||||
fn sensible_gas_limit(&self) -> U256 {
|
fn sensible_gas_limit(&self) -> U256 {
|
||||||
self.params.read().gas_range_target.0 / 5
|
self.params.read().gas_range_target.0 / 5
|
||||||
}
|
}
|
||||||
|
@ -260,6 +260,9 @@ pub trait MinerService: Send + Sync {
|
|||||||
/// Suggested gas price.
|
/// Suggested gas price.
|
||||||
fn sensible_gas_price(&self) -> U256;
|
fn sensible_gas_price(&self) -> U256;
|
||||||
|
|
||||||
|
/// Suggested max priority fee gas price
|
||||||
|
fn sensible_max_priority_fee(&self) -> U256;
|
||||||
|
|
||||||
/// Suggested gas limit.
|
/// Suggested gas limit.
|
||||||
fn sensible_gas_limit(&self) -> U256;
|
fn sensible_gas_limit(&self) -> U256;
|
||||||
|
|
||||||
|
@ -504,7 +504,10 @@ mod test {
|
|||||||
use super::{super::tests::*, *};
|
use super::{super::tests::*, *};
|
||||||
use blocks::SyncHeader;
|
use blocks::SyncHeader;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient};
|
use ethcore::{
|
||||||
|
client::{BlockChainClient, EachBlockWith, TestBlockChainClient},
|
||||||
|
spec::Spec,
|
||||||
|
};
|
||||||
use ethereum_types::H256;
|
use ethereum_types::H256;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use rlp::{Rlp, RlpStream};
|
use rlp::{Rlp, RlpStream};
|
||||||
@ -769,7 +772,7 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn return_nodes() {
|
fn return_nodes() {
|
||||||
let mut client = TestBlockChainClient::new();
|
let mut client = TestBlockChainClient::new_with_spec(Spec::new_test_round());
|
||||||
let queue = RwLock::new(VecDeque::new());
|
let queue = RwLock::new(VecDeque::new());
|
||||||
let sync = dummy_sync_with_peer(H256::zero(), &client);
|
let sync = dummy_sync_with_peer(H256::zero(), &client);
|
||||||
let ss = TestSnapshotService::new();
|
let ss = TestSnapshotService::new();
|
||||||
|
@ -137,6 +137,29 @@ impl<'a> TypedTransactionView<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the actual priority gas price paid to the miner
|
||||||
|
pub fn effective_priority_gas_price(&self, block_base_fee: Option<U256>) -> U256 {
|
||||||
|
match self.transaction_type {
|
||||||
|
TypedTxId::Legacy => self
|
||||||
|
.gas_price()
|
||||||
|
.saturating_sub(block_base_fee.unwrap_or_default()),
|
||||||
|
TypedTxId::AccessList => self
|
||||||
|
.gas_price()
|
||||||
|
.saturating_sub(block_base_fee.unwrap_or_default()),
|
||||||
|
TypedTxId::EIP1559Transaction => {
|
||||||
|
let max_priority_fee_per_gas: U256 =
|
||||||
|
view!(Self, &self.rlp.rlp.data().unwrap()[1..])
|
||||||
|
.rlp
|
||||||
|
.val_at(2);
|
||||||
|
min(
|
||||||
|
max_priority_fee_per_gas,
|
||||||
|
self.gas_price()
|
||||||
|
.saturating_sub(block_base_fee.unwrap_or_default()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the gas field of the transaction.
|
/// Get the gas field of the transaction.
|
||||||
pub fn gas(&self) -> U256 {
|
pub fn gas(&self) -> U256 {
|
||||||
match self.transaction_type {
|
match self.transaction_type {
|
||||||
@ -260,6 +283,7 @@ mod tests {
|
|||||||
assert_eq!(view.nonce(), 0.into());
|
assert_eq!(view.nonce(), 0.into());
|
||||||
assert_eq!(view.gas_price(), 1.into());
|
assert_eq!(view.gas_price(), 1.into());
|
||||||
assert_eq!(view.effective_gas_price(None), 1.into());
|
assert_eq!(view.effective_gas_price(None), 1.into());
|
||||||
|
assert_eq!(view.effective_priority_gas_price(None), 1.into());
|
||||||
assert_eq!(view.gas(), 0x61a8.into());
|
assert_eq!(view.gas(), 0x61a8.into());
|
||||||
assert_eq!(view.value(), 0xa.into());
|
assert_eq!(view.value(), 0xa.into());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -285,6 +309,7 @@ mod tests {
|
|||||||
let view = view!(TypedTransactionView, &rlp);
|
let view = view!(TypedTransactionView, &rlp);
|
||||||
assert_eq!(view.nonce(), 0x1.into());
|
assert_eq!(view.nonce(), 0x1.into());
|
||||||
assert_eq!(view.gas_price(), 0xa.into());
|
assert_eq!(view.gas_price(), 0xa.into());
|
||||||
|
assert_eq!(view.effective_priority_gas_price(None), 0xa.into());
|
||||||
assert_eq!(view.gas(), 0x1e241.into());
|
assert_eq!(view.gas(), 0x1e241.into());
|
||||||
assert_eq!(view.value(), 0x0.into());
|
assert_eq!(view.value(), 0x0.into());
|
||||||
assert_eq!(view.data(), "".from_hex().unwrap());
|
assert_eq!(view.data(), "".from_hex().unwrap());
|
||||||
@ -306,6 +331,10 @@ mod tests {
|
|||||||
assert_eq!(view.nonce(), 0x1.into());
|
assert_eq!(view.nonce(), 0x1.into());
|
||||||
assert_eq!(view.gas_price(), 0xa.into());
|
assert_eq!(view.gas_price(), 0xa.into());
|
||||||
assert_eq!(view.effective_gas_price(Some(0x07.into())), 0x08.into());
|
assert_eq!(view.effective_gas_price(Some(0x07.into())), 0x08.into());
|
||||||
|
assert_eq!(
|
||||||
|
view.effective_priority_gas_price(Some(0x07.into())),
|
||||||
|
0x01.into()
|
||||||
|
);
|
||||||
assert_eq!(view.gas(), 0x1e241.into());
|
assert_eq!(view.gas(), 0x1e241.into());
|
||||||
assert_eq!(view.value(), 0x0.into());
|
assert_eq!(view.value(), 0x0.into());
|
||||||
assert_eq!(view.data(), "".from_hex().unwrap());
|
assert_eq!(view.data(), "".from_hex().unwrap());
|
||||||
|
@ -91,7 +91,10 @@ use ethcore::{client::BlockChainClient, miner::MinerService};
|
|||||||
use ethereum_types::{Address, H256, H520, U256};
|
use ethereum_types::{Address, H256, H520, U256};
|
||||||
use ethkey::Password;
|
use ethkey::Password;
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
use types::transaction::{PendingTransaction, SignedTransaction};
|
use types::{
|
||||||
|
transaction::{PendingTransaction, SignedTransaction},
|
||||||
|
BlockNumber,
|
||||||
|
};
|
||||||
|
|
||||||
use jsonrpc_core::{
|
use jsonrpc_core::{
|
||||||
futures::{future, Future, IntoFuture},
|
futures::{future, Future, IntoFuture},
|
||||||
@ -397,6 +400,24 @@ where
|
|||||||
.unwrap_or_else(|| miner.sensible_gas_price())
|
.unwrap_or_else(|| miner.sensible_gas_price())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extract the default priority gas price from a client and miner.
|
||||||
|
pub fn default_max_priority_fee_per_gas<C, M>(
|
||||||
|
client: &C,
|
||||||
|
miner: &M,
|
||||||
|
percentile: usize,
|
||||||
|
eip1559_transition: BlockNumber,
|
||||||
|
) -> U256
|
||||||
|
where
|
||||||
|
C: BlockChainClient,
|
||||||
|
M: MinerService,
|
||||||
|
{
|
||||||
|
client
|
||||||
|
.priority_gas_price_corpus(100, eip1559_transition)
|
||||||
|
.percentile(percentile)
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_else(|| miner.sensible_max_priority_fee())
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert RPC confirmation payload to signer confirmation payload.
|
/// Convert RPC confirmation payload to signer confirmation payload.
|
||||||
/// May need to resolve in the future to fetch things like gas price.
|
/// May need to resolve in the future to fetch things like gas price.
|
||||||
pub fn from_rpc<D>(
|
pub fn from_rpc<D>(
|
||||||
|
@ -273,6 +273,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn eip1559_not_activated() -> Error {
|
||||||
|
unsupported("EIP-1559 is not activated", None)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn not_enough_data() -> Error {
|
pub fn not_enough_data() -> Error {
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
|
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
|
||||||
|
@ -52,7 +52,7 @@ use v1::{
|
|||||||
self,
|
self,
|
||||||
block_import::is_major_importing,
|
block_import::is_major_importing,
|
||||||
deprecated::{self, DeprecationNotice},
|
deprecated::{self, DeprecationNotice},
|
||||||
dispatch::{default_gas_price, FullDispatcher},
|
dispatch::{default_gas_price, default_max_priority_fee_per_gas, FullDispatcher},
|
||||||
errors, fake_sign, limit_logs,
|
errors, fake_sign, limit_logs,
|
||||||
},
|
},
|
||||||
metadata::Metadata,
|
metadata::Metadata,
|
||||||
@ -696,6 +696,22 @@ where
|
|||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn max_priority_fee_per_gas(&self) -> BoxFuture<U256> {
|
||||||
|
let latest_block = self.client.chain_info().best_block_number;
|
||||||
|
let eip1559_transition = self.client.engine().params().eip1559_transition;
|
||||||
|
|
||||||
|
if latest_block + 1 >= eip1559_transition {
|
||||||
|
Box::new(future::ok(default_max_priority_fee_per_gas(
|
||||||
|
&*self.client,
|
||||||
|
&*self.miner,
|
||||||
|
self.options.gas_price_percentile,
|
||||||
|
eip1559_transition,
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
Box::new(future::done(Err(errors::eip1559_not_activated())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn fee_history(
|
fn fee_history(
|
||||||
&self,
|
&self,
|
||||||
mut block_count: U256,
|
mut block_count: U256,
|
||||||
@ -805,8 +821,11 @@ where
|
|||||||
|
|
||||||
gas_and_reward.push((
|
gas_and_reward.push((
|
||||||
gas_used,
|
gas_used,
|
||||||
txs[i].effective_gas_price(base_fee)
|
txs[i]
|
||||||
- base_fee.unwrap_or_default(),
|
.effective_gas_price(base_fee)
|
||||||
|
.saturating_sub(
|
||||||
|
base_fee.unwrap_or_default(),
|
||||||
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ use std::{env, sync::Arc};
|
|||||||
|
|
||||||
use accounts::AccountProvider;
|
use accounts::AccountProvider;
|
||||||
use ethcore::{
|
use ethcore::{
|
||||||
client::{BlockChainClient, ChainInfo, Client, ClientConfig, ImportBlock},
|
client::{BlockChainClient, ChainInfo, Client, ClientConfig, EvmTestClient, ImportBlock},
|
||||||
ethereum,
|
ethereum,
|
||||||
miner::Miner,
|
miner::Miner,
|
||||||
spec::{Genesis, Spec},
|
spec::{Genesis, Spec},
|
||||||
@ -67,7 +67,7 @@ fn snapshot_service() -> Arc<TestSnapshotService> {
|
|||||||
|
|
||||||
fn make_spec(chain: &BlockChain) -> Spec {
|
fn make_spec(chain: &BlockChain) -> Spec {
|
||||||
let genesis = Genesis::from(chain.genesis());
|
let genesis = Genesis::from(chain.genesis());
|
||||||
let mut spec = ethereum::new_frontier_test();
|
let mut spec = EvmTestClient::spec_from_json(&chain.network).unwrap();
|
||||||
let state = chain.pre_state.clone().into();
|
let state = chain.pre_state.clone().into();
|
||||||
spec.set_genesis_state(state)
|
spec.set_genesis_state(state)
|
||||||
.expect("unable to set genesis state");
|
.expect("unable to set genesis state");
|
||||||
@ -281,6 +281,26 @@ fn eth_get_block() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn eth_get_max_priority_fee_per_gas() {
|
||||||
|
let chain = extract_non_legacy_chain!(
|
||||||
|
"BlockchainTests/ValidBlocks/bcEIP1559/transType",
|
||||||
|
ForkSpec::London
|
||||||
|
);
|
||||||
|
let tester = EthTester::from_chain(&chain);
|
||||||
|
let request = r#"{"method":"eth_maxPriorityFeePerGas","params":[],"id":1,"jsonrpc":"2.0"}"#;
|
||||||
|
|
||||||
|
// We are expecting for 50-th percentile of the previous 100 blocks transactions priority fees.
|
||||||
|
//
|
||||||
|
// Sorted priority fees: 0x64 0x64 0x64 0x7d 0x7d 0xea 0x149.
|
||||||
|
// Currently, the way 50-th percentile is calculated, the 3rd fee would be the result.
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":"0x64","id":1}"#;
|
||||||
|
assert_eq!(
|
||||||
|
tester.handler.handle_request_sync(request).unwrap(),
|
||||||
|
response
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn eth_get_block_by_hash() {
|
fn eth_get_block_by_hash() {
|
||||||
let chain = extract_chain!("BlockchainTests/ValidBlocks/bcGasPricerTest/RPC_API_Test");
|
let chain = extract_chain!("BlockchainTests/ValidBlocks/bcGasPricerTest/RPC_API_Test");
|
||||||
|
@ -359,6 +359,10 @@ impl MinerService for TestMinerService {
|
|||||||
20_000_000_000u64.into()
|
20_000_000_000u64.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sensible_max_priority_fee(&self) -> U256 {
|
||||||
|
2_000_000_000u64.into()
|
||||||
|
}
|
||||||
|
|
||||||
fn sensible_gas_limit(&self) -> U256 {
|
fn sensible_gas_limit(&self) -> U256 {
|
||||||
0x5208.into()
|
0x5208.into()
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ use std::{
|
|||||||
|
|
||||||
use accounts::AccountProvider;
|
use accounts::AccountProvider;
|
||||||
use ethcore::{
|
use ethcore::{
|
||||||
client::{BlockChainClient, EachBlockWith, Executed, TestBlockChainClient},
|
client::{BlockChainClient, EachBlockWith, EvmTestClient, Executed, TestBlockChainClient},
|
||||||
miner::{self, MinerService},
|
miner::{self, MinerService},
|
||||||
};
|
};
|
||||||
use ethereum_types::{Address, Bloom, H160, H256, U256};
|
use ethereum_types::{Address, Bloom, H160, H256, U256};
|
||||||
@ -51,6 +51,12 @@ fn blockchain_client() -> Arc<TestBlockChainClient> {
|
|||||||
Arc::new(client)
|
Arc::new(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn eip1559_blockchain_client() -> Arc<TestBlockChainClient> {
|
||||||
|
let spec = EvmTestClient::spec_from_json(ðjson::spec::ForkSpec::London).unwrap();
|
||||||
|
let client = TestBlockChainClient::new_with_spec(spec);
|
||||||
|
Arc::new(client)
|
||||||
|
}
|
||||||
|
|
||||||
fn accounts_provider() -> Arc<AccountProvider> {
|
fn accounts_provider() -> Arc<AccountProvider> {
|
||||||
Arc::new(AccountProvider::transient_provider())
|
Arc::new(AccountProvider::transient_provider())
|
||||||
}
|
}
|
||||||
@ -89,8 +95,25 @@ impl Default for EthTester {
|
|||||||
|
|
||||||
impl EthTester {
|
impl EthTester {
|
||||||
pub fn new_with_options(options: EthClientOptions) -> Self {
|
pub fn new_with_options(options: EthClientOptions) -> Self {
|
||||||
let runtime = Runtime::with_thread_count(1);
|
|
||||||
let client = blockchain_client();
|
let client = blockchain_client();
|
||||||
|
EthTester::new_with_client_and_options(client, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_eip1559_with_options(options: EthClientOptions) -> Self {
|
||||||
|
let client = eip1559_blockchain_client();
|
||||||
|
EthTester::new_with_client_and_options(client, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_blocks(&self, count: usize, with: EachBlockWith) {
|
||||||
|
self.client.add_blocks(count, with);
|
||||||
|
self.sync.increase_imported_block_number(count as u64);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_with_client_and_options(
|
||||||
|
client: Arc<TestBlockChainClient>,
|
||||||
|
options: EthClientOptions,
|
||||||
|
) -> Self {
|
||||||
|
let runtime = Runtime::with_thread_count(1);
|
||||||
let sync = sync_provider();
|
let sync = sync_provider();
|
||||||
let ap = accounts_provider();
|
let ap = accounts_provider();
|
||||||
let ap2 = ap.clone();
|
let ap2 = ap.clone();
|
||||||
@ -126,11 +149,6 @@ impl EthTester {
|
|||||||
hashrates,
|
hashrates,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_blocks(&self, count: usize, with: EachBlockWith) {
|
|
||||||
self.client.add_blocks(count, with);
|
|
||||||
self.sync.increase_imported_block_number(count as u64);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -537,6 +555,33 @@ fn rpc_eth_gas_price() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_eth_get_max_priority_fee_per_gas() {
|
||||||
|
let tester = EthTester::new_eip1559_with_options(Default::default());
|
||||||
|
|
||||||
|
let request = r#"{"method":"eth_maxPriorityFeePerGas","params":[],"id":1,"jsonrpc":"2.0"}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":"0x77359400","id":1}"#; // 2 GWei
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
tester.io.handle_request_sync(request),
|
||||||
|
Some(response.to_owned())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_eth_get_max_priority_fee_per_gas_error() {
|
||||||
|
let tester = EthTester::default();
|
||||||
|
|
||||||
|
let request = r#"{"method":"eth_maxPriorityFeePerGas","params":[],"id":1,"jsonrpc":"2.0"}"#;
|
||||||
|
let response =
|
||||||
|
r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"EIP-1559 is not activated"},"id":1}"#;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
tester.io.handle_request_sync(request),
|
||||||
|
Some(response.to_owned())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_accounts() {
|
fn rpc_eth_accounts() {
|
||||||
let tester = EthTester::default();
|
let tester = EthTester::default();
|
||||||
|
@ -51,6 +51,23 @@ macro_rules! register_test {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! extract_non_legacy_chain {
|
||||||
|
($file: expr, $network: expr) => {{
|
||||||
|
const RAW_DATA: &'static [u8] = include_bytes!(concat!(
|
||||||
|
"../../../../ethcore/res/json_tests/",
|
||||||
|
$file,
|
||||||
|
".json"
|
||||||
|
));
|
||||||
|
::ethjson::blockchain::Test::load(RAW_DATA)
|
||||||
|
.unwrap()
|
||||||
|
.into_iter()
|
||||||
|
.filter(|&(_, ref t)| t.network == $network)
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.1
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod eth;
|
mod eth;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -60,6 +60,10 @@ pub trait Eth {
|
|||||||
#[rpc(name = "eth_gasPrice")]
|
#[rpc(name = "eth_gasPrice")]
|
||||||
fn gas_price(&self) -> BoxFuture<U256>;
|
fn gas_price(&self) -> BoxFuture<U256>;
|
||||||
|
|
||||||
|
/// Returns current max_priority_fee
|
||||||
|
#[rpc(name = "eth_maxPriorityFeePerGas")]
|
||||||
|
fn max_priority_fee_per_gas(&self) -> BoxFuture<U256>;
|
||||||
|
|
||||||
/// Returns transaction fee history.
|
/// Returns transaction fee history.
|
||||||
#[rpc(name = "eth_feeHistory")]
|
#[rpc(name = "eth_feeHistory")]
|
||||||
fn fee_history(&self, _: U256, _: BlockNumber, _: Option<Vec<f64>>)
|
fn fee_history(&self, _: U256, _: BlockNumber, _: Option<Vec<f64>>)
|
||||||
|
Loading…
Reference in New Issue
Block a user