Compare commits

...

6 Commits

Author SHA1 Message Date
POA
f13fa10b8a Bump to v3.3.2, London on Sokol, effective_gas_price function enhancement 2021-12-07 14:03:48 +03:00
POA
657100cebc Bump to v3.3.1 2021-11-30 10:55:54 +03:00
POA
d2d19ec8c2 Merge branch 'dev' of https://github.com/openethereum/openethereum into dev 2021-11-30 10:39:06 +03:00
POA
0f872aff78 Add a bootnode for Kovan 2021-11-30 10:38:55 +03:00
Rim Rakhimov
405738c791 Fix for modexp overflow in debug mode (#578)
* fix modexp overflow panic in debug mode

* Added one more unit test for modexp

* Remove redundant bytes from modexp unit test

Co-authored-by: POA <33550681+poa@users.noreply.github.com>
2021-11-30 10:33:40 +03:00
Rim Rakhimov
3b19a79c37 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
2021-11-25 10:43:00 +03:00
24 changed files with 505 additions and 26 deletions

View File

@@ -1,3 +1,20 @@
## OpenEthereum v3.3.2
Enhancements:
* London hardfork block: Sokol (24114400)
Bug fixes:
* Fix for maxPriorityFeePerGas overflow
## OpenEthereum v3.3.1
Enhancements:
* Add eth_maxPriorityFeePerGas implementation (#570)
* Add a bootnode for Kovan
Bug fixes:
* Fix for modexp overflow in debug mode (#578)
## OpenEthereum v3.3.0
Enhancements:

4
Cargo.lock generated
View File

@@ -2932,7 +2932,7 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
[[package]]
name = "openethereum"
version = "3.3.0"
version = "3.3.2"
dependencies = [
"ansi_term 0.10.2",
"atty",
@@ -3282,7 +3282,7 @@ dependencies = [
[[package]]
name = "parity-version"
version = "3.3.0"
version = "3.3.2"
dependencies = [
"parity-bytes",
"rlp",

View File

@@ -2,7 +2,7 @@
description = "OpenEthereum"
name = "openethereum"
# NOTE Make sure to update util/version/Cargo.toml as well
version = "3.3.0"
version = "3.3.2"
license = "GPL-3.0"
authors = [
"OpenEthereum developers",

View File

@@ -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.
pub fn status(&self) -> Status {
let pool = self.pool.read();

View File

@@ -265,6 +265,7 @@
},
"nodes": [
"enode://30499bde23362f7d310a34518a2a6ff765921870bf0c3e63d21153cfa7ba9cf39cc7c8e54e9dad2f2b3c07288b3e91b220656833cc2d843a54875c229f3f959a@8.9.8.175:30303",
"enode://30499bde23362f7d310a34518a2a6ff765921870bf0c3e63d21153cfa7ba9cf39cc7c8e54e9dad2f2b3c07288b3e91b220656833cc2d843a54875c229f3f959a@45.33.77.29:30303",
"enode://16898006ba2cd4fa8bf9a3dfe32684c178fa861df144bfc21fe800dc4838a03e342056951fa9fd533dcb0be1219e306106442ff2cf1f7e9f8faa5f2fc1a3aa45@116.203.116.241:30303",
"enode://49a0e1aa38caa12cbf31222cb4e31cef1e8794cb4dd38012f84498ac867b19584e29bbf6d53201d7dfd3b5eb0998a4d908d096ed4ddb5f9102c623852cd331ec@54.87.247.5:30303"
]

View File

@@ -52,7 +52,16 @@
"eip1884Transition": 12095200,
"eip2028Transition": 12095200,
"eip2929Transition": 21050600,
"eip2930Transition": 21050600
"eip2930Transition": 21050600,
"eip3198Transition": 24114400,
"eip3529Transition": 24114400,
"eip3541Transition": 24114400,
"eip1559Transition": 24114400,
"eip1559BaseFeeMaxChangeDenominator": "0x8",
"eip1559ElasticityMultiplier": "0x2",
"eip1559BaseFeeInitialValue": "0x3b9aca00",
"eip1559FeeCollector": "0xE8DDc5c7A2d2F0D7a9798459c0104fDf5E987ACA",
"eip1559FeeCollectorTransition": 24114400
},
"genesis": {
"seal": {

View File

@@ -1090,6 +1090,10 @@ impl BlockChainClient for TestBlockChainClient {
}
None
}
fn is_aura(&self) -> bool {
self.engine().name() == "AuthorityRound"
}
}
impl IoClient for TestBlockChainClient {

View File

@@ -416,6 +416,40 @@ pub trait BlockChainClient:
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
fn signing_chain_id(&self) -> Option<u64>;

View File

@@ -2760,6 +2760,127 @@ mod tests {
}
}
evm_test! {test_too_big_max_priority_fee_with_not_enough_cash: test_too_big_max_priority_fee_with_not_enough_cash_int}
fn test_too_big_max_priority_fee_with_not_enough_cash(factory: Factory) {
let keypair = Random.generate();
let max_priority_fee_per_gas /* 2**256 - 1 */ = U256::from(340282366920938463463374607431768211455u128)
* U256::from(340282366920938463463374607431768211455u128)
+ U256::from(340282366920938463463374607431768211455u128)
+ U256::from(340282366920938463463374607431768211455u128);
let t = TypedTransaction::EIP1559Transaction(EIP1559TransactionTx {
transaction: AccessListTx::new(
Transaction {
action: Action::Create,
value: U256::from(17),
data: "3331600055".from_hex().unwrap(),
gas: U256::from(100_000),
gas_price: max_priority_fee_per_gas,
nonce: U256::zero(),
},
vec![
(
H160::from_low_u64_be(10),
vec![H256::from_low_u64_be(102), H256::from_low_u64_be(103)],
),
(H160::from_low_u64_be(400), vec![]),
],
),
max_priority_fee_per_gas,
})
.sign(keypair.secret(), None);
let sender = t.sender();
let mut state = get_temp_state_with_factory(factory);
state
.add_balance(&sender, &U256::from(15000017), CleanupMode::NoEmpty)
.unwrap();
let mut info = EnvInfo::default();
info.gas_limit = U256::from(100_000);
info.base_fee = Some(U256::from(100));
let machine = make_london_machine(0);
let schedule = machine.schedule(info.number);
let res = {
let mut ex = Executive::new(&mut state, &info, &machine, &schedule);
let opts = TransactOptions::with_no_tracing();
ex.transact(&t, opts)
};
match res {
Err(ExecutionError::NotEnoughCash { required, got })
if required
== U512::from(max_priority_fee_per_gas) * U512::from(100_000)
+ U512::from(17)
&& got == U512::from(15000017) =>
{
()
}
_ => assert!(false, "Expected not enough cash error. {:?}", res),
}
}
evm_test! {test_too_big_max_priority_fee_with_less_max_fee_per_gas: test_too_big_max_priority_fee_with_less_max_fee_per_gas_int}
fn test_too_big_max_priority_fee_with_less_max_fee_per_gas(factory: Factory) {
let keypair = Random.generate();
let max_priority_fee_per_gas /* 2**256 - 1 */ = U256::from(340282366920938463463374607431768211455u128)
* U256::from(340282366920938463463374607431768211455u128)
+ U256::from(340282366920938463463374607431768211455u128)
+ U256::from(340282366920938463463374607431768211455u128);
let t = TypedTransaction::EIP1559Transaction(EIP1559TransactionTx {
transaction: AccessListTx::new(
Transaction {
action: Action::Create,
value: U256::from(17),
data: "3331600055".from_hex().unwrap(),
gas: U256::from(100_000),
gas_price: U256::from(150),
nonce: U256::zero(),
},
vec![
(
H160::from_low_u64_be(10),
vec![H256::from_low_u64_be(102), H256::from_low_u64_be(103)],
),
(H160::from_low_u64_be(400), vec![]),
],
),
max_priority_fee_per_gas,
})
.sign(keypair.secret(), None);
let sender = t.sender();
let mut state = get_temp_state_with_factory(factory);
state
.add_balance(&sender, &U256::from(15000017), CleanupMode::NoEmpty)
.unwrap();
let mut info = EnvInfo::default();
info.gas_limit = U256::from(100_000);
info.base_fee = Some(U256::from(100));
let machine = make_london_machine(0);
let schedule = machine.schedule(info.number);
let res = {
let mut ex = Executive::new(&mut state, &info, &machine, &schedule);
let opts = TransactOptions::with_no_tracing();
ex.transact(&t, opts)
};
match res {
Err(ExecutionError::TransactionMalformed(err))
if err.contains("maxPriorityFeePerGas higher than maxFeePerGas") =>
{
()
}
_ => assert!(
false,
"Expected maxPriorityFeePerGas higher than maxFeePerGas error. {:?}",
res
),
}
}
evm_test! {test_keccak: test_keccak_int}
fn test_keccak(factory: Factory) {
let code = "6064640fffffffff20600055".from_hex().unwrap();

View File

@@ -1006,6 +1006,14 @@ impl miner::MinerService for Miner {
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 {
self.params.read().gas_range_target.0 / 5
}

View File

@@ -260,6 +260,9 @@ pub trait MinerService: Send + Sync {
/// Suggested gas price.
fn sensible_gas_price(&self) -> U256;
/// Suggested max priority fee gas price
fn sensible_max_priority_fee(&self) -> U256;
/// Suggested gas limit.
fn sensible_gas_limit(&self) -> U256;

View File

@@ -504,7 +504,10 @@ mod test {
use super::{super::tests::*, *};
use blocks::SyncHeader;
use bytes::Bytes;
use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient};
use ethcore::{
client::{BlockChainClient, EachBlockWith, TestBlockChainClient},
spec::Spec,
};
use ethereum_types::H256;
use parking_lot::RwLock;
use rlp::{Rlp, RlpStream};
@@ -769,7 +772,7 @@ mod test {
#[test]
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 sync = dummy_sync_with_peer(H256::zero(), &client);
let ss = TestSnapshotService::new();

View File

@@ -634,10 +634,16 @@ impl TypedTransaction {
pub fn effective_gas_price(&self, block_base_fee: Option<U256>) -> U256 {
match self {
Self::EIP1559Transaction(tx) => min(
self.tx().gas_price,
tx.max_priority_fee_per_gas + block_base_fee.unwrap_or_default(),
),
Self::EIP1559Transaction(tx) => {
let (v2, overflow) = tx
.max_priority_fee_per_gas
.overflowing_add(block_base_fee.unwrap_or_default());
if overflow {
self.tx().gas_price
} else {
min(self.tx().gas_price, v2)
}
}
Self::AccessList(_) => self.tx().gas_price,
Self::Legacy(_) => self.tx().gas_price,
}
@@ -1337,4 +1343,41 @@ mod tests {
test_vector("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", "9bddad43f934d313c2b79ca28a432dd2b7281029");
test_vector("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", "3c24d7329e92f84f08556ceb6df1cdb0104ca49f");
}
#[test]
fn should_not_panic_on_effective_gas_price_overflow() {
use self::publickey::{Generator, Random};
let key = Random.generate();
let gas_price /* 2**256 - 1 */ = U256::from(340282366920938463463374607431768211455u128)
* U256::from(340282366920938463463374607431768211455u128)
+ U256::from(340282366920938463463374607431768211455u128)
+ U256::from(340282366920938463463374607431768211455u128);
let t = TypedTransaction::EIP1559Transaction(EIP1559TransactionTx {
transaction: AccessListTx::new(
Transaction {
action: Action::Create,
nonce: U256::from(42),
gas_price,
gas: U256::from(50_000),
value: U256::from(1),
data: b"Hello!".to_vec(),
},
vec![
(
H160::from_low_u64_be(10),
vec![H256::from_low_u64_be(102), H256::from_low_u64_be(103)],
),
(H160::from_low_u64_be(400), vec![]),
],
),
max_priority_fee_per_gas: gas_price,
})
.sign(&key.secret(), Some(69));
let result = t.transaction.effective_gas_price(Some(124.into()));
assert_eq!(
gas_price, result,
"Invalid effective gas price, when max_priority_fee_per_gas is U256::max"
);
}
}

View File

@@ -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.
pub fn gas(&self) -> U256 {
match self.transaction_type {
@@ -260,6 +283,7 @@ mod tests {
assert_eq!(view.nonce(), 0.into());
assert_eq!(view.gas_price(), 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.value(), 0xa.into());
assert_eq!(
@@ -285,6 +309,7 @@ mod tests {
let view = view!(TypedTransactionView, &rlp);
assert_eq!(view.nonce(), 0x1.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.value(), 0x0.into());
assert_eq!(view.data(), "".from_hex().unwrap());
@@ -306,6 +331,10 @@ mod tests {
assert_eq!(view.nonce(), 0x1.into());
assert_eq!(view.gas_price(), 0xa.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.value(), 0x0.into());
assert_eq!(view.data(), "".from_hex().unwrap());

View File

@@ -91,7 +91,10 @@ use ethcore::{client::BlockChainClient, miner::MinerService};
use ethereum_types::{Address, H256, H520, U256};
use ethkey::Password;
use hash::keccak;
use types::transaction::{PendingTransaction, SignedTransaction};
use types::{
transaction::{PendingTransaction, SignedTransaction},
BlockNumber,
};
use jsonrpc_core::{
futures::{future, Future, IntoFuture},
@@ -397,6 +400,24 @@ where
.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.
/// May need to resolve in the future to fetch things like gas price.
pub fn from_rpc<D>(

View File

@@ -273,6 +273,10 @@ where
}
}
pub fn eip1559_not_activated() -> Error {
unsupported("EIP-1559 is not activated", None)
}
pub fn not_enough_data() -> Error {
Error {
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),

View File

@@ -52,7 +52,7 @@ use v1::{
self,
block_import::is_major_importing,
deprecated::{self, DeprecationNotice},
dispatch::{default_gas_price, FullDispatcher},
dispatch::{default_gas_price, default_max_priority_fee_per_gas, FullDispatcher},
errors, fake_sign, limit_logs,
},
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(
&self,
mut block_count: U256,
@@ -805,8 +821,11 @@ where
gas_and_reward.push((
gas_used,
txs[i].effective_gas_price(base_fee)
- base_fee.unwrap_or_default(),
txs[i]
.effective_gas_price(base_fee)
.saturating_sub(
base_fee.unwrap_or_default(),
),
));
}
}

View File

@@ -19,7 +19,7 @@ use std::{env, sync::Arc};
use accounts::AccountProvider;
use ethcore::{
client::{BlockChainClient, ChainInfo, Client, ClientConfig, ImportBlock},
client::{BlockChainClient, ChainInfo, Client, ClientConfig, EvmTestClient, ImportBlock},
ethereum,
miner::Miner,
spec::{Genesis, Spec},
@@ -67,7 +67,7 @@ fn snapshot_service() -> Arc<TestSnapshotService> {
fn make_spec(chain: &BlockChain) -> Spec {
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();
spec.set_genesis_state(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]
fn eth_get_block_by_hash() {
let chain = extract_chain!("BlockchainTests/ValidBlocks/bcGasPricerTest/RPC_API_Test");

View File

@@ -359,6 +359,10 @@ impl MinerService for TestMinerService {
20_000_000_000u64.into()
}
fn sensible_max_priority_fee(&self) -> U256 {
2_000_000_000u64.into()
}
fn sensible_gas_limit(&self) -> U256 {
0x5208.into()
}

View File

@@ -23,7 +23,7 @@ use std::{
use accounts::AccountProvider;
use ethcore::{
client::{BlockChainClient, EachBlockWith, Executed, TestBlockChainClient},
client::{BlockChainClient, EachBlockWith, EvmTestClient, Executed, TestBlockChainClient},
miner::{self, MinerService},
};
use ethereum_types::{Address, Bloom, H160, H256, U256};
@@ -51,6 +51,12 @@ fn blockchain_client() -> Arc<TestBlockChainClient> {
Arc::new(client)
}
fn eip1559_blockchain_client() -> Arc<TestBlockChainClient> {
let spec = EvmTestClient::spec_from_json(&ethjson::spec::ForkSpec::London).unwrap();
let client = TestBlockChainClient::new_with_spec(spec);
Arc::new(client)
}
fn accounts_provider() -> Arc<AccountProvider> {
Arc::new(AccountProvider::transient_provider())
}
@@ -89,8 +95,25 @@ impl Default for EthTester {
impl EthTester {
pub fn new_with_options(options: EthClientOptions) -> Self {
let runtime = Runtime::with_thread_count(1);
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 ap = accounts_provider();
let ap2 = ap.clone();
@@ -126,11 +149,6 @@ impl EthTester {
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]
@@ -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]
fn rpc_eth_accounts() {
let tester = EthTester::default();

View File

@@ -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)]
mod eth;
#[cfg(test)]

View File

@@ -60,6 +60,10 @@ pub trait Eth {
#[rpc(name = "eth_gasPrice")]
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.
#[rpc(name = "eth_feeHistory")]
fn fee_history(&self, _: U256, _: BlockNumber, _: Option<Vec<f64>>)

View File

@@ -1,7 +1,7 @@
[package]
name = "parity-version"
# NOTE: this value is used for OpenEthereum version string (via env CARGO_PKG_VERSION)
version = "3.3.0"
version = "3.3.2"
authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs"

View File

@@ -203,11 +203,11 @@ impl ModexpPricer {
let (base_len, exp_len) = (base_len_u256.low_u64(), exp_len_u256.low_u64());
// read fist 32-byte word of the exponent.
let exp_low = if base_len + 96 >= input.len() as u64 {
let exp_low = if base_len.wrapping_add(96) >= input.len() as u64 {
U256::zero()
} else {
buf.iter_mut().for_each(|b| *b = 0);
let mut reader = input[(96 + base_len as usize)..].chain(io::repeat(0));
let mut reader = input[(base_len as usize).wrapping_add(96)..].chain(io::repeat(0));
let len = min(exp_len, 32) as usize;
reader
.read_exact(&mut buf[(32 - len)..])
@@ -1728,6 +1728,33 @@ mod tests {
native: EthereumBuiltin::from_str("modexp").unwrap(),
};
// test for potential base len overflow
{
let input = hex!(
"
00000000000000000000000000000000ffffffffffffffffffffffffffffffff
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
03
ff"
);
let expected_cost = U256::max_value();
assert_eq!(f.cost(&input[..], 0), expected_cost);
}
// another test for potential base len overflow
{
let input = hex!(
"
00000000000000000000000000000000ffffffffffffffffffffffffffffffff
0000000000000000000000000000000000000000000000000000000000000020
0000000000000000000000000000000000000000000000000000000000000020"
);
let expected_cost = U256::max_value();
assert_eq!(f.cost(&input[..], 0), expected_cost);
}
// test for potential gas cost multiplication overflow
{
let input = hex!("0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000003b27bafd00000000000000000000000000000000000000000000000000000000503c8ac3");
@@ -1840,6 +1867,38 @@ mod tests {
}
}
#[test]
fn modexp2565() {
let pricer = Modexp2565Pricer {};
// test for potential base len overflow
{
let input = hex!(
"
00000000000000000000000000000000ffffffffffffffffffffffffffffffff
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
03
ff"
);
let expected_cost = U256::max_value();
assert_eq!(pricer.cost(&input[..]), expected_cost);
}
// another test for potential base len overflow
{
let input = hex!(
"
00000000000000000000000000000000ffffffffffffffffffffffffffffffff
0000000000000000000000000000000000000000000000000000000000000020
0000000000000000000000000000000000000000000000000000000000000020"
);
let expected_cost = U256::max_value();
assert_eq!(pricer.cost(&input[..]), expected_cost);
}
}
#[test]
fn bn128_add() {
let f = Builtin {