Reduced gas cost for static calls made to precompiles EIP2046/1352 (#11583)
* Implemented eip2046 * Update ethcore/builtin/src/lib.rs Co-Authored-By: Wei Tang <accounts@that.world> * Update ethcore/builtin/src/lib.rs Co-Authored-By: Wei Tang <accounts@that.world> * Update ethcore/builtin/src/lib.rs Co-Authored-By: Andronik Ordian <write@reusable.software> * Update ethcore/builtin/src/lib.rs Co-Authored-By: Wei Tang <accounts@that.world> * move precompile address limit def to gasometer * use const instead lazy_static Co-authored-by: Wei Tang <accounts@that.world> Co-authored-by: Andronik Ordian <write@reusable.software>
This commit is contained in:
parent
5627f049a7
commit
c0920b30ee
@ -15,7 +15,7 @@
|
|||||||
// along with Open Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
// along with Open Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use ethereum_types::{BigEndianHash, U256};
|
use ethereum_types::{BigEndianHash, U256, H160, Address};
|
||||||
use super::u256_to_address;
|
use super::u256_to_address;
|
||||||
|
|
||||||
use {evm, vm};
|
use {evm, vm};
|
||||||
@ -31,6 +31,8 @@ macro_rules! overflowing {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PRECOMPILES_ADDRESS_LIMIT: Address = H160([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xff,0xff]);
|
||||||
|
|
||||||
enum Request<Cost: ::evm::CostType> {
|
enum Request<Cost: ::evm::CostType> {
|
||||||
Gas(Cost),
|
Gas(Cost),
|
||||||
GasMem(Cost, Cost),
|
GasMem(Cost, Cost),
|
||||||
@ -224,7 +226,7 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
|
|||||||
|
|
||||||
Request::GasMemProvide(gas, mem, Some(requested))
|
Request::GasMemProvide(gas, mem, Some(requested))
|
||||||
},
|
},
|
||||||
instructions::DELEGATECALL | instructions::STATICCALL => {
|
instructions::DELEGATECALL => {
|
||||||
let gas = Gas::from(schedule.call_gas);
|
let gas = Gas::from(schedule.call_gas);
|
||||||
let mem = cmp::max(
|
let mem = cmp::max(
|
||||||
mem_needed(stack.peek(4), stack.peek(5))?,
|
mem_needed(stack.peek(4), stack.peek(5))?,
|
||||||
@ -234,6 +236,23 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
|
|||||||
|
|
||||||
Request::GasMemProvide(gas, mem, Some(requested))
|
Request::GasMemProvide(gas, mem, Some(requested))
|
||||||
},
|
},
|
||||||
|
instructions::STATICCALL => {
|
||||||
|
let code_address = u256_to_address(stack.peek(1));
|
||||||
|
let gas = if code_address <= PRECOMPILES_ADDRESS_LIMIT {
|
||||||
|
Gas::from(schedule.staticcall_precompile_gas)
|
||||||
|
} else {
|
||||||
|
Gas::from(schedule.call_gas)
|
||||||
|
};
|
||||||
|
|
||||||
|
let mem = cmp::max(
|
||||||
|
mem_needed(stack.peek(4), stack.peek(5))?, // out_off, out_size
|
||||||
|
mem_needed(stack.peek(2), stack.peek(3))? // in_off, in_size
|
||||||
|
);
|
||||||
|
|
||||||
|
let requested = *stack.peek(0);
|
||||||
|
|
||||||
|
Request::GasMemProvide(gas, mem, Some(requested))
|
||||||
|
},
|
||||||
instructions::CREATE => {
|
instructions::CREATE => {
|
||||||
let start = stack.peek(1);
|
let start = stack.peek(1);
|
||||||
let len = stack.peek(2);
|
let len = stack.peek(2);
|
||||||
|
@ -55,6 +55,9 @@ pub fn new_constantinople_fix_test_machine() -> Machine { load_machine(include_b
|
|||||||
/// Create a new Foundation Istanbul era spec.
|
/// Create a new Foundation Istanbul era spec.
|
||||||
pub fn new_istanbul_test_machine() -> Machine { load_machine(include_bytes!("../../res/ethereum/istanbul_test.json")) }
|
pub fn new_istanbul_test_machine() -> Machine { load_machine(include_bytes!("../../res/ethereum/istanbul_test.json")) }
|
||||||
|
|
||||||
|
/// Create a new Foundation Berlin era spec.
|
||||||
|
pub fn new_berlin_test_machine() -> Machine { load_machine(include_bytes!("../../res/ethereum/berlin_test.json")) }
|
||||||
|
|
||||||
/// Create a new Musicoin-MCIP3-era spec.
|
/// Create a new Musicoin-MCIP3-era spec.
|
||||||
pub fn new_mcip3_test_machine() -> Machine { load_machine(include_bytes!("../../res/ethereum/mcip3_test.json")) }
|
pub fn new_mcip3_test_machine() -> Machine { load_machine(include_bytes!("../../res/ethereum/mcip3_test.json")) }
|
||||||
|
|
||||||
|
122
ethcore/res/ethereum/berlin_test.json
Normal file
122
ethcore/res/ethereum/berlin_test.json
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
{
|
||||||
|
"name": "Berlin (test)",
|
||||||
|
"engine": {
|
||||||
|
"Ethash": {
|
||||||
|
"params": {
|
||||||
|
"minimumDifficulty": "0x020000",
|
||||||
|
"difficultyBoundDivisor": "0x0800",
|
||||||
|
"durationLimit": "0x0d",
|
||||||
|
"blockReward": "0x1BC16D674EC80000",
|
||||||
|
"homesteadTransition": "0x0",
|
||||||
|
"eip100bTransition": "0x0",
|
||||||
|
"difficultyBombDelays": {
|
||||||
|
"0": 5000000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"gasLimitBoundDivisor": "0x0400",
|
||||||
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
|
"accountStartNonce": "0x00",
|
||||||
|
"maximumExtraDataSize": "0x20",
|
||||||
|
"minGasLimit": "0x1388",
|
||||||
|
"networkID" : "0x1",
|
||||||
|
"maxCodeSize": 24576,
|
||||||
|
"maxCodeSizeTransition": "0x0",
|
||||||
|
"eip150Transition": "0x0",
|
||||||
|
"eip160Transition": "0x0",
|
||||||
|
"eip161abcTransition": "0x0",
|
||||||
|
"eip161dTransition": "0x0",
|
||||||
|
"eip140Transition": "0x0",
|
||||||
|
"eip211Transition": "0x0",
|
||||||
|
"eip214Transition": "0x0",
|
||||||
|
"eip155Transition": "0x0",
|
||||||
|
"eip658Transition": "0x0",
|
||||||
|
"eip145Transition": "0x0",
|
||||||
|
"eip1014Transition": "0x0",
|
||||||
|
"eip1052Transition": "0x0",
|
||||||
|
"eip1283Transition": "0x0",
|
||||||
|
"eip1283DisableTransition": "0x0",
|
||||||
|
"eip1283ReenableTransition": "0x0",
|
||||||
|
"eip1344Transition": "0x0",
|
||||||
|
"eip1706Transition": "0x0",
|
||||||
|
"eip1884Transition": "0x0",
|
||||||
|
"eip2028Transition": "0x0",
|
||||||
|
"eip2046Transition": "0x0"
|
||||||
|
},
|
||||||
|
"genesis": {
|
||||||
|
"seal": {
|
||||||
|
"ethereum": {
|
||||||
|
"nonce": "0x0000000000000042",
|
||||||
|
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"difficulty": "0x400000000",
|
||||||
|
"author": "0x0000000000000000000000000000000000000000",
|
||||||
|
"timestamp": "0x00",
|
||||||
|
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
|
||||||
|
"gasLimit": "0x1388"
|
||||||
|
},
|
||||||
|
"accounts": {
|
||||||
|
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||||
|
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||||
|
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||||
|
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||||
|
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 20 } } } },
|
||||||
|
"0000000000000000000000000000000000000006": {
|
||||||
|
"builtin": {
|
||||||
|
"name": "alt_bn128_add",
|
||||||
|
"pricing": {
|
||||||
|
"0": {
|
||||||
|
"price": { "alt_bn128_const_operations": { "price": 500 }}
|
||||||
|
},
|
||||||
|
"0": {
|
||||||
|
"info": "EIP 1108 transition",
|
||||||
|
"price": { "alt_bn128_const_operations": { "price": 150 }}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000007": {
|
||||||
|
"builtin": {
|
||||||
|
"name": "alt_bn128_mul",
|
||||||
|
"pricing": {
|
||||||
|
"0": {
|
||||||
|
"price": { "alt_bn128_const_operations": { "price": 40000 }}
|
||||||
|
},
|
||||||
|
"0": {
|
||||||
|
"info": "EIP 1108 transition",
|
||||||
|
"price": { "alt_bn128_const_operations": { "price": 6000 }}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000008": {
|
||||||
|
"builtin": {
|
||||||
|
"name": "alt_bn128_pairing",
|
||||||
|
"pricing": {
|
||||||
|
"0": {
|
||||||
|
"price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }}
|
||||||
|
},
|
||||||
|
"0": {
|
||||||
|
"info": "EIP 1108 transition",
|
||||||
|
"price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 }}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000009": {
|
||||||
|
"builtin": {
|
||||||
|
"name": "blake2_f",
|
||||||
|
"activate_at": "0x00",
|
||||||
|
"pricing": {
|
||||||
|
"blake2_f": {
|
||||||
|
"gas_per_round": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
Subproject commit d4f86ecf4aa7c44a40bc0c972fd3e25d63ef5d92
|
Subproject commit 06acfb48aee71ecb57a9ca991cf0f57b630e3469
|
@ -91,6 +91,7 @@ bundle_test_spec! {
|
|||||||
"ethereum/byzantium_test" => new_byzantium_test,
|
"ethereum/byzantium_test" => new_byzantium_test,
|
||||||
"ethereum/constantinople_test" => new_constantinople_test,
|
"ethereum/constantinople_test" => new_constantinople_test,
|
||||||
"ethereum/istanbul_test" => new_istanbul_test,
|
"ethereum/istanbul_test" => new_istanbul_test,
|
||||||
|
"ethereum/berlin_test" => new_berlin_test,
|
||||||
"ethereum/eip150_test" => new_eip150_test,
|
"ethereum/eip150_test" => new_eip150_test,
|
||||||
"ethereum/eip161_test" => new_eip161_test,
|
"ethereum/eip161_test" => new_eip161_test,
|
||||||
"ethereum/eip210_test" => new_eip210_test,
|
"ethereum/eip210_test" => new_eip210_test,
|
||||||
@ -117,6 +118,7 @@ bundle_test_machine! {
|
|||||||
"ethereum/byzantium_test" => new_byzantium_test_machine,
|
"ethereum/byzantium_test" => new_byzantium_test_machine,
|
||||||
"ethereum/constantinople_test" => new_constantinople_test_machine,
|
"ethereum/constantinople_test" => new_constantinople_test_machine,
|
||||||
"ethereum/istanbul_test" => new_istanbul_test_machine,
|
"ethereum/istanbul_test" => new_istanbul_test_machine,
|
||||||
|
"ethereum/berlin_test" => new_berlin_test_machine,
|
||||||
"ethereum/eip210_test" => new_eip210_test_machine,
|
"ethereum/eip210_test" => new_eip210_test_machine,
|
||||||
"ethereum/frontier_test" => new_frontier_test_machine,
|
"ethereum/frontier_test" => new_frontier_test_machine,
|
||||||
"ethereum/homestead_test" => new_homestead_test_machine,
|
"ethereum/homestead_test" => new_homestead_test_machine,
|
||||||
|
@ -110,6 +110,7 @@ impl<'a> EvmTestClient<'a> {
|
|||||||
ForkSpec::Constantinople => Some(spec::new_constantinople_test()),
|
ForkSpec::Constantinople => Some(spec::new_constantinople_test()),
|
||||||
ForkSpec::ConstantinopleFix => Some(spec::new_constantinople_fix_test()),
|
ForkSpec::ConstantinopleFix => Some(spec::new_constantinople_fix_test()),
|
||||||
ForkSpec::Istanbul => Some(spec::new_istanbul_test()),
|
ForkSpec::Istanbul => Some(spec::new_istanbul_test()),
|
||||||
|
ForkSpec::Berlin => Some(spec::new_berlin_test()),
|
||||||
ForkSpec::EIP158ToByzantiumAt5 => Some(spec::new_transition_test()),
|
ForkSpec::EIP158ToByzantiumAt5 => Some(spec::new_transition_test()),
|
||||||
ForkSpec::FrontierToHomesteadAt5 | ForkSpec::HomesteadToDaoAt5 | ForkSpec::HomesteadToEIP150At5 => None,
|
ForkSpec::FrontierToHomesteadAt5 | ForkSpec::HomesteadToDaoAt5 | ForkSpec::HomesteadToEIP150At5 => None,
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,8 @@ pub struct CommonParams {
|
|||||||
pub eip1884_transition: BlockNumber,
|
pub eip1884_transition: BlockNumber,
|
||||||
/// Number of first block where EIP-2028 rules begin.
|
/// Number of first block where EIP-2028 rules begin.
|
||||||
pub eip2028_transition: BlockNumber,
|
pub eip2028_transition: BlockNumber,
|
||||||
|
/// Number of first block where EIP-2046/1352 rules begin.
|
||||||
|
pub eip2046_transition: BlockNumber,
|
||||||
/// Number of first block where EIP-2200 advance transition begin.
|
/// Number of first block where EIP-2200 advance transition begin.
|
||||||
pub eip2200_advance_transition: BlockNumber,
|
pub eip2200_advance_transition: BlockNumber,
|
||||||
/// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin.
|
/// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin.
|
||||||
@ -191,6 +193,9 @@ impl CommonParams {
|
|||||||
schedule.sload_gas = 800;
|
schedule.sload_gas = 800;
|
||||||
schedule.sstore_dirty_gas = Some(800);
|
schedule.sstore_dirty_gas = Some(800);
|
||||||
}
|
}
|
||||||
|
if block_number >= self.eip2046_transition {
|
||||||
|
schedule.staticcall_precompile_gas = 40;
|
||||||
|
}
|
||||||
if block_number >= self.eip210_transition {
|
if block_number >= self.eip210_transition {
|
||||||
schedule.blockhash_gas = 800;
|
schedule.blockhash_gas = 800;
|
||||||
}
|
}
|
||||||
@ -328,6 +333,10 @@ impl From<ethjson::spec::Params> for CommonParams {
|
|||||||
BlockNumber::max_value,
|
BlockNumber::max_value,
|
||||||
Into::into,
|
Into::into,
|
||||||
),
|
),
|
||||||
|
eip2046_transition: p.eip2046_transition.map_or_else(
|
||||||
|
BlockNumber::max_value,
|
||||||
|
Into::into,
|
||||||
|
),
|
||||||
eip2200_advance_transition: p.eip2200_advance_transition.map_or_else(
|
eip2200_advance_transition: p.eip2200_advance_transition.map_or_else(
|
||||||
BlockNumber::max_value,
|
BlockNumber::max_value,
|
||||||
Into::into,
|
Into::into,
|
||||||
|
@ -71,8 +71,10 @@ pub struct Schedule {
|
|||||||
pub log_topic_gas: usize,
|
pub log_topic_gas: usize,
|
||||||
/// Gas price for `CREATE` opcode
|
/// Gas price for `CREATE` opcode
|
||||||
pub create_gas: usize,
|
pub create_gas: usize,
|
||||||
/// Gas price for `*CALL*` opcodes
|
/// Gas price for `*CALL*` opcodes, EXCEPT for staticcall to precompiles
|
||||||
pub call_gas: usize,
|
pub call_gas: usize,
|
||||||
|
/// Gas price for staticcall to precompiles
|
||||||
|
pub staticcall_precompile_gas: usize,
|
||||||
/// Stipend for transfer for `CALL|CALLCODE` opcode when `value>0`
|
/// Stipend for transfer for `CALL|CALLCODE` opcode when `value>0`
|
||||||
pub call_stipend: usize,
|
pub call_stipend: usize,
|
||||||
/// Additional gas required for value transfer (`CALL|CALLCODE`)
|
/// Additional gas required for value transfer (`CALL|CALLCODE`)
|
||||||
@ -250,6 +252,7 @@ impl Schedule {
|
|||||||
log_topic_gas: 375,
|
log_topic_gas: 375,
|
||||||
create_gas: 32000,
|
create_gas: 32000,
|
||||||
call_gas: 700,
|
call_gas: 700,
|
||||||
|
staticcall_precompile_gas: 700,
|
||||||
call_stipend: 2300,
|
call_stipend: 2300,
|
||||||
call_value_transfer_gas: 9000,
|
call_value_transfer_gas: 9000,
|
||||||
call_new_account_gas: 25000,
|
call_new_account_gas: 25000,
|
||||||
@ -312,6 +315,13 @@ impl Schedule {
|
|||||||
schedule
|
schedule
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Schedule for the Berlin fork of the Ethereum main net.
|
||||||
|
pub fn new_berlin() -> Schedule {
|
||||||
|
let mut schedule = Self::new_istanbul();
|
||||||
|
schedule.staticcall_precompile_gas = 40; // EIPs 2046 1352
|
||||||
|
schedule
|
||||||
|
}
|
||||||
|
|
||||||
fn new(efcd: bool, hdc: bool, tcg: usize) -> Schedule {
|
fn new(efcd: bool, hdc: bool, tcg: usize) -> Schedule {
|
||||||
Schedule {
|
Schedule {
|
||||||
exceptional_failed_code_deposit: efcd,
|
exceptional_failed_code_deposit: efcd,
|
||||||
@ -341,6 +351,7 @@ impl Schedule {
|
|||||||
log_topic_gas: 375,
|
log_topic_gas: 375,
|
||||||
create_gas: 32000,
|
create_gas: 32000,
|
||||||
call_gas: 40,
|
call_gas: 40,
|
||||||
|
staticcall_precompile_gas: 40,
|
||||||
call_stipend: 2300,
|
call_stipend: 2300,
|
||||||
call_value_transfer_gas: 9000,
|
call_value_transfer_gas: 9000,
|
||||||
call_new_account_gas: 25000,
|
call_new_account_gas: 25000,
|
||||||
|
@ -107,6 +107,13 @@ impl FakeExt {
|
|||||||
ext
|
ext
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// New fake externalities with Berlin schedule rules
|
||||||
|
pub fn new_berlin() -> Self {
|
||||||
|
let mut ext = FakeExt::default();
|
||||||
|
ext.schedule = Schedule::new_berlin();
|
||||||
|
ext
|
||||||
|
}
|
||||||
|
|
||||||
/// Alter fake externalities to allow wasm
|
/// Alter fake externalities to allow wasm
|
||||||
pub fn with_wasm(mut self) -> Self {
|
pub fn with_wasm(mut self) -> Self {
|
||||||
self.schedule.wasm = Some(Default::default());
|
self.schedule.wasm = Some(Default::default());
|
||||||
|
@ -107,6 +107,8 @@ pub struct Params {
|
|||||||
/// See `CommonParams` docs.
|
/// See `CommonParams` docs.
|
||||||
pub eip2028_transition: Option<Uint>,
|
pub eip2028_transition: Option<Uint>,
|
||||||
/// See `CommonParams` docs.
|
/// See `CommonParams` docs.
|
||||||
|
pub eip2046_transition: Option<Uint>,
|
||||||
|
/// See `CommonParams` docs.
|
||||||
pub eip2200_advance_transition: Option<Uint>,
|
pub eip2200_advance_transition: Option<Uint>,
|
||||||
/// See `CommonParams` docs.
|
/// See `CommonParams` docs.
|
||||||
pub dust_protection_transition: Option<Uint>,
|
pub dust_protection_transition: Option<Uint>,
|
||||||
|
@ -38,8 +38,10 @@ pub enum ForkSpec {
|
|||||||
Constantinople,
|
Constantinople,
|
||||||
/// Constantinople transition test-net
|
/// Constantinople transition test-net
|
||||||
ConstantinopleFix,
|
ConstantinopleFix,
|
||||||
/// Istanbul (To be announced)
|
/// Istanbul (#9,069,000 2019-12-08)
|
||||||
Istanbul,
|
Istanbul,
|
||||||
|
/// Berlin (To be announced)
|
||||||
|
Berlin,
|
||||||
/// Byzantium transition test-net
|
/// Byzantium transition test-net
|
||||||
EIP158ToByzantiumAt5,
|
EIP158ToByzantiumAt5,
|
||||||
/// Homestead transition test-net
|
/// Homestead transition test-net
|
||||||
|
Loading…
Reference in New Issue
Block a user