Skip to content

Commit ab42581

Browse files
authored
Add OP-Granite hardfork, limiting bn256Pairing input size (bluealloy#1685)
* Add OP-Granite hardfork, limiting bn256Pairing input size * Move optimism-specific bn128 precompile
1 parent 05b34f4 commit ab42581

File tree

6 files changed

+138
-4
lines changed

6 files changed

+138
-4
lines changed

crates/precompile/src/bn128.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub mod mul {
4545
pub mod pair {
4646
use super::*;
4747

48-
const ADDRESS: Address = crate::u64_to_address(8);
48+
pub const ADDRESS: Address = crate::u64_to_address(8);
4949

5050
pub const ISTANBUL_PAIR_PER_POINT: u64 = 34_000;
5151
pub const ISTANBUL_PAIR_BASE: u64 = 45_000;

crates/precompile/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ impl PrecompileSpecId {
297297
#[cfg(feature = "optimism")]
298298
BEDROCK | REGOLITH | CANYON => Self::BERLIN,
299299
#[cfg(feature = "optimism")]
300-
ECOTONE | FJORD => Self::CANCUN,
300+
ECOTONE | FJORD | GRANITE => Self::CANCUN,
301301
}
302302
}
303303
}

crates/primitives/src/specification.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,9 @@ pub enum SpecId {
6565
CANCUN = 20,
6666
ECOTONE = 21,
6767
FJORD = 22,
68-
PRAGUE = 23,
69-
PRAGUE_EOF = 24,
68+
GRANITE = 23,
69+
PRAGUE = 24,
70+
PRAGUE_EOF = 25,
7071
#[default]
7172
LATEST = u8::MAX,
7273
}
@@ -120,6 +121,8 @@ impl From<&str> for SpecId {
120121
"Ecotone" => SpecId::ECOTONE,
121122
#[cfg(feature = "optimism")]
122123
"Fjord" => SpecId::FJORD,
124+
#[cfg(feature = "optimism")]
125+
"Granite" => SpecId::GRANITE,
123126
_ => Self::LATEST,
124127
}
125128
}
@@ -158,6 +161,8 @@ impl From<SpecId> for &'static str {
158161
SpecId::ECOTONE => "Ecotone",
159162
#[cfg(feature = "optimism")]
160163
SpecId::FJORD => "Fjord",
164+
#[cfg(feature = "optimism")]
165+
SpecId::GRANITE => "Granite",
161166
SpecId::LATEST => "Latest",
162167
}
163168
}
@@ -219,6 +224,8 @@ spec!(CANYON, CanyonSpec);
219224
spec!(ECOTONE, EcotoneSpec);
220225
#[cfg(feature = "optimism")]
221226
spec!(FJORD, FjordSpec);
227+
#[cfg(feature = "optimism")]
228+
spec!(GRANITE, GraniteSpec);
222229

223230
#[cfg(not(feature = "optimism"))]
224231
#[macro_export]
@@ -378,6 +385,10 @@ macro_rules! spec_to_generic {
378385
use $crate::FjordSpec as SPEC;
379386
$e
380387
}
388+
$crate::SpecId::GRANITE => {
389+
use $crate::GraniteSpec as SPEC;
390+
$e
391+
}
381392
}
382393
}};
383394
}
@@ -418,6 +429,8 @@ mod tests {
418429
spec_to_generic!(ECOTONE, assert_eq!(SPEC::SPEC_ID, ECOTONE));
419430
#[cfg(feature = "optimism")]
420431
spec_to_generic!(FJORD, assert_eq!(SPEC::SPEC_ID, FJORD));
432+
#[cfg(feature = "optimism")]
433+
spec_to_generic!(GRANITE, assert_eq!(SPEC::SPEC_ID, GRANITE));
421434
spec_to_generic!(PRAGUE, assert_eq!(SPEC::SPEC_ID, PRAGUE));
422435
spec_to_generic!(PRAGUE_EOF, assert_eq!(SPEC::SPEC_ID, PRAGUE_EOF));
423436
spec_to_generic!(LATEST, assert_eq!(SPEC::SPEC_ID, LATEST));
@@ -540,4 +553,32 @@ mod optimism_tests {
540553
assert!(SpecId::enabled(SpecId::FJORD, SpecId::ECOTONE));
541554
assert!(SpecId::enabled(SpecId::FJORD, SpecId::FJORD));
542555
}
556+
557+
#[test]
558+
fn test_granite_post_merge_hardforks() {
559+
assert!(GraniteSpec::enabled(SpecId::MERGE));
560+
assert!(GraniteSpec::enabled(SpecId::SHANGHAI));
561+
assert!(GraniteSpec::enabled(SpecId::CANCUN));
562+
assert!(!GraniteSpec::enabled(SpecId::LATEST));
563+
assert!(GraniteSpec::enabled(SpecId::BEDROCK));
564+
assert!(GraniteSpec::enabled(SpecId::REGOLITH));
565+
assert!(GraniteSpec::enabled(SpecId::CANYON));
566+
assert!(GraniteSpec::enabled(SpecId::ECOTONE));
567+
assert!(GraniteSpec::enabled(SpecId::FJORD));
568+
assert!(GraniteSpec::enabled(SpecId::GRANITE));
569+
}
570+
571+
#[test]
572+
fn test_granite_post_merge_hardforks_spec_id() {
573+
assert!(SpecId::enabled(SpecId::GRANITE, SpecId::MERGE));
574+
assert!(SpecId::enabled(SpecId::GRANITE, SpecId::SHANGHAI));
575+
assert!(SpecId::enabled(SpecId::GRANITE, SpecId::CANCUN));
576+
assert!(!SpecId::enabled(SpecId::GRANITE, SpecId::LATEST));
577+
assert!(SpecId::enabled(SpecId::GRANITE, SpecId::BEDROCK));
578+
assert!(SpecId::enabled(SpecId::GRANITE, SpecId::REGOLITH));
579+
assert!(SpecId::enabled(SpecId::GRANITE, SpecId::CANYON));
580+
assert!(SpecId::enabled(SpecId::GRANITE, SpecId::ECOTONE));
581+
assert!(SpecId::enabled(SpecId::GRANITE, SpecId::FJORD));
582+
assert!(SpecId::enabled(SpecId::GRANITE, SpecId::GRANITE));
583+
}
543584
}

