Skip to content

Commit 3df9602

Browse files
birchmdJoshua J. Bouw
andauthored
Release 2.5.1. (#470)
* 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]>
1 parent 0c8db05 commit 3df9602

File tree

19 files changed

+548
-15
lines changed

19 files changed

+548
-15
lines changed

CHANGES.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [2.5.1] - 2022-03-16
11+
12+
### Fixes
13+
14+
- Fix for bug in checking address exists introduced in the v2.5.0 release by [@birchmd]. ([#469])
15+
16+
### Added
17+
18+
- New Aurora-only precompiles for checking the current and predecessor NEAR account IDs by [@birchmd]. ([#462])
19+
20+
[#462]: https://github.com/aurora-is-near/aurora-engine/pull/462
21+
[#469]: https://github.com/aurora-is-near/aurora-engine/pull/469
22+
1023
## [2.5.0] - 2022-03-09
1124

1225
### Changes
@@ -219,7 +232,8 @@ struct SubmitResult {
219232

220233
## [1.0.0] - 2021-05-12
221234

222-
[Unreleased]: https://github.com/aurora-is-near/aurora-engine/compare/2.5.0...develop
235+
[Unreleased]: https://github.com/aurora-is-near/aurora-engine/compare/2.5.1...develop
236+
[2.5.1]: https://github.com/aurora-is-near/aurora-engine/compare/2.5.0...2.5.1
223237
[2.5.0]: https://github.com/aurora-is-near/aurora-engine/compare/2.4.0...2.5.0
224238
[2.4.0]: https://github.com/aurora-is-near/aurora-engine/compare/2.3.0...2.4.0
225239
[2.3.0]: https://github.com/aurora-is-near/aurora-engine/compare/2.2.0...2.3.0

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,5 @@ members = [
4141
exclude = [
4242
"etc/state-migration-test",
4343
"etc/ft-receiver",
44+
"etc/benchmark-contract",
4445
]

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ documentation.
1515
Network | Contract ID | Chain ID | Version
1616
------- | ------------------- | ---------- | ------
1717
Mainnet | [`aurora`][Mainnet] | 1313161554 | 2.4.0
18-
Testnet | [`aurora`][Testnet] | 1313161555 | 2.5.0
19-
Local | `aurora.test.near` | 1313161556 | 2.5.0
18+
Testnet | [`aurora`][Testnet] | 1313161555 | 2.5.1
19+
Local | `aurora.test.near` | 1313161556 | 2.5.1
2020

2121
[Mainnet]: https://explorer.near.org/accounts/aurora
2222
[Testnet]: https://explorer.testnet.near.org/accounts/aurora

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.5.0
1+
2.5.1
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
use super::{EvmPrecompileResult, Precompile};
2+
use crate::prelude::types::{Address, EthGas};
3+
use crate::PrecompileOutput;
4+
use aurora_engine_types::account_id::AccountId;
5+
use evm::{Context, ExitError};
6+
7+
mod costs {
8+
use crate::prelude::types::EthGas;
9+
10+
// TODO(#51): Determine the correct amount of gas
11+
pub(super) const PREDECESSOR_ACCOUNT_GAS: EthGas = EthGas::new(0);
12+
// TODO(#51): Determine the correct amount of gas
13+
pub(super) const CURRENT_ACCOUNT_GAS: EthGas = EthGas::new(0);
14+
}
15+
16+
pub struct PredecessorAccount {
17+
predecessor_account_id: AccountId,
18+
}
19+
20+
impl PredecessorAccount {
21+
/// predecessor_account_id precompile address
22+
///
23+
/// Address: `0x723ffbaba940e75e7bf5f6d61dcbf8d9a4de0fd7`
24+
/// This address is computed as: `&keccak("predecessorAccountId")[12..]`
25+
pub const ADDRESS: Address =
26+
super::make_address(0x723ffbab, 0xa940e75e7bf5f6d61dcbf8d9a4de0fd7);
27+
28+
pub fn new(predecessor_account_id: AccountId) -> Self {
29+
Self {
30+
predecessor_account_id,
31+
}
32+
}
33+
}
34+
35+
impl Precompile for PredecessorAccount {
36+
fn required_gas(_input: &[u8]) -> Result<EthGas, ExitError> {
37+
Ok(costs::PREDECESSOR_ACCOUNT_GAS)
38+
}
39+
40+
fn run(
41+
&self,
42+
input: &[u8],
43+
target_gas: Option<EthGas>,
44+
_context: &Context,
45+
_is_static: bool,
46+
) -> EvmPrecompileResult {
47+
let cost = Self::required_gas(input)?;
48+
if let Some(target_gas) = target_gas {
49+
if cost > target_gas {
50+
return Err(ExitError::OutOfGas);
51+
}
52+
}
53+
54+
Ok(
55+
PrecompileOutput::without_logs(cost, self.predecessor_account_id.as_bytes().to_vec())
56+
.into(),
57+
)
58+
}
59+
}
60+
61+
pub struct CurrentAccount {
62+
current_account_id: AccountId,
63+
}
64+
65+
impl CurrentAccount {
66+
/// current_account_id precompile address
67+
///
68+
/// Address: `0xfefae79e4180eb0284f261205e3f8cea737aff56`
69+
/// This address is computed as: `&keccak("currentAccountId")[12..]`
70+
pub const ADDRESS: Address =
71+
super::make_address(0xfefae79e, 0x4180eb0284f261205e3f8cea737aff56);
72+
73+
pub fn new(current_account_id: AccountId) -> Self {
74+
Self { current_account_id }
75+
}
76+
}
77+
78+
impl Precompile for CurrentAccount {
79+
fn required_gas(_input: &[u8]) -> Result<EthGas, ExitError> {
80+
Ok(costs::PREDECESSOR_ACCOUNT_GAS)
81+
}
82+
83+
fn run(
84+
&self,
85+
input: &[u8],
86+
target_gas: Option<EthGas>,
87+
_context: &Context,
88+
_is_static: bool,
89+
) -> EvmPrecompileResult {
90+
let cost = Self::required_gas(input)?;
91+
if let Some(target_gas) = target_gas {
92+
if cost > target_gas {
93+
return Err(ExitError::OutOfGas);
94+
}
95+
}
96+
97+
Ok(
98+
PrecompileOutput::without_logs(cost, self.current_account_id.as_bytes().to_vec())
99+
.into(),
100+
)
101+
}
102+
}
103+
104+
#[cfg(test)]
105+
mod tests {
106+
use crate::account_ids::{CurrentAccount, PredecessorAccount};
107+
use crate::prelude::sdk::types::near_account_to_evm_address;
108+
109+
#[test]
110+
fn test_predecessor_account_precompile_id() {
111+
assert_eq!(
112+
PredecessorAccount::ADDRESS,
113+
near_account_to_evm_address("predecessorAccountId".as_bytes())
114+
);
115+
}
116+
117+
#[test]
118+
fn test_curent_account_precompile_id() {
119+
assert_eq!(
120+
CurrentAccount::ADDRESS,
121+
near_account_to_evm_address("currentAccountId".as_bytes())
122+
);
123+
}
124+
}

engine-precompiles/src/lib.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#![allow(dead_code)]
22
#![cfg_attr(not(feature = "std"), no_std)]
33
#![cfg_attr(not(feature = "std"), feature(alloc_error_handler))]
4-
#![cfg_attr(feature = "log", feature(panic_info_message))]
54

5+
pub mod account_ids;
66
pub mod blake2;
77
pub mod bn128;
88
pub mod hash;
@@ -15,6 +15,7 @@ pub mod secp256k1;
1515
#[cfg(test)]
1616
mod utils;
1717

18+
use crate::account_ids::{CurrentAccount, PredecessorAccount};
1819
use crate::blake2::Blake2F;
1920
use crate::bn128::{Bn128Add, Bn128Mul, Bn128Pair};
2021
use crate::hash::{RIPEMD160, SHA256};
@@ -125,6 +126,7 @@ impl executor::stack::PrecompileSet for Precompiles {
125126
pub struct PrecompileConstructorContext {
126127
pub current_account_id: AccountId,
127128
pub random_seed: H256,
129+
pub predecessor_account_id: AccountId,
128130
}
129131

130132
impl Precompiles {
@@ -137,14 +139,18 @@ impl Precompiles {
137139
ExitToNear::ADDRESS,
138140
ExitToEthereum::ADDRESS,
139141
RandomSeed::ADDRESS,
142+
CurrentAccount::ADDRESS,
143+
PredecessorAccount::ADDRESS,
140144
];
141145
let fun: prelude::Vec<Box<dyn Precompile>> = vec![
142146
Box::new(ECRecover),
143147
Box::new(SHA256),
144148
Box::new(RIPEMD160),
145149
Box::new(ExitToNear::new(ctx.current_account_id.clone())),
146-
Box::new(ExitToEthereum::new(ctx.current_account_id)),
150+
Box::new(ExitToEthereum::new(ctx.current_account_id.clone())),
147151
Box::new(RandomSeed::new(ctx.random_seed)),
152+
Box::new(CurrentAccount::new(ctx.current_account_id)),
153+
Box::new(PredecessorAccount::new(ctx.predecessor_account_id)),
148154
];
149155
let map: BTreeMap<Address, Box<dyn Precompile>> = addresses.into_iter().zip(fun).collect();
150156

@@ -165,6 +171,8 @@ impl Precompiles {
165171
ExitToNear::ADDRESS,
166172
ExitToEthereum::ADDRESS,
167173
RandomSeed::ADDRESS,
174+
CurrentAccount::ADDRESS,
175+
PredecessorAccount::ADDRESS,
168176
];
169177
let fun: prelude::Vec<Box<dyn Precompile>> = vec![
170178
Box::new(ECRecover),
@@ -176,8 +184,10 @@ impl Precompiles {
176184
Box::new(Bn128Mul::<Byzantium>::new()),
177185
Box::new(Bn128Pair::<Byzantium>::new()),
178186
Box::new(ExitToNear::new(ctx.current_account_id.clone())),
179-
Box::new(ExitToEthereum::new(ctx.current_account_id)),
187+
Box::new(ExitToEthereum::new(ctx.current_account_id.clone())),
180188
Box::new(RandomSeed::new(ctx.random_seed)),
189+
Box::new(CurrentAccount::new(ctx.current_account_id)),
190+
Box::new(PredecessorAccount::new(ctx.predecessor_account_id)),
181191
];
182192
let map: BTreeMap<Address, Box<dyn Precompile>> = addresses.into_iter().zip(fun).collect();
183193

@@ -198,6 +208,8 @@ impl Precompiles {
198208
ExitToNear::ADDRESS,
199209
ExitToEthereum::ADDRESS,
200210
RandomSeed::ADDRESS,
211+
CurrentAccount::ADDRESS,
212+
PredecessorAccount::ADDRESS,
201213
];
202214
let fun: prelude::Vec<Box<dyn Precompile>> = vec![
203215
Box::new(ECRecover),
@@ -210,8 +222,10 @@ impl Precompiles {
210222
Box::new(Bn128Pair::<Istanbul>::new()),
211223
Box::new(Blake2F),
212224
Box::new(ExitToNear::new(ctx.current_account_id.clone())),
213-
Box::new(ExitToEthereum::new(ctx.current_account_id)),
225+
Box::new(ExitToEthereum::new(ctx.current_account_id.clone())),
214226
Box::new(RandomSeed::new(ctx.random_seed)),
227+
Box::new(CurrentAccount::new(ctx.current_account_id)),
228+
Box::new(PredecessorAccount::new(ctx.predecessor_account_id)),
215229
];
216230
let map: BTreeMap<Address, Box<dyn Precompile>> = addresses.into_iter().zip(fun).collect();
217231

@@ -232,6 +246,8 @@ impl Precompiles {
232246
ExitToNear::ADDRESS,
233247
ExitToEthereum::ADDRESS,
234248
RandomSeed::ADDRESS,
249+
CurrentAccount::ADDRESS,
250+
PredecessorAccount::ADDRESS,
235251
];
236252
let fun: prelude::Vec<Box<dyn Precompile>> = vec![
237253
Box::new(ECRecover),
@@ -244,8 +260,10 @@ impl Precompiles {
244260
Box::new(Bn128Pair::<Istanbul>::new()),
245261
Box::new(Blake2F),
246262
Box::new(ExitToNear::new(ctx.current_account_id.clone())),
247-
Box::new(ExitToEthereum::new(ctx.current_account_id)),
263+
Box::new(ExitToEthereum::new(ctx.current_account_id.clone())),
248264
Box::new(RandomSeed::new(ctx.random_seed)),
265+
Box::new(CurrentAccount::new(ctx.current_account_id)),
266+
Box::new(PredecessorAccount::new(ctx.predecessor_account_id)),
249267
];
250268
let map: BTreeMap<Address, Box<dyn Precompile>> = addresses.into_iter().zip(fun).collect();
251269

engine-sdk/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![cfg_attr(not(feature = "std"), no_std)]
22
#![cfg_attr(not(feature = "std"), feature(alloc_error_handler))]
3-
#![cfg_attr(feature = "log", feature(panic_info_message))]
43

54
#[cfg(feature = "contract")]
65
use crate::prelude::Address;

engine-standalone-storage/src/sync/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,13 @@ pub fn consume_message(storage: &mut crate::Storage, message: Message) -> Result
139139
&promise_args.callback.args,
140140
)
141141
.expect("Connector deposit function must return valid args");
142+
// Since this would be executed as a callback, the predecessor_account_id
143+
// is now equal to the current_account_id
144+
let env = {
145+
let mut tmp = env.clone();
146+
tmp.predecessor_account_id = env.current_account_id;
147+
tmp
148+
};
142149
let maybe_promise_args = connector_contract.finish_deposit(
143150
env.predecessor_account_id(),
144151
env.current_account_id(),
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use crate::test_utils::{self, standalone};
2+
use aurora_engine::parameters::SubmitResult;
3+
4+
#[test]
5+
fn test_account_id_precompiles() {
6+
let mut signer = test_utils::Signer::random();
7+
let mut runner = test_utils::deploy_evm();
8+
let mut standalone = standalone::StandaloneRunner::default();
9+
10+
standalone.init_evm();
11+
runner.standalone_runner = Some(standalone);
12+
13+
let constructor = test_utils::solidity::ContractConstructor::compile_from_source(
14+
"src/tests/res",
15+
"target/solidity_build",
16+
"AccountIds.sol",
17+
"AccountIds",
18+
);
19+
20+
// deploy contract
21+
let nonce = signer.use_nonce();
22+
let contract = runner.deploy_contract(
23+
&signer.secret_key,
24+
|c| c.deploy_without_constructor(nonce.into()),
25+
constructor,
26+
);
27+
28+
// check current_account_id is correct
29+
let result = runner
30+
.submit_with_signer(&mut signer, |nonce| {
31+
contract.call_method_without_args("currentAccountId", nonce)
32+
})
33+
.unwrap();
34+
assert_eq!(unwrap_ethabi_string(&result), "aurora");
35+
36+
// check predecessor_account_id is correct
37+
let result = runner
38+
.submit_with_signer(&mut signer, |nonce| {
39+
contract.call_method_without_args("predecessorAccountId", nonce)
40+
})
41+
.unwrap();
42+
assert_eq!(unwrap_ethabi_string(&result), "some-account.near");
43+
44+
// double check the case where account_id is the full 64 bytes
45+
let account_id = "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789";
46+
assert_eq!(account_id.len(), 64);
47+
runner.standalone_runner.as_mut().unwrap().env.block_height += 1000;
48+
runner
49+
.standalone_runner
50+
.as_mut()
51+
.unwrap()
52+
.env
53+
.current_account_id = account_id.parse().unwrap();
54+
let nonce = signer.use_nonce();
55+
let tx = contract.call_method_without_args("currentAccountId", nonce.into());
56+
let result = runner
57+
.standalone_runner
58+
.as_mut()
59+
.unwrap()
60+
.submit_transaction(&signer.secret_key, tx)
61+
.unwrap();
62+
assert_eq!(unwrap_ethabi_string(&result), account_id);
63+
}
64+
65+
fn unwrap_ethabi_string(result: &SubmitResult) -> String {
66+
let bytes = test_utils::unwrap_success_slice(result);
67+
let mut tokens = ethabi::decode(&[ethabi::ParamType::String], &bytes).unwrap();
68+
tokens.pop().unwrap().into_string().unwrap()
69+
}

engine-tests/src/tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod access_lists;
2+
mod account_id_precompiles;
23
mod contract_call;
34
mod eip1559;
45
mod erc20;

0 commit comments

Comments
 (0)