Skip to content

Commit e40acc4

Browse files
committed
Bump version to v3.0.0
2 parents da5a313 + f5ed625 commit e40acc4

9 files changed

Lines changed: 140 additions & 6 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ members = [
88
[workspace.package]
99
authors = ["Aurora Labs <hello@aurora.dev>"]
1010
edition = "2021"
11-
version = "2.2.1"
11+
version = "3.0.0"
1212
description = "Aurora Ethereum Virtual Machine implementation written in pure Rust"
1313
categories = ["no-std", "compilers", "cryptography::cryptocurrencies"]
1414
keywords = ["aurora-evm", "evm", "ethereum", "blockchain", "no_std"]

evm-tests/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ pedantic = { level = "deny", priority = -1 }
1515
nursery = { level = "deny", priority = -1 }
1616

1717
[dependencies]
18-
aurora-engine-modexp = { git = "https://github.com/aurora-is-near/aurora-engine.git", tag = "3.10.0-rc.1" }
19-
aurora-engine-precompiles = { git = "https://github.com/aurora-is-near/aurora-engine.git", tag = "3.10.0-rc.1" }
18+
aurora-engine-precompiles = "2.1.0"
2019
aurora-evm.workspace = true
2120
bytecount = "0.6"
2221
clap = { version = "4.5", features = ["cargo"] }

evm-tests/src/precompiles.rs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ mod kzg;
22

33
use crate::precompiles::kzg::Kzg;
44
use crate::types::Spec;
5-
use aurora_engine_modexp::AuroraModExp;
5+
use aurora_engine_precompiles::modexp::AuroraModExp;
66
use aurora_engine_precompiles::{
77
alt_bn256::{Bn256Add, Bn256Mul, Bn256Pair},
88
blake2::Blake2F,
@@ -13,7 +13,7 @@ use aurora_engine_precompiles::{
1313
identity::Identity,
1414
modexp::ModExp,
1515
secp256k1::ECRecover,
16-
Berlin, Byzantium, EthGas, Istanbul, Precompile,
16+
Berlin, Byzantium, EthGas, Istanbul, Osaka, Precompile,
1717
};
1818
use aurora_evm::executor::stack::{
1919
PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileSet,
@@ -52,7 +52,8 @@ impl Precompiles {
5252
| Spec::Istanbul => Self::new_istanbul(),
5353
Spec::Berlin | Spec::London | Spec::Merge | Spec::Shanghai => Self::new_berlin(),
5454
Spec::Cancun => Self::new_cancun(),
55-
Spec::Prague | Spec::Osaka => Self::new_prague(),
55+
Spec::Prague => Self::new_prague(),
56+
Spec::Osaka => Self::new_osaka(),
5657
}
5758
}
5859

@@ -131,6 +132,44 @@ impl Precompiles {
131132
map.insert(BlsMapFp2ToG2::ADDRESS.raw(), Box::new(BlsMapFp2ToG2));
132133
Self(map)
133134
}
135+
136+
pub fn new_osaka() -> Self {
137+
let mut map = BTreeMap::new();
138+
map.insert(
139+
ECRecover::ADDRESS.raw(),
140+
Box::new(ECRecover) as Box<dyn Precompile>,
141+
);
142+
map.insert(SHA256::ADDRESS.raw(), Box::new(SHA256));
143+
map.insert(RIPEMD160::ADDRESS.raw(), Box::new(RIPEMD160));
144+
map.insert(Identity::ADDRESS.raw(), Box::new(Identity));
145+
map.insert(
146+
ModExp::<Osaka, AuroraModExp>::ADDRESS.raw(),
147+
Box::new(ModExp::<Osaka, AuroraModExp>::new()),
148+
);
149+
map.insert(
150+
Bn256Add::<Istanbul>::ADDRESS.raw(),
151+
Box::new(Bn256Add::<Istanbul>::new()),
152+
);
153+
map.insert(
154+
Bn256Mul::<Istanbul>::ADDRESS.raw(),
155+
Box::new(Bn256Mul::<Istanbul>::new()),
156+
);
157+
map.insert(
158+
Bn256Pair::<Istanbul>::ADDRESS.raw(),
159+
Box::new(Bn256Pair::<Istanbul>::new()),
160+
);
161+
map.insert(Blake2F::ADDRESS.raw(), Box::new(Blake2F));
162+
163+
map.insert(Kzg::ADDRESS, Box::new(Kzg));
164+
map.insert(BlsG1Add::ADDRESS.raw(), Box::new(BlsG1Add));
165+
map.insert(BlsG1Msm::ADDRESS.raw(), Box::new(BlsG1Msm));
166+
map.insert(BlsG2Add::ADDRESS.raw(), Box::new(BlsG2Add));
167+
map.insert(BlsG2Msm::ADDRESS.raw(), Box::new(BlsG2Msm));
168+
map.insert(BlsPairingCheck::ADDRESS.raw(), Box::new(BlsPairingCheck));
169+
map.insert(BlsMapFpToG1::ADDRESS.raw(), Box::new(BlsMapFpToG1));
170+
map.insert(BlsMapFp2ToG2::ADDRESS.raw(), Box::new(BlsMapFp2ToG2));
171+
Self(map)
172+
}
134173
}
135174

136175
/// Precompile input and output data struct

evm-tests/src/types/spec.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ impl Spec {
7979
Self::Shanghai => Some(Config::shanghai()),
8080
Self::Cancun => Some(Config::cancun()),
8181
Self::Prague => Some(Config::prague()),
82+
Self::Osaka => Some(Config::osaka()),
8283
_ => None,
8384
}
8485
}

