Skip to content

Commit

Permalink
Release 2.5.1. (#470)
Browse files Browse the repository at this point in the history
* Feat(Engine): Precompiles for predecessor_account_id and current_account_id (#462)
* Implement a NEAR native version of the Solidity pure arithmetic benchmark to compare EVM execution cost with direct wasm cost (#463)
* Fix features related to panic_info_message (#466)
* Fix(standalone): set predecessor_account_id appropriately when executing promise callbacks (#467)
* Fix(engine): fix bug in checking if an address exists (#469)
* Version update
* Update unreleased link

Co-authored-by: Joshua J. Bouw <[email protected]>
  • Loading branch information
birchmd and Joshua J. Bouw authored Mar 22, 2022
1 parent 0c8db05 commit 3df9602
Show file tree
Hide file tree
Showing 19 changed files with 548 additions and 15 deletions.
16 changes: 15 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [2.5.1] - 2022-03-16

### Fixes

- Fix for bug in checking address exists introduced in the v2.5.0 release by [@birchmd]. ([#469])

### Added

- New Aurora-only precompiles for checking the current and predecessor NEAR account IDs by [@birchmd]. ([#462])

[#462]: https://github.com/aurora-is-near/aurora-engine/pull/462
[#469]: https://github.com/aurora-is-near/aurora-engine/pull/469

## [2.5.0] - 2022-03-09

### Changes
Expand Down Expand Up @@ -219,7 +232,8 @@ struct SubmitResult {

## [1.0.0] - 2021-05-12

[Unreleased]: https://github.com/aurora-is-near/aurora-engine/compare/2.5.0...develop
[Unreleased]: https://github.com/aurora-is-near/aurora-engine/compare/2.5.1...develop
[2.5.1]: https://github.com/aurora-is-near/aurora-engine/compare/2.5.0...2.5.1
[2.5.0]: https://github.com/aurora-is-near/aurora-engine/compare/2.4.0...2.5.0
[2.4.0]: https://github.com/aurora-is-near/aurora-engine/compare/2.3.0...2.4.0
[2.3.0]: https://github.com/aurora-is-near/aurora-engine/compare/2.2.0...2.3.0
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@ members = [
exclude = [
"etc/state-migration-test",
"etc/ft-receiver",
"etc/benchmark-contract",
]
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ documentation.
Network | Contract ID | Chain ID | Version
------- | ------------------- | ---------- | ------
Mainnet | [`aurora`][Mainnet] | 1313161554 | 2.4.0
Testnet | [`aurora`][Testnet] | 1313161555 | 2.5.0
Local | `aurora.test.near` | 1313161556 | 2.5.0
Testnet | [`aurora`][Testnet] | 1313161555 | 2.5.1
Local | `aurora.test.near` | 1313161556 | 2.5.1

[Mainnet]: https://explorer.near.org/accounts/aurora
[Testnet]: https://explorer.testnet.near.org/accounts/aurora
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.5.0
2.5.1
124 changes: 124 additions & 0 deletions engine-precompiles/src/account_ids.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
use super::{EvmPrecompileResult, Precompile};
use crate::prelude::types::{Address, EthGas};
use crate::PrecompileOutput;
use aurora_engine_types::account_id::AccountId;
use evm::{Context, ExitError};

mod costs {
use crate::prelude::types::EthGas;

// TODO(#51): Determine the correct amount of gas
pub(super) const PREDECESSOR_ACCOUNT_GAS: EthGas = EthGas::new(0);
// TODO(#51): Determine the correct amount of gas
pub(super) const CURRENT_ACCOUNT_GAS: EthGas = EthGas::new(0);
}

pub struct PredecessorAccount {
predecessor_account_id: AccountId,
}

impl PredecessorAccount {
/// predecessor_account_id precompile address
///
/// Address: `0x723ffbaba940e75e7bf5f6d61dcbf8d9a4de0fd7`
/// This address is computed as: `&keccak("predecessorAccountId")[12..]`
pub const ADDRESS: Address =
super::make_address(0x723ffbab, 0xa940e75e7bf5f6d61dcbf8d9a4de0fd7);

pub fn new(predecessor_account_id: AccountId) -> Self {
Self {
predecessor_account_id,
}
}
}

impl Precompile for PredecessorAccount {
fn required_gas(_input: &[u8]) -> Result<EthGas, ExitError> {
Ok(costs::PREDECESSOR_ACCOUNT_GAS)
}

fn run(
&self,
input: &[u8],
target_gas: Option<EthGas>,
_context: &Context,
_is_static: bool,
) -> EvmPrecompileResult {
let cost = Self::required_gas(input)?;
if let Some(target_gas) = target_gas {
if cost > target_gas {
return Err(ExitError::OutOfGas);
}
}

Ok(
PrecompileOutput::without_logs(cost, self.predecessor_account_id.as_bytes().to_vec())
.into(),
)
}
}

pub struct CurrentAccount {
current_account_id: AccountId,
}

impl CurrentAccount {
/// current_account_id precompile address
///
/// Address: `0xfefae79e4180eb0284f261205e3f8cea737aff56`
/// This address is computed as: `&keccak("currentAccountId")[12..]`
pub const ADDRESS: Address =
super::make_address(0xfefae79e, 0x4180eb0284f261205e3f8cea737aff56);

pub fn new(current_account_id: AccountId) -> Self {
Self { current_account_id }
}
}

impl Precompile for CurrentAccount {
fn required_gas(_input: &[u8]) -> Result<EthGas, ExitError> {
Ok(costs::PREDECESSOR_ACCOUNT_GAS)
}

fn run(
&self,
input: &[u8],
target_gas: Option<EthGas>,
_context: &Context,
_is_static: bool,
) -> EvmPrecompileResult {
let cost = Self::required_gas(input)?;
if let Some(target_gas) = target_gas {
if cost > target_gas {
return Err(ExitError::OutOfGas);
}
}

Ok(
PrecompileOutput::without_logs(cost, self.current_account_id.as_bytes().to_vec())
.into(),
)
}
}

#[cfg(test)]
mod tests {
use crate::account_ids::{CurrentAccount, PredecessorAccount};
use crate::prelude::sdk::types::near_account_to_evm_address;

#[test]
fn test_predecessor_account_precompile_id() {
assert_eq!(
PredecessorAccount::ADDRESS,
near_account_to_evm_address("predecessorAccountId".as_bytes())
);
}

#[test]
fn test_curent_account_precompile_id() {
assert_eq!(
CurrentAccount::ADDRESS,
near_account_to_evm_address("currentAccountId".as_bytes())
);
}
}
28 changes: 23 additions & 5 deletions engine-precompiles/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#![allow(dead_code)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc_error_handler))]
#![cfg_attr(feature = "log", feature(panic_info_message))]

pub mod account_ids;
pub mod blake2;
pub mod bn128;
pub mod hash;
Expand All @@ -15,6 +15,7 @@ pub mod secp256k1;
#[cfg(test)]
mod utils;

use crate::account_ids::{CurrentAccount, PredecessorAccount};
use crate::blake2::Blake2F;
use crate::bn128::{Bn128Add, Bn128Mul, Bn128Pair};
use crate::hash::{RIPEMD160, SHA256};
Expand Down Expand Up @@ -125,6 +126,7 @@ impl executor::stack::PrecompileSet for Precompiles {
pub struct PrecompileConstructorContext {
pub current_account_id: AccountId,
pub random_seed: H256,
pub predecessor_account_id: AccountId,
}

impl Precompiles {
Expand All @@ -137,14 +139,18 @@ impl Precompiles {
ExitToNear::ADDRESS,
ExitToEthereum::ADDRESS,
RandomSeed::ADDRESS,
CurrentAccount::ADDRESS,
PredecessorAccount::ADDRESS,
];
let fun: prelude::Vec<Box<dyn Precompile>> = vec![
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)),
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)),
];
let map: BTreeMap<Address, Box<dyn Precompile>> = addresses.into_iter().zip(fun).collect();

Expand All @@ -165,6 +171,8 @@ impl Precompiles {
ExitToNear::ADDRESS,
ExitToEthereum::ADDRESS,
RandomSeed::ADDRESS,
CurrentAccount::ADDRESS,
PredecessorAccount::ADDRESS,
];
let fun: prelude::Vec<Box<dyn Precompile>> = vec![
Box::new(ECRecover),
Expand All @@ -176,8 +184,10 @@ impl Precompiles {
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)),
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)),
];
let map: BTreeMap<Address, Box<dyn Precompile>> = addresses.into_iter().zip(fun).collect();

Expand All @@ -198,6 +208,8 @@ impl Precompiles {
ExitToNear::ADDRESS,
ExitToEthereum::ADDRESS,
RandomSeed::ADDRESS,
CurrentAccount::ADDRESS,
PredecessorAccount::ADDRESS,
];
let fun: prelude::Vec<Box<dyn Precompile>> = vec![
Box::new(ECRecover),
Expand All @@ -210,8 +222,10 @@ impl Precompiles {
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)),
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)),
];
let map: BTreeMap<Address, Box<dyn Precompile>> = addresses.into_iter().zip(fun).collect();

Expand All @@ -232,6 +246,8 @@ impl Precompiles {
ExitToNear::ADDRESS,
ExitToEthereum::ADDRESS,
RandomSeed::ADDRESS,
CurrentAccount::ADDRESS,
PredecessorAccount::ADDRESS,
];
let fun: prelude::Vec<Box<dyn Precompile>> = vec![
Box::new(ECRecover),
Expand All @@ -244,8 +260,10 @@ impl Precompiles {
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)),
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)),
];
let map: BTreeMap<Address, Box<dyn Precompile>> = addresses.into_iter().zip(fun).collect();

Expand Down
1 change: 0 additions & 1 deletion engine-sdk/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc_error_handler))]
#![cfg_attr(feature = "log", feature(panic_info_message))]

