Skip to content

Commit

Permalink
Fix(precompiles): Allow native precompiles to work in the standalone …
Browse files Browse the repository at this point in the history
…engine (#473)
  • Loading branch information
birchmd committed Apr 27, 2022
1 parent 81fbdc5 commit dbdd2f4
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 120 deletions.
103 changes: 62 additions & 41 deletions engine-precompiles/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ use crate::bn128::{Bn128Add, Bn128Mul, Bn128Pair};
use crate::hash::{RIPEMD160, SHA256};
use crate::identity::Identity;
use crate::modexp::ModExp;
use crate::native::{ExitToEthereum, ExitToNear};
use crate::native::{exit_to_ethereum, exit_to_near, ExitToEthereum, ExitToNear};
use crate::prelude::types::EthGas;
use crate::prelude::{Vec, H160, H256};
use crate::random::RandomSeed;
use crate::secp256k1::ECRecover;
use aurora_engine_sdk::io::IO;
use aurora_engine_types::{account_id::AccountId, types::Address, vec, BTreeMap, Box};
use evm::backend::Log;
use evm::executor;
Expand Down Expand Up @@ -101,9 +102,15 @@ impl HardFork for Istanbul {}

impl HardFork for Berlin {}

pub struct Precompiles(pub prelude::BTreeMap<Address, Box<dyn Precompile>>);
pub struct Precompiles<I> {
pub generic_precompiles: prelude::BTreeMap<Address, Box<dyn Precompile>>,
// Cannot be part of the generic precompiles because the `dyn` type-erasure messes with
// with the lifetime requirements on the type parameter `I`.
pub near_exit: ExitToNear<I>,
pub ethereum_exit: ExitToEthereum<I>,
}

impl executor::stack::PrecompileSet for Precompiles {
impl<I: IO + Copy> executor::stack::PrecompileSet for Precompiles<I> {
fn execute(
&self,
address: prelude::H160,
Expand All @@ -112,32 +119,32 @@ impl executor::stack::PrecompileSet for Precompiles {
context: &Context,
is_static: bool,
) -> Option<Result<executor::stack::PrecompileOutput, executor::stack::PrecompileFailure>> {
self.0.get(&Address::new(address)).map(|p| {
self.precompile_action(Address::new(address), |p| {
p.run(input, gas_limit.map(EthGas::new), context, is_static)
.map_err(|exit_status| executor::stack::PrecompileFailure::Error { exit_status })
})
}

fn is_precompile(&self, address: prelude::H160) -> bool {
self.0.contains_key(&Address::new(address))
self.precompile_action(Address::new(address), |_| true)
.unwrap_or(false)
}
}

pub struct PrecompileConstructorContext {
pub struct PrecompileConstructorContext<I> {
pub current_account_id: AccountId,
pub random_seed: H256,
pub predecessor_account_id: AccountId,
pub io: I,
}

impl Precompiles {
impl<I: IO + Copy> Precompiles<I> {
#[allow(dead_code)]
pub fn new_homestead(ctx: PrecompileConstructorContext) -> Self {
pub fn new_homestead(ctx: PrecompileConstructorContext<I>) -> Self {
let addresses = vec![
ECRecover::ADDRESS,
SHA256::ADDRESS,
RIPEMD160::ADDRESS,
ExitToNear::ADDRESS,
ExitToEthereum::ADDRESS,
RandomSeed::ADDRESS,
CurrentAccount::ADDRESS,
PredecessorAccount::ADDRESS,
Expand All @@ -146,19 +153,16 @@ impl Precompiles {
Box::new(ECRecover),
Box::new(SHA256),
Box::new(RIPEMD160),
Box::new(ExitToNear::new(ctx.current_account_id.clone())),
Box::new(ExitToEthereum::new(ctx.current_account_id.clone())),
Box::new(RandomSeed::new(ctx.random_seed)),
Box::new(CurrentAccount::new(ctx.current_account_id)),
Box::new(PredecessorAccount::new(ctx.predecessor_account_id)),
Box::new(CurrentAccount::new(ctx.current_account_id.clone())),
Box::new(PredecessorAccount::new(ctx.predecessor_account_id.clone())),
];
let map: BTreeMap<Address, Box<dyn Precompile>> = addresses.into_iter().zip(fun).collect();

Precompiles(map)
Self::with_generic_precompiles(map, ctx)
}

#[allow(dead_code)]
pub fn new_byzantium(ctx: PrecompileConstructorContext) -> Self {
pub fn new_byzantium(ctx: PrecompileConstructorContext<I>) -> Self {
let addresses = vec![
ECRecover::ADDRESS,
SHA256::ADDRESS,
Expand All @@ -168,8 +172,6 @@ impl Precompiles {
Bn128Add::<Byzantium>::ADDRESS,
Bn128Mul::<Byzantium>::ADDRESS,
Bn128Pair::<Byzantium>::ADDRESS,
ExitToNear::ADDRESS,
ExitToEthereum::ADDRESS,
RandomSeed::ADDRESS,
CurrentAccount::ADDRESS,
PredecessorAccount::ADDRESS,
Expand All @@ -183,18 +185,16 @@ impl Precompiles {
Box::new(Bn128Add::<Byzantium>::new()),
Box::new(Bn128Mul::<Byzantium>::new()),
Box::new(Bn128Pair::<Byzantium>::new()),
Box::new(ExitToNear::new(ctx.current_account_id.clone())),
Box::new(ExitToEthereum::new(ctx.current_account_id.clone())),
Box::new(RandomSeed::new(ctx.random_seed)),
Box::new(CurrentAccount::new(ctx.current_account_id)),
Box::new(PredecessorAccount::new(ctx.predecessor_account_id)),
Box::new(CurrentAccount::new(ctx.current_account_id.clone())),
Box::new(PredecessorAccount::new(ctx.predecessor_account_id.clone())),
];
let map: BTreeMap<Address, Box<dyn Precompile>> = addresses.into_iter().zip(fun).collect();

Precompiles(map)
Self::with_generic_precompiles(map, ctx)
}

pub fn new_istanbul(ctx: PrecompileConstructorContext) -> Self {
pub fn new_istanbul(ctx: PrecompileConstructorContext<I>) -> Self {
let addresses = vec![
ECRecover::ADDRESS,
SHA256::ADDRESS,
Expand All @@ -205,8 +205,6 @@ impl Precompiles {
Bn128Mul::<Istanbul>::ADDRESS,
Bn128Pair::<Istanbul>::ADDRESS,
Blake2F::ADDRESS,
ExitToNear::ADDRESS,
ExitToEthereum::ADDRESS,
RandomSeed::ADDRESS,
CurrentAccount::ADDRESS,
PredecessorAccount::ADDRESS,
Expand All @@ -221,18 +219,16 @@ impl Precompiles {
Box::new(Bn128Mul::<Istanbul>::new()),
Box::new(Bn128Pair::<Istanbul>::new()),
Box::new(Blake2F),
Box::new(ExitToNear::new(ctx.current_account_id.clone())),
Box::new(ExitToEthereum::new(ctx.current_account_id.clone())),
Box::new(RandomSeed::new(ctx.random_seed)),
Box::new(CurrentAccount::new(ctx.current_account_id)),
Box::new(PredecessorAccount::new(ctx.predecessor_account_id)),
Box::new(CurrentAccount::new(ctx.current_account_id.clone())),
Box::new(PredecessorAccount::new(ctx.predecessor_account_id.clone())),
];
let map: BTreeMap<Address, Box<dyn Precompile>> = addresses.into_iter().zip(fun).collect();

Precompiles(map)
Self::with_generic_precompiles(map, ctx)
}

pub fn new_berlin(ctx: PrecompileConstructorContext) -> Self {
pub fn new_berlin(ctx: PrecompileConstructorContext<I>) -> Self {
let addresses = vec![
ECRecover::ADDRESS,
SHA256::ADDRESS,
Expand All @@ -243,8 +239,6 @@ impl Precompiles {
Bn128Mul::<Istanbul>::ADDRESS,
Bn128Pair::<Istanbul>::ADDRESS,
Blake2F::ADDRESS,
ExitToNear::ADDRESS,
ExitToEthereum::ADDRESS,
RandomSeed::ADDRESS,
CurrentAccount::ADDRESS,
PredecessorAccount::ADDRESS,
Expand All @@ -259,21 +253,48 @@ impl Precompiles {
Box::new(Bn128Mul::<Istanbul>::new()),
Box::new(Bn128Pair::<Istanbul>::new()),
Box::new(Blake2F),
Box::new(ExitToNear::new(ctx.current_account_id.clone())),
Box::new(ExitToEthereum::new(ctx.current_account_id.clone())),
Box::new(RandomSeed::new(ctx.random_seed)),
Box::new(CurrentAccount::new(ctx.current_account_id)),
Box::new(PredecessorAccount::new(ctx.predecessor_account_id)),
Box::new(CurrentAccount::new(ctx.current_account_id.clone())),
Box::new(PredecessorAccount::new(ctx.predecessor_account_id.clone())),
];
let map: BTreeMap<Address, Box<dyn Precompile>> = addresses.into_iter().zip(fun).collect();

Precompiles(map)
Self::with_generic_precompiles(map, ctx)
}

pub fn new_london(ctx: PrecompileConstructorContext) -> Self {
pub fn new_london(ctx: PrecompileConstructorContext<I>) -> Self {
// no precompile changes in London HF
Self::new_berlin(ctx)
}

fn with_generic_precompiles(
generic_precompiles: BTreeMap<Address, Box<dyn Precompile>>,
ctx: PrecompileConstructorContext<I>,
) -> Self {
let near_exit = ExitToNear::new(ctx.current_account_id.clone(), ctx.io);
let ethereum_exit = ExitToEthereum::new(ctx.current_account_id, ctx.io);

Self {
generic_precompiles,
near_exit,
ethereum_exit,
}
}

fn precompile_action<U, F: FnOnce(&dyn Precompile) -> U>(
&self,
address: Address,
f: F,
) -> Option<U> {
if address == exit_to_near::ADDRESS {
return Some(f(&self.near_exit));
} else if address == exit_to_ethereum::ADDRESS {
return Some(f(&self.ethereum_exit));
}
self.generic_precompiles
.get(&address)
.map(|p| f(p.as_ref()))
}
}

/// fn for making an address by concatenating the bytes from two given numbers,
Expand Down
Loading

0 comments on commit dbdd2f4

Please sign in to comment.