evm/src/core/eval/bitwise.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,68 @@ pub fn sar(shift: U256, value: U256) -> U256 {
9797
}
9898
}
9999
}
100+
101+
/// EIP-7939: CLZ - Count Leading Zeros. Osaka hard fork.
102+
#[inline]
103+
pub fn clz(op1: U256) -> U256 {
104+
U256::from(op1.leading_zeros())
105+
}
106+
107+
#[cfg(test)]
108+
mod tests {
109+
use super::*;
110+
111+
#[allow(clippy::cognitive_complexity)]
112+
#[test]
113+
fn test_clz() {
114+
// Zero case (EIP spec: returns 256)
115+
assert_eq!(clz(U256::zero()), U256::from(256));
116+
117+
// Max value and MSB cases
118+
assert_eq!(clz(U256::MAX), U256::zero());
119+
assert_eq!(clz(U256::one() << 255), U256::zero());
120+
assert_eq!(clz((U256::one() << 255) | U256::one()), U256::zero());
121+
122+
// High bit boundaries
123+
assert_eq!(clz(U256::one() << 254), U256::from(1));
124+
assert_eq!(clz((U256::one() << 255) - U256::one()), U256::from(1)); // 0x7FFFF...
125+
assert_eq!(clz(U256::MAX >> 1), U256::from(1));
126+
127+
// Random high shifts
128+
assert_eq!(clz(U256::one() << 250), U256::from(5));
129+
130+
// 192 bit boundary (Transition from word[3] to word[2])
131+
assert_eq!(clz(U256::one() << 192), U256::from(63));
132+
assert_eq!(clz(U256::one() << 191), U256::from(64));
133+
assert_eq!(clz(U256::from(u64::MAX)), U256::from(192)); // Only lowest 64 bits set
134+
135+
// 128 bit boundary (Transition from word[2] to word[1])
136+
assert_eq!(clz(U256::one() << 128), U256::from(127));
137+
assert_eq!(clz(U256::one() << 127), U256::from(128));
138+
assert_eq!(clz(U256::from(u128::MAX)), U256::from(128));
139+
assert_eq!(clz(U256::MAX >> 128), U256::from(128));
140+
141+
// 64 bit boundary (Transition from word[1] to word[0])
142+
assert_eq!(clz(U256::one() << 64), U256::from(191));
143+
assert_eq!(clz(U256::one() << 63), U256::from(192));
144+
145+
// Small numbers and masks
146+
assert_eq!(clz(U256::from(0xFFFF)), U256::from(240));
147+
assert_eq!(clz(U256::from(0x100)), U256::from(247));
148+
assert_eq!(clz(U256::from(0xFF)), U256::from(248));
149+
150+
// Low bit shifts
151+
assert_eq!(clz(U256::one() << 20), U256::from(235));
152+
assert_eq!(clz(U256::one() << 10), U256::from(245));
153+
154+
// Very small numbers
155+
assert_eq!(clz(U256::from(16)), U256::from(251));
156+
assert_eq!(clz(U256::from(15)), U256::from(252));
157+
assert_eq!(clz(U256::from(8)), U256::from(252));
158+
assert_eq!(clz(U256::from(7)), U256::from(253));
159+
assert_eq!(clz(U256::from(4)), U256::from(253));
160+
assert_eq!(clz(U256::from(3)), U256::from(254));
161+
assert_eq!(clz(U256::from(2)), U256::from(254));
162+
assert_eq!(clz(U256::from(1)), U256::from(255));
163+
}
164+
}

