Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion crates/handler/src/precompile_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ impl<CTX: ContextTr> PrecompileProvider<CTX> for EthPrecompiles {
let Some(precompile) = self.precompiles.get(address) else {
return Ok(None);
};

let mut result = InterpreterResult {
result: InstructionResult::Return,
gas: Gas::new(gas_limit),
Expand All @@ -120,7 +121,7 @@ impl<CTX: ContextTr> PrecompileProvider<CTX> for EthPrecompiles {
CallInput::Bytes(bytes) => bytes.0.iter().as_slice(),
};

match (*precompile)(input_bytes, gas_limit) {
match (*precompile)(input_bytes, gas_limit, self.precompiles.crypto()) {
Ok(output) => {
let underflow = result.gas.record_cost(output.gas_used);
assert!(underflow, "Gas underflow is not possible");
Expand Down
49 changes: 33 additions & 16 deletions crates/op-revm/src/precompiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,16 @@ pub mod bn128_pair {
pub const GRANITE_MAX_INPUT_SIZE: usize = 112687;
/// Bn128 pair precompile.
pub const GRANITE: PrecompileWithAddress =
PrecompileWithAddress(bn128::pair::ADDRESS, |input, gas_limit| {
run_pair(input, gas_limit)
PrecompileWithAddress(bn128::pair::ADDRESS, |input, gas_limit, crypto| {
run_pair(input, gas_limit, crypto)
});

/// Run the bn128 pair precompile with Optimism input limit.
pub fn run_pair(input: &[u8], gas_limit: u64) -> PrecompileResult {
pub fn run_pair(
input: &[u8],
gas_limit: u64,
crypto: &dyn precompile::Crypto,
) -> PrecompileResult {
if input.len() > GRANITE_MAX_INPUT_SIZE {
return Err(PrecompileError::Bn128PairLength);
}
Expand All @@ -160,6 +164,7 @@ pub mod bn128_pair {
bn128::pair::ISTANBUL_PAIR_PER_POINT,
bn128::pair::ISTANBUL_PAIR_BASE,
gas_limit,
crypto,
)
}
}
Expand Down Expand Up @@ -190,33 +195,45 @@ pub mod bls12_381 {
PrecompileWithAddress(PAIRING_ADDRESS, run_pair);

/// Run the g1 msm precompile with Optimism input limit.
pub fn run_g1_msm(input: &[u8], gas_limit: u64) -> PrecompileResult {
pub fn run_g1_msm(
input: &[u8],
gas_limit: u64,
crypto: &dyn precompile::Crypto,
) -> PrecompileResult {
if input.len() > ISTHMUS_G1_MSM_MAX_INPUT_SIZE {
return Err(PrecompileError::Other(
"G1MSM input length too long for OP Stack input size limitation".to_string(),
));
}
precompile::bls12_381::g1_msm::g1_msm(input, gas_limit)
precompile::bls12_381::g1_msm::g1_msm(input, gas_limit, crypto)
}

/// Run the g2 msm precompile with Optimism input limit.
pub fn run_g2_msm(input: &[u8], gas_limit: u64) -> PrecompileResult {
pub fn run_g2_msm(
input: &[u8],
gas_limit: u64,
crypto: &dyn precompile::Crypto,
) -> PrecompileResult {
if input.len() > ISTHMUS_G2_MSM_MAX_INPUT_SIZE {
return Err(PrecompileError::Other(
"G2MSM input length too long for OP Stack input size limitation".to_string(),
));
}
precompile::bls12_381::g2_msm::g2_msm(input, gas_limit)
precompile::bls12_381::g2_msm::g2_msm(input, gas_limit, crypto)
}

/// Run the pairing precompile with Optimism input limit.
pub fn run_pair(input: &[u8], gas_limit: u64) -> PrecompileResult {
pub fn run_pair(
input: &[u8],
gas_limit: u64,
crypto: &dyn precompile::Crypto,
) -> PrecompileResult {
if input.len() > ISTHMUS_PAIRING_MAX_INPUT_SIZE {
return Err(PrecompileError::Other(
"Pairing input length too long for OP Stack input size limitation".to_string(),
));
}
precompile::bls12_381::pairing::pairing(input, gas_limit)
precompile::bls12_381::pairing::pairing(input, gas_limit, crypto)
}
}

Expand Down Expand Up @@ -255,7 +272,7 @@ mod tests {
let expected =
hex::decode("0000000000000000000000000000000000000000000000000000000000000001")
.unwrap();
let outcome = bn128_pair::run_pair(&input, 260_000).unwrap();
let outcome = bn128_pair::run_pair(&input, 260_000, &precompile::DefaultCrypto).unwrap();
assert_eq!(outcome.bytes, expected);

// Invalid input length
Expand All @@ -268,17 +285,17 @@ mod tests {
)
.unwrap();

let res = bn128_pair::run_pair(&input, 260_000);
let res = bn128_pair::run_pair(&input, 260_000, &precompile::DefaultCrypto);
assert!(matches!(res, Err(PrecompileError::Bn128PairLength)));

// Valid input length shorter than 112687
let input = vec![1u8; 586 * bn128::PAIR_ELEMENT_LEN];
let res = bn128_pair::run_pair(&input, 260_000);
let res = bn128_pair::run_pair(&input, 260_000, &precompile::DefaultCrypto);
assert!(matches!(res, Err(PrecompileError::OutOfGas)));

// Input length longer than 112687
let input = vec![1u8; 587 * bn128::PAIR_ELEMENT_LEN];
let res = bn128_pair::run_pair(&input, 260_000);
let res = bn128_pair::run_pair(&input, 260_000, &precompile::DefaultCrypto);
assert!(matches!(res, Err(PrecompileError::Bn128PairLength)));
}

Expand Down Expand Up @@ -320,7 +337,7 @@ mod tests {
let oversized_input = vec![0u8; ISTHMUS_G1_MSM_MAX_INPUT_SIZE + 1];
let input = Bytes::from(oversized_input);

let res = run_g1_msm(&input, 260_000);
let res = run_g1_msm(&input, 260_000, &precompile::DefaultCrypto);

assert!(
matches!(res, Err(PrecompileError::Other(msg)) if msg.contains("input length too long"))
Expand All @@ -331,7 +348,7 @@ mod tests {
let oversized_input = vec![0u8; ISTHMUS_G2_MSM_MAX_INPUT_SIZE + 1];
let input = Bytes::from(oversized_input);

let res = run_g2_msm(&input, 260_000);
let res = run_g2_msm(&input, 260_000, &precompile::DefaultCrypto);

assert!(
matches!(res, Err(PrecompileError::Other(msg)) if msg.contains("input length too long"))
Expand All @@ -342,7 +359,7 @@ mod tests {
let oversized_input = vec![0u8; ISTHMUS_PAIRING_MAX_INPUT_SIZE + 1];
let input = Bytes::from(oversized_input);

let res = bls12_381::run_pair(&input, 260_000);
let res = bls12_381::run_pair(&input, 260_000, &precompile::DefaultCrypto);

assert!(
matches!(res, Err(PrecompileError::Other(msg)) if msg.contains("input length too long"))
Expand Down
36 changes: 27 additions & 9 deletions crates/precompile/bench/blake2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,71 +20,89 @@ pub fn add_benches(group: &mut BenchmarkGroup<'_, criterion::measurement::WallTi
group.bench_function("blake2/2_rounds", |b| {
let input = &inputs[0]; // 2 rounds
b.iter(|| {
black_box(blake2::run(black_box(input), u64::MAX).unwrap());
black_box(
blake2::run(black_box(input), u64::MAX, &revm_precompile::DefaultCrypto).unwrap(),
);
});
});

// Benchmark with 4 rounds
group.bench_function("blake2/4_rounds", |b| {
let input = &inputs[1]; // 4 rounds
b.iter(|| {
black_box(blake2::run(black_box(input), u64::MAX).unwrap());
black_box(
blake2::run(black_box(input), u64::MAX, &revm_precompile::DefaultCrypto).unwrap(),
);
});
});

// Benchmark with 64 rounds
group.bench_function("blake2/64_rounds", |b| {
let input = &inputs[2]; // 64 rounds
b.iter(|| {
black_box(blake2::run(black_box(input), u64::MAX).unwrap());
black_box(
blake2::run(black_box(input), u64::MAX, &revm_precompile::DefaultCrypto).unwrap(),
);
});
});

// Benchmark with 10 rounds (Blake2s standard)
group.bench_function("blake2/10_rounds", |b| {
let input = &inputs[3]; // 10 rounds
b.iter(|| {
black_box(blake2::run(black_box(input), u64::MAX).unwrap());
black_box(
blake2::run(black_box(input), u64::MAX, &revm_precompile::DefaultCrypto).unwrap(),
);
});
});

// Benchmark with 12 rounds (Blake2b standard)
group.bench_function("blake2/12_rounds", |b| {
let input = &inputs[4]; // 12 rounds
b.iter(|| {
black_box(blake2::run(black_box(input), u64::MAX).unwrap());
black_box(
blake2::run(black_box(input), u64::MAX, &revm_precompile::DefaultCrypto).unwrap(),
);
});
});

// Benchmark with 512 rounds
group.bench_function("blake2/512_rounds", |b| {
let input = &inputs[5]; // 512 rounds
b.iter(|| {
black_box(blake2::run(black_box(input), u64::MAX).unwrap());
black_box(
blake2::run(black_box(input), u64::MAX, &revm_precompile::DefaultCrypto).unwrap(),
);
});
});

// Benchmark with 1024 rounds
group.bench_function("blake2/1024_rounds", |b| {
let input = &inputs[6]; // 1024 rounds
b.iter(|| {
black_box(blake2::run(black_box(input), u64::MAX).unwrap());
black_box(
blake2::run(black_box(input), u64::MAX, &revm_precompile::DefaultCrypto).unwrap(),
);
});
});

// Benchmark with 100K rounds
group.bench_function("blake2/100K_rounds", |b| {
let input = &inputs[7]; // 100000 rounds
b.iter(|| {
black_box(blake2::run(black_box(input), u64::MAX).unwrap());
black_box(
blake2::run(black_box(input), u64::MAX, &revm_precompile::DefaultCrypto).unwrap(),
);
});
});

// Benchmark with 200K rounds
group.bench_function("blake2/200K_rounds", |b| {
let input = &inputs[8]; // 200000 rounds
b.iter(|| {
black_box(blake2::run(black_box(input), u64::MAX).unwrap());
black_box(
blake2::run(black_box(input), u64::MAX, &revm_precompile::DefaultCrypto).unwrap(),
);
});
});

Expand Down
9 changes: 8 additions & 1 deletion crates/precompile/bench/ecrecover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ pub fn add_benches<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
let message_and_signature = Bytes::from(message_and_signature);

group.bench_function("ecrecover precompile", |b| {
b.iter(|| ec_recover_run(&message_and_signature, u64::MAX).unwrap())
b.iter(|| {
ec_recover_run(
&message_and_signature,
u64::MAX,
&revm_precompile::DefaultCrypto,
)
.unwrap()
})
});
}
21 changes: 19 additions & 2 deletions crates/precompile/bench/eip1962.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@ pub fn add_bn128_add_benches<M: Measurement>(group: &mut BenchmarkGroup<'_, M>)
let input = Bytes::from(ecadd_input);

group.bench_function("bn128 add precompile", |b| {
b.iter(|| run_add(&input, ISTANBUL_ADD_GAS_COST, 150).unwrap())
b.iter(|| {
run_add(
&input,
ISTANBUL_ADD_GAS_COST,
150,
&revm_precompile::DefaultCrypto,
)
.unwrap()
})
});
}

Expand All @@ -38,7 +46,15 @@ pub fn add_bn128_mul_benches<M: Measurement>(group: &mut BenchmarkGroup<'_, M>)
let input = Bytes::from(ecmul_input);

group.bench_function("bn128 mul precompile", |b| {
b.iter(|| run_mul(&input, ISTANBUL_MUL_GAS_COST, 6000).unwrap())
b.iter(|| {
run_mul(
&input,
ISTANBUL_MUL_GAS_COST,
6000,
&revm_precompile::DefaultCrypto,
)
.unwrap()
})
});
}

Expand Down Expand Up @@ -69,6 +85,7 @@ pub fn add_bn128_pair_benches<M: Measurement>(group: &mut BenchmarkGroup<'_, M>)
ISTANBUL_PAIR_PER_POINT,
ISTANBUL_PAIR_BASE,
u64::MAX,
&revm_precompile::DefaultCrypto,
)
.unwrap()
})
Expand Down
14 changes: 7 additions & 7 deletions crates/precompile/bench/eip2537.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ pub fn add_g1_add_benches<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
let precompile = *PRECOMPILE.precompile();

group.bench_function("g1_add", |b| {
b.iter(|| precompile(&input, u64::MAX).unwrap());
b.iter(|| precompile(&input, u64::MAX, &revm_precompile::DefaultCrypto).unwrap());
});
}

Expand All @@ -167,7 +167,7 @@ pub fn add_g2_add_benches<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
let precompile = *PRECOMPILE.precompile();

group.bench_function("g2_add", |b| {
b.iter(|| precompile(&input, u64::MAX).unwrap());
b.iter(|| precompile(&input, u64::MAX, &revm_precompile::DefaultCrypto).unwrap());
});
}

Expand All @@ -185,7 +185,7 @@ pub fn add_g1_msm_benches<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
let input = Bytes::from(test_vector);

group.bench_function(format!("g1_msm (size {size})"), |b| {
b.iter(|| precompile(&input, u64::MAX).unwrap());
b.iter(|| precompile(&input, u64::MAX, &revm_precompile::DefaultCrypto).unwrap());
});
}
}
Expand Down Expand Up @@ -230,7 +230,7 @@ pub fn add_g2_msm_benches<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
let input = Bytes::from(test_vector);

group.bench_function(format!("g2_msm (size {size})"), |b| {
b.iter(|| precompile(&input, u64::MAX).unwrap());
b.iter(|| precompile(&input, u64::MAX, &revm_precompile::DefaultCrypto).unwrap());
});
}
}
Expand Down Expand Up @@ -263,7 +263,7 @@ pub fn add_pairing_benches<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
let input = Bytes::from(test_vector);

group.bench_function(format!("pairing ({pairs} pairs)"), |b| {
b.iter(|| precompile(&input, u64::MAX).unwrap());
b.iter(|| precompile(&input, u64::MAX, &revm_precompile::DefaultCrypto).unwrap());
});
}
}
Expand All @@ -284,7 +284,7 @@ pub fn add_map_fp_to_g1_benches<M: Measurement>(group: &mut BenchmarkGroup<'_, M
let precompile = *PRECOMPILE.precompile();

group.bench_function("map_fp_to_g1", |b| {
b.iter(|| precompile(&input, u64::MAX).unwrap());
b.iter(|| precompile(&input, u64::MAX, &revm_precompile::DefaultCrypto).unwrap());
});
}

Expand All @@ -311,6 +311,6 @@ pub fn add_map_fp2_to_g2_benches<M: Measurement>(group: &mut BenchmarkGroup<'_,
let precompile = *PRECOMPILE.precompile();

group.bench_function("map_fp2_to_g2", |b| {
b.iter(|| precompile(&input, u64::MAX).unwrap());
b.iter(|| precompile(&input, u64::MAX, &revm_precompile::DefaultCrypto).unwrap());
});
}
2 changes: 1 addition & 1 deletion crates/precompile/bench/eip4844.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ pub fn add_benches<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
let gas = 50000;

group.bench_function("kzg precompile", |b| {
b.iter(|| run(&kzg_input, gas).unwrap())
b.iter(|| run(&kzg_input, gas, &revm_precompile::DefaultCrypto).unwrap())
});
}
4 changes: 2 additions & 2 deletions crates/precompile/src/blake2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub const FUN: PrecompileWithAddress = PrecompileWithAddress(crate::u64_to_addre
/// reference: <https://eips.ethereum.org/EIPS/eip-152>
/// input format:
/// [4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f]
pub fn run(input: &[u8], gas_limit: u64) -> PrecompileResult {
pub fn run(input: &[u8], gas_limit: u64, _crypto: &dyn crate::Crypto) -> PrecompileResult {
if input.len() != INPUT_LENGTH {
return Err(PrecompileError::Blake2WrongLength);
}
Expand Down Expand Up @@ -639,7 +639,7 @@ mod tests {

let time = Instant::now();
for i in 0..3000 {
let _ = run(&input[i % 3], u64::MAX).unwrap();
let _ = run(&input[i % 3], u64::MAX, &crate::DefaultCrypto).unwrap();
}
println!("duration: {:?}", time.elapsed());
}
Expand Down
Loading
Loading