crates/revm/src/optimism.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Optimism-specific constants, types, and helpers.
22
3+
mod bn128;
34
mod fast_lz;
45
mod handler_register;
56
mod l1block;

crates/revm/src/optimism/bn128.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
use revm_precompile::bn128;
2+
use revm_precompile::{Error, Precompile, PrecompileResult, PrecompileWithAddress};
3+
4+
pub(crate) mod pair {
5+
use super::*;
6+
7+
const GRANITE_MAX_INPUT_SIZE: usize = 112687;
8+
pub(crate) const GRANITE: PrecompileWithAddress = PrecompileWithAddress(
9+
bn128::pair::ADDRESS,
10+
Precompile::Standard(|input, gas_limit| run_pair(input, gas_limit)),
11+
);
12+
13+
pub(crate) fn run_pair(input: &[u8], gas_limit: u64) -> PrecompileResult {
14+
if input.len() > GRANITE_MAX_INPUT_SIZE {
15+
return Err(Error::Bn128PairLength.into());
16+
}
17+
bn128::run_pair(
18+
input,
19+
bn128::pair::ISTANBUL_PAIR_PER_POINT,
20+
bn128::pair::ISTANBUL_PAIR_BASE,
21+
gas_limit,
22+
)
23+
}
24+
}
25+
26+
#[cfg(test)]
27+
mod tests {
28+
use revm_precompile::primitives::{hex, PrecompileErrors};
29+
30+
use super::*;
31+
32+
#[test]
33+
fn test_bn128_pair() {
34+
let input = hex::decode(
35+
"\
36+
1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f59\
37+
3034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41\
38+
209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7\
39+
04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678\
40+
2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d\
41+
120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550\
42+
111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c\
43+
2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411\
44+
198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2\
45+
1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed\
46+
090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b\
47+
12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa",
48+
)
49+
.unwrap();
50+
let expected =
51+
hex::decode("0000000000000000000000000000000000000000000000000000000000000001")
52+
.unwrap();
53+
let outcome = pair::run_pair(&input, 260_000).unwrap();
54+
assert_eq!(outcome.bytes, expected);
55+
56+
// invalid input length
57+
let input = hex::decode(
58+
"\
59+
1111111111111111111111111111111111111111111111111111111111111111\
60+
1111111111111111111111111111111111111111111111111111111111111111\
61+
111111111111111111111111111111\
62+
",
63+
)
64+
.unwrap();
65+
66+
let res = pair::run_pair(&input, 260_000);
67+
assert!(matches!(
68+
res,
69+
Err(PrecompileErrors::Error(Error::Bn128PairLength))
70+
));
71+
72+
// valid input length shorter than 112687
73+
let input = vec![1u8; 586 * bn128::PAIR_ELEMENT_LEN];
74+
let res = pair::run_pair(&input, 260_000);
75+
assert!(matches!(res, Err(PrecompileErrors::Error(Error::OutOfGas))));
76+
77+
// input length longer than 112687
78+
let input = vec![1u8; 587 * bn128::PAIR_ELEMENT_LEN];
79+
let res = pair::run_pair(&input, 260_000);
80+
assert!(matches!(
81+
res,
82+
Err(PrecompileErrors::Error(Error::Bn128PairLength))
83+
));
84+
}
85+
}

crates/revm/src/optimism/handler_register.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@ pub fn load_precompiles<SPEC: Spec, EXT, DB: Database>() -> ContextPrecompiles<D
156156
])
157157
}
158158

159+
if SPEC::enabled(SpecId::GRANITE) {
160+
precompiles.extend([
161+
// Restrict bn256Pairing input size
162+
optimism::bn128::pair::GRANITE,
163+
])
164+
}
165+
159166
precompiles
160167
}
161168

0 commit comments

Comments
 (0)