#[cfg(feature = "contract")]
use crate::prelude::Address;
Expand Down
7 changes: 7 additions & 0 deletions engine-standalone-storage/src/sync/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ pub fn consume_message(storage: &mut crate::Storage, message: Message) -> Result
&promise_args.callback.args,
)
.expect("Connector deposit function must return valid args");
// Since this would be executed as a callback, the predecessor_account_id
// is now equal to the current_account_id
let env = {
let mut tmp = env.clone();
tmp.predecessor_account_id = env.current_account_id;
tmp
};
let maybe_promise_args = connector_contract.finish_deposit(
env.predecessor_account_id(),
env.current_account_id(),
Expand Down
69 changes: 69 additions & 0 deletions engine-tests/src/tests/account_id_precompiles.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use crate::test_utils::{self, standalone};
use aurora_engine::parameters::SubmitResult;

#[test]
fn test_account_id_precompiles() {
let mut signer = test_utils::Signer::random();
let mut runner = test_utils::deploy_evm();
let mut standalone = standalone::StandaloneRunner::default();

standalone.init_evm();
runner.standalone_runner = Some(standalone);

let constructor = test_utils::solidity::ContractConstructor::compile_from_source(
"src/tests/res",
"target/solidity_build",
"AccountIds.sol",
"AccountIds",
);

// deploy contract
let nonce = signer.use_nonce();
let contract = runner.deploy_contract(
&signer.secret_key,
|c| c.deploy_without_constructor(nonce.into()),
constructor,
);

// check current_account_id is correct
let result = runner
.submit_with_signer(&mut signer, |nonce| {
contract.call_method_without_args("currentAccountId", nonce)
})
.unwrap();
assert_eq!(unwrap_ethabi_string(&result), "aurora");

// check predecessor_account_id is correct
let result = runner
.submit_with_signer(&mut signer, |nonce| {
contract.call_method_without_args("predecessorAccountId", nonce)
})
.unwrap();
assert_eq!(unwrap_ethabi_string(&result), "some-account.near");

// double check the case where account_id is the full 64 bytes
let account_id = "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789";
assert_eq!(account_id.len(), 64);
runner.standalone_runner.as_mut().unwrap().env.block_height += 1000;
runner
.standalone_runner
.as_mut()
.unwrap()
.env
.current_account_id = account_id.parse().unwrap();
let nonce = signer.use_nonce();
let tx = contract.call_method_without_args("currentAccountId", nonce.into());
let result = runner
.standalone_runner
.as_mut()
.unwrap()
.submit_transaction(&signer.secret_key, tx)
.unwrap();
assert_eq!(unwrap_ethabi_string(&result), account_id);
}

fn unwrap_ethabi_string(result: &SubmitResult) -> String {
let bytes = test_utils::unwrap_success_slice(result);
let mut tokens = ethabi::decode(&[ethabi::ParamType::String], &bytes).unwrap();
tokens.pop().unwrap().into_string().unwrap()
}
1 change: 1 addition & 0 deletions engine-tests/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod access_lists;
mod account_id_precompiles;
mod contract_call;
mod eip1559;
mod erc20;
Expand Down
2 changes: 1 addition & 1 deletion engine-tests/src/tests/repro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ fn repro_GdASJ3KESs() {
SubmitResult::try_from_slice(&outcome.return_data.as_value().unwrap()).unwrap();

assert_eq!(submit_result.gas_used, 706713);
assert_eq!(238, profile.all_gas() / 1_000_000_000_000);
assert_eq!(239, profile.all_gas() / 1_000_000_000_000);

// Also validate the SubmitResult in the standalone engine
let mut standalone = standalone::StandaloneRunner::default();
Expand Down
Loading

0 comments on commit 3df9602

Please sign in to comment.