evm/src/core/eval/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ fn eval_table<H: InterpreterHandler>(
8383
table_elem!(SHL, state, op2_u256_fn!(state, self::bitwise::shl));
8484
table_elem!(SHR, state, op2_u256_fn!(state, self::bitwise::shr));
8585
table_elem!(SAR, state, op2_u256_fn!(state, self::bitwise::sar));
86+
table_elem!(CLZ, state, op1_u256_fn!(state, self::bitwise::clz));
8687
table_elem!(POP, state, self::misc::pop(state));
8788
table_elem!(PC, state, position, self::misc::pc(state, position));
8889
table_elem!(MSIZE, state, self::misc::msize(state));

evm/src/core/opcode.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ impl Opcode {
6565
pub const SHR: Opcode = Opcode(0x1c);
6666
/// `SAR`
6767
pub const SAR: Opcode = Opcode(0x1d);
68+
/// `CLZ`: EIP-7939 Osaka hard fork
69+
pub const CLZ: Opcode = Opcode(0x1e);
6870

6971
/// `SHA3`
7072
pub const SHA3: Opcode = Opcode(0x20);
@@ -360,6 +362,7 @@ impl Display for Opcode {
360362
Self::SHL => "SHL",
361363
Self::SHR => "SHR",
362364
Self::SAR => "SAR",
365+
Self::CLZ => "CLZ",
363366
Self::POP => "POP",
364367
Self::MLOAD => "MLOAD",
365368
Self::MSTORE => "MSTORE",

evm/src/gasometer/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,9 @@ pub fn dynamic_opcode_cost<H: Handler>(
792792
Opcode::SHL | Opcode::SHR | Opcode::SAR if config.has_bitwise_shifting => GasCost::VeryLow,
793793
Opcode::SHL | Opcode::SHR | Opcode::SAR => GasCost::Invalid(opcode),
794794

795+
Opcode::CLZ if config.has_clz => GasCost::Low,
796+
Opcode::CLZ => GasCost::Invalid(opcode),
797+
795798
Opcode::SELFBALANCE if config.has_self_balance => GasCost::Low,
796799
Opcode::SELFBALANCE => GasCost::Invalid(opcode),
797800

evm/src/runtime/mod.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ pub struct Config {
254254
pub has_restricted_selfdestruct: bool,
255255
/// EIP-7702
256256
pub has_authorization_list: bool,
257+
/// EIP-7939
258+
pub has_clz: bool,
257259
/// EIP-7702
258260
pub gas_per_empty_account_cost: u64,
259261
/// EIP-7702
@@ -323,6 +325,7 @@ impl Config {
323325
has_mcopy: false,
324326
has_restricted_selfdestruct: false,
325327
has_authorization_list: false,
328+
has_clz: false,
326329
gas_per_empty_account_cost: 0,
327330
gas_per_auth_base_cost: 0,
328331
has_floor_gas: false,
@@ -388,6 +391,7 @@ impl Config {
388391
has_mcopy: false,
389392
has_restricted_selfdestruct: false,
390393
has_authorization_list: false,
394+
has_clz: false,
391395
gas_per_auth_base_cost: 0,
392396
gas_per_empty_account_cost: 0,
393397
has_floor_gas: false,
@@ -431,6 +435,12 @@ impl Config {
431435
Self::config_with_derived_values(DerivedConfigInputs::prague())
432436
}
433437

438+
/// Osaka hard fork configuration.
439+
#[must_use]
440+
pub const fn osaka() -> Self {
441+
Self::config_with_derived_values(DerivedConfigInputs::osaka())
442+
}
443+
434444
const fn config_with_derived_values(inputs: DerivedConfigInputs) -> Self {
435445
let DerivedConfigInputs {
436446
gas_storage_read_warm,
@@ -448,6 +458,7 @@ impl Config {
448458
has_mcopy,
449459
has_restricted_selfdestruct,
450460
has_authorization_list,
461+
has_clz,
451462
gas_per_empty_account_cost,
452463
gas_per_auth_base_cost,
453464
has_floor_gas,
@@ -523,6 +534,7 @@ impl Config {
523534
has_mcopy,
524535
has_restricted_selfdestruct,
525536
has_authorization_list,
537+
has_clz,
526538
gas_per_empty_account_cost,
527539
gas_per_auth_base_cost,
528540
has_floor_gas,
@@ -551,6 +563,7 @@ struct DerivedConfigInputs {
551563
has_mcopy: bool,
552564
has_restricted_selfdestruct: bool,
553565
has_authorization_list: bool,
566+
has_clz: bool,
554567
gas_per_empty_account_cost: u64,
555568
gas_per_auth_base_cost: u64,
556569
has_floor_gas: bool,
@@ -575,6 +588,7 @@ impl DerivedConfigInputs {
575588
has_mcopy: false,
576589
has_restricted_selfdestruct: false,
577590
has_authorization_list: false,
591+
has_clz: false,
578592
gas_per_auth_base_cost: 0,
579593
gas_per_empty_account_cost: 0,
580594
has_floor_gas: false,
@@ -599,6 +613,7 @@ impl DerivedConfigInputs {
599613
has_mcopy: false,
600614
has_restricted_selfdestruct: false,
601615
has_authorization_list: false,
616+
has_clz: false,
602617
gas_per_auth_base_cost: 0,
603618
gas_per_empty_account_cost: 0,
604619
has_floor_gas: false,
@@ -623,6 +638,7 @@ impl DerivedConfigInputs {
623638
has_mcopy: false,
624639
has_restricted_selfdestruct: false,
625640
has_authorization_list: false,
641+
has_clz: false,
626642
gas_per_auth_base_cost: 0,
627643
gas_per_empty_account_cost: 0,
628644
has_floor_gas: false,
@@ -648,6 +664,7 @@ impl DerivedConfigInputs {
648664
has_mcopy: false,
649665
has_restricted_selfdestruct: false,
650666
has_authorization_list: false,
667+
has_clz: false,
651668
gas_per_auth_base_cost: 0,
652669
gas_per_empty_account_cost: 0,
653670
has_floor_gas: false,
@@ -674,4 +691,10 @@ impl DerivedConfigInputs {
674691
config.total_cost_floor_per_token = 10;
675692
config
676693
}
694+
695+
const fn osaka() -> Self {
696+
let mut config = Self::prague();
697+
config.has_clz = true;
698+
config
699+
}
677700
}

0 commit comments

Comments
 (0)