Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f13fa10b8a | ||
|
|
657100cebc | ||
|
|
d2d19ec8c2 | ||
|
|
0f872aff78 | ||
|
|
405738c791 | ||
|
|
3b19a79c37 |
17
CHANGELOG.md
17
CHANGELOG.md
@@ -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
4
Cargo.lock
generated
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -1090,6 +1090,10 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn is_aura(&self) -> bool {
|
||||
self.engine().name() == "AuthorityRound"
|
||||
}
|
||||
}
|
||||
|
||||
impl IoClient for TestBlockChainClient {
|
||||
|
||||
@@ -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>;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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>(
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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(),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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(ðjson::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();
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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>>)
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user