diff --git a/crates/precompile/src/blake2.rs b/crates/precompile/src/blake2.rs index 057bba74d4..2cf60d7f65 100644 --- a/crates/precompile/src/blake2.rs +++ b/crates/precompile/src/blake2.rs @@ -1,5 +1,5 @@ use crate::{Error, Precompile, PrecompileResult, PrecompileWithAddress}; -use revm_primitives::Bytes; +use revm_primitives::{Bytes, PrecompileErrors}; const F_ROUND: u64 = 1; const INPUT_LENGTH: usize = 213; @@ -14,20 +14,20 @@ pub fn run(input: &Bytes, gas_limit: u64) -> PrecompileResult { let input = &input[..]; if input.len() != INPUT_LENGTH { - return Err(Error::Blake2WrongLength); + return Err(Error::Blake2WrongLength.into()); } let f = match input[212] { 1 => true, 0 => false, - _ => return Err(Error::Blake2WrongFinalIndicatorFlag), + _ => return Err(Error::Blake2WrongFinalIndicatorFlag.into()), }; // rounds 4 bytes let rounds = u32::from_be_bytes(input[..4].try_into().unwrap()) as usize; let gas_used = rounds as u64 * F_ROUND; if gas_used > gas_limit { - return Err(Error::OutOfGas); + return Err(Error::OutOfGas.into()); } let mut h = [0u64; 8]; @@ -51,7 +51,7 @@ pub fn run(input: &Bytes, gas_limit: u64) -> PrecompileResult { out[i..i + 8].copy_from_slice(&h.to_le_bytes()); } - Ok((gas_used, out.into())) + PrecompileResult::ok(gas_used, out.into()) } pub mod algo { diff --git a/crates/precompile/src/bls12_381.rs b/crates/precompile/src/bls12_381.rs index fd5daae00a..2068b6ecbe 100644 --- a/crates/precompile/src/bls12_381.rs +++ b/crates/precompile/src/bls12_381.rs @@ -85,28 +85,35 @@ mod test { for vector in test_vectors.0 { let test_name = format!("{file_name}/{}", vector.name); - let input = Bytes::from_hex(vector.input.clone()).unwrap_or_else(|e| { + let input = Bytes::from_hex(&vector.input).unwrap_or_else(|e| { panic!( - "could not deserialize input {} as hex in {test_name}: {e}", - &vector.input + "could not deserialize input {} as hex in {}: {}", + vector.input, test_name, e ) }); let target_gas: u64 = 30_000_000; let res = precompile(&input, target_gas); - if vector.error.unwrap_or_default() { - assert!(res.is_err(), "expected error didn't happen in {test_name}"); - } else { - let (actual_gas, actual_output) = - res.unwrap_or_else(|e| panic!("precompile call failed for {test_name}: {e}")); - assert_eq!( - vector.gas, actual_gas, - "expected gas: {}, actual gas: {} in {test_name}", - vector.gas, actual_gas - ); - let expected_output = Bytes::from_hex(vector.expected).unwrap(); - assert_eq!( - expected_output, actual_output, - "expected output: {expected_output}, actual output: {actual_output} in {test_name}"); + match res { + PrecompileResult::Error { .. } if vector.error.unwrap_or_default() => { + // Test passed, it was expected to fail + } + PrecompileResult::Ok { + gas_used: actual_gas, + output: actual_output, + } => { + assert_eq!( + vector.gas, actual_gas, + "expected gas: {}, actual gas: {} in {}", + vector.gas, actual_gas, test_name + ); + let expected_output = Bytes::from_hex(&vector.expected).unwrap(); + assert_eq!( + expected_output, actual_output, + "expected output: {:?}, actual output: {:?} in {}", + expected_output, actual_output, test_name + ); + } + _ => panic!("unexpected result in {}, vector: {:?}", test_name, vector), } } } diff --git a/crates/precompile/src/bls12_381/g1_add.rs b/crates/precompile/src/bls12_381/g1_add.rs index 9fed002dfc..d7390eabbd 100644 --- a/crates/precompile/src/bls12_381/g1_add.rs +++ b/crates/precompile/src/bls12_381/g1_add.rs @@ -23,21 +23,21 @@ const INPUT_LENGTH: usize = 256; /// See also: pub(super) fn g1_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { if BASE_GAS_FEE > gas_limit { - return Err(PrecompileError::OutOfGas); + return Err(PrecompileError::OutOfGas.into()); } if input.len() != INPUT_LENGTH { return Err(PrecompileError::Other(format!( "G1ADD input should be {INPUT_LENGTH} bytes, was {}", input.len() - ))); + )).into()); } // NB: There is no subgroup check for the G1 addition precompile. // // So we set the subgroup checks here to `false` - let a_aff = &extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH], false)?; - let b_aff = &extract_g1_input(&input[G1_INPUT_ITEM_LENGTH..], false)?; + let a_aff = &extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH], false).unwrap(); + let b_aff = &extract_g1_input(&input[G1_INPUT_ITEM_LENGTH..], false).unwrap(); let mut b = blst_p1::default(); // SAFETY: b and b_aff are blst values. @@ -52,5 +52,5 @@ pub(super) fn g1_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { unsafe { blst_p1_to_affine(&mut p_aff, &p) }; let out = encode_g1_point(&p_aff); - Ok((BASE_GAS_FEE, out)) + PrecompileResult::ok(BASE_GAS_FEE, out) } diff --git a/crates/precompile/src/bls12_381/g1_msm.rs b/crates/precompile/src/bls12_381/g1_msm.rs index c8d086abb6..5bcd9095b3 100644 --- a/crates/precompile/src/bls12_381/g1_msm.rs +++ b/crates/precompile/src/bls12_381/g1_msm.rs @@ -29,13 +29,13 @@ pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { "G1MSM input length should be multiple of {}, was {}", g1_mul::INPUT_LENGTH, input_len - ))); + )).into()); } let k = input_len / g1_mul::INPUT_LENGTH; let required_gas = msm_required_gas(k, g1_mul::BASE_GAS_FEE); if required_gas > gas_limit { - return Err(PrecompileError::OutOfGas); + return Err(PrecompileError::OutOfGas.into()); } let mut g1_points: Vec = Vec::with_capacity(k); @@ -53,7 +53,7 @@ pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { // NB: Scalar multiplications, MSMs and pairings MUST perform a subgroup check. // // So we set the subgroup_check flag to `true` - let p0_aff = &extract_g1_input(slice, true)?; + let p0_aff = &extract_g1_input(slice, true).unwrap(); let mut p0 = blst_p1::default(); // SAFETY: p0 and p0_aff are blst values. @@ -64,14 +64,15 @@ pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { &extract_scalar_input( &input[i * g1_mul::INPUT_LENGTH + G1_INPUT_ITEM_LENGTH ..i * g1_mul::INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + SCALAR_LENGTH], - )? + ) + .unwrap() .b, ); } // return infinity point if all points are infinity if g1_points.is_empty() { - return Ok((required_gas, [0; 128].into())); + return PrecompileResult::ok(required_gas, [0; 128].into()); } let points = p1_affines::from(&g1_points); @@ -82,5 +83,5 @@ pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { unsafe { blst_p1_to_affine(&mut multiexp_aff, &multiexp) }; let out = encode_g1_point(&multiexp_aff); - Ok((required_gas, out)) + PrecompileResult::ok(required_gas, out) } diff --git a/crates/precompile/src/bls12_381/g1_mul.rs b/crates/precompile/src/bls12_381/g1_mul.rs index 305458e236..14430aead5 100644 --- a/crates/precompile/src/bls12_381/g1_mul.rs +++ b/crates/precompile/src/bls12_381/g1_mul.rs @@ -25,24 +25,24 @@ pub(super) const INPUT_LENGTH: usize = 160; /// See also: pub(super) fn g1_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult { if BASE_GAS_FEE > gas_limit { - return Err(PrecompileError::OutOfGas); + return Err(PrecompileError::OutOfGas.into()); } if input.len() != INPUT_LENGTH { return Err(PrecompileError::Other(format!( "G1MUL input should be {INPUT_LENGTH} bytes, was {}", input.len() - ))); + )).into()); } // NB: Scalar multiplications, MSMs and pairings MUST perform a subgroup check. // // So we set the subgroup_check flag to `true` - let p0_aff = &extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH], true)?; + let p0_aff = &extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH], true).unwrap(); let mut p0 = blst_p1::default(); // SAFETY: p0 and p0_aff are blst values. unsafe { blst_p1_from_affine(&mut p0, p0_aff) }; - let input_scalar0 = extract_scalar_input(&input[G1_INPUT_ITEM_LENGTH..])?; + let input_scalar0 = extract_scalar_input(&input[G1_INPUT_ITEM_LENGTH..]).unwrap(); let mut p = blst_p1::default(); // SAFETY: input_scalar0.b has fixed size, p and p0 are blst values. @@ -52,5 +52,5 @@ pub(super) fn g1_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult { unsafe { blst_p1_to_affine(&mut p_aff, &p) }; let out = encode_g1_point(&p_aff); - Ok((BASE_GAS_FEE, out)) + PrecompileResult::ok(BASE_GAS_FEE, out) } diff --git a/crates/precompile/src/bls12_381/g2_add.rs b/crates/precompile/src/bls12_381/g2_add.rs index a8f5b85a8e..6005dc6673 100644 --- a/crates/precompile/src/bls12_381/g2_add.rs +++ b/crates/precompile/src/bls12_381/g2_add.rs @@ -24,21 +24,21 @@ const INPUT_LENGTH: usize = 512; /// See also pub(super) fn g2_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { if BASE_GAS_FEE > gas_limit { - return Err(PrecompileError::OutOfGas); + return Err(PrecompileError::OutOfGas.into()); } if input.len() != INPUT_LENGTH { return Err(PrecompileError::Other(format!( "G2ADD input should be {INPUT_LENGTH} bytes, was {}", input.len() - ))); + )).into()); } // NB: There is no subgroup check for the G2 addition precompile. // // So we set the subgroup checks here to `false` - let a_aff = &extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH], false)?; - let b_aff = &extract_g2_input(&input[G2_INPUT_ITEM_LENGTH..], false)?; + let a_aff = &extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH], false).unwrap(); + let b_aff = &extract_g2_input(&input[G2_INPUT_ITEM_LENGTH..], false).unwrap(); let mut b = blst_p2::default(); // SAFETY: b and b_aff are blst values. @@ -53,5 +53,5 @@ pub(super) fn g2_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { unsafe { blst_p2_to_affine(&mut p_aff, &p) }; let out = encode_g2_point(&p_aff); - Ok((BASE_GAS_FEE, out)) + PrecompileResult::ok(BASE_GAS_FEE, out) } diff --git a/crates/precompile/src/bls12_381/g2_msm.rs b/crates/precompile/src/bls12_381/g2_msm.rs index 85f8208fde..cc9db92923 100644 --- a/crates/precompile/src/bls12_381/g2_msm.rs +++ b/crates/precompile/src/bls12_381/g2_msm.rs @@ -29,13 +29,13 @@ pub(super) fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { "G2MSM input length should be multiple of {}, was {}", g2_mul::INPUT_LENGTH, input_len - ))); + )).into()); } let k = input_len / g2_mul::INPUT_LENGTH; let required_gas = msm_required_gas(k, g2_mul::BASE_GAS_FEE); if required_gas > gas_limit { - return Err(PrecompileError::OutOfGas); + return Err(PrecompileError::OutOfGas.into()); } let mut g2_points: Vec = Vec::with_capacity(k); @@ -52,7 +52,7 @@ pub(super) fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { // NB: Scalar multiplications, MSMs and pairings MUST perform a subgroup check. // // So we set the subgroup_check flag to `true` - let p0_aff = &extract_g2_input(slice, true)?; + let p0_aff = &extract_g2_input(slice, true).unwrap(); let mut p0 = blst_p2::default(); // SAFETY: p0 and p0_aff are blst values. @@ -64,14 +64,15 @@ pub(super) fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { &extract_scalar_input( &input[i * g2_mul::INPUT_LENGTH + G2_INPUT_ITEM_LENGTH ..i * g2_mul::INPUT_LENGTH + G2_INPUT_ITEM_LENGTH + SCALAR_LENGTH], - )? + ) + .unwrap() .b, ); } // return infinity point if all points are infinity if g2_points.is_empty() { - return Ok((required_gas, [0; 256].into())); + return PrecompileResult::ok(required_gas, [0; 256].into()); } let points = p2_affines::from(&g2_points); @@ -82,5 +83,5 @@ pub(super) fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { unsafe { blst_p2_to_affine(&mut multiexp_aff, &multiexp) }; let out = encode_g2_point(&multiexp_aff); - Ok((required_gas, out)) + PrecompileResult::ok(required_gas, out) } diff --git a/crates/precompile/src/bls12_381/g2_mul.rs b/crates/precompile/src/bls12_381/g2_mul.rs index 62cb903e9b..f285c5c8aa 100644 --- a/crates/precompile/src/bls12_381/g2_mul.rs +++ b/crates/precompile/src/bls12_381/g2_mul.rs @@ -25,24 +25,24 @@ pub(super) const INPUT_LENGTH: usize = 288; /// See also: pub(super) fn g2_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult { if BASE_GAS_FEE > gas_limit { - return Err(PrecompileError::OutOfGas); + return Err(PrecompileError::OutOfGas.into()); } if input.len() != INPUT_LENGTH { return Err(PrecompileError::Other(format!( "G2MUL input should be {INPUT_LENGTH} bytes, was {}", input.len() - ))); + )).into()); } // NB: Scalar multiplications, MSMs and pairings MUST perform a subgroup check. // // So we set the subgroup_check flag to `true` - let p0_aff = &extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH], true)?; + let p0_aff = &extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH], true).unwrap(); let mut p0 = blst_p2::default(); // SAFETY: p0 and p0_aff are blst values. unsafe { blst_p2_from_affine(&mut p0, p0_aff) }; - let input_scalar0 = extract_scalar_input(&input[G2_INPUT_ITEM_LENGTH..])?; + let input_scalar0 = extract_scalar_input(&input[G2_INPUT_ITEM_LENGTH..]).unwrap(); let mut p = blst_p2::default(); // SAFETY: input_scalar0.b has fixed size, p and p0 are blst values. @@ -52,5 +52,5 @@ pub(super) fn g2_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult { unsafe { blst_p2_to_affine(&mut p_aff, &p) }; let out = encode_g2_point(&p_aff); - Ok((BASE_GAS_FEE, out)) + PrecompileResult::ok(BASE_GAS_FEE, out) } diff --git a/crates/precompile/src/bls12_381/map_fp2_to_g2.rs b/crates/precompile/src/bls12_381/map_fp2_to_g2.rs index 51a90ac313..afcdcbb22a 100644 --- a/crates/precompile/src/bls12_381/map_fp2_to_g2.rs +++ b/crates/precompile/src/bls12_381/map_fp2_to_g2.rs @@ -23,18 +23,18 @@ const BASE_GAS_FEE: u64 = 75000; /// See also: pub(super) fn map_fp2_to_g2(input: &Bytes, gas_limit: u64) -> PrecompileResult { if BASE_GAS_FEE > gas_limit { - return Err(PrecompileError::OutOfGas); + return Err(PrecompileError::OutOfGas.into()); } if input.len() != PADDED_FP2_LENGTH { return Err(PrecompileError::Other(format!( "MAP_FP2_TO_G2 input should be {PADDED_FP2_LENGTH} bytes, was {}", input.len() - ))); + )).into()); } - let input_p0_x = remove_padding(&input[..PADDED_FP_LENGTH])?; - let input_p0_y = remove_padding(&input[PADDED_FP_LENGTH..PADDED_FP2_LENGTH])?; + let input_p0_x = remove_padding(&input[..PADDED_FP_LENGTH]).unwrap(); + let input_p0_y = remove_padding(&input[PADDED_FP_LENGTH..PADDED_FP2_LENGTH]).unwrap(); let mut fp2 = blst_fp2::default(); let mut fp_x = blst_fp::default(); @@ -56,5 +56,5 @@ pub(super) fn map_fp2_to_g2(input: &Bytes, gas_limit: u64) -> PrecompileResult { unsafe { blst_p2_to_affine(&mut p_aff, &p) }; let out = encode_g2_point(&p_aff); - Ok((BASE_GAS_FEE, out)) + PrecompileResult::ok(BASE_GAS_FEE, out) } diff --git a/crates/precompile/src/bls12_381/map_fp_to_g1.rs b/crates/precompile/src/bls12_381/map_fp_to_g1.rs index a6d9f48ecb..19e194c8cf 100644 --- a/crates/precompile/src/bls12_381/map_fp_to_g1.rs +++ b/crates/precompile/src/bls12_381/map_fp_to_g1.rs @@ -21,17 +21,17 @@ const MAP_FP_TO_G1_BASE: u64 = 5500; /// See also: pub(super) fn map_fp_to_g1(input: &Bytes, gas_limit: u64) -> PrecompileResult { if MAP_FP_TO_G1_BASE > gas_limit { - return Err(PrecompileError::OutOfGas); + return Err(PrecompileError::OutOfGas.into()); } if input.len() != PADDED_FP_LENGTH { return Err(PrecompileError::Other(format!( "MAP_FP_TO_G1 input should be {PADDED_FP_LENGTH} bytes, was {}", input.len() - ))); + )).into()); } - let input_p0 = remove_padding(input)?; + let input_p0 = remove_padding(input).unwrap(); let mut fp = blst_fp::default(); @@ -48,5 +48,5 @@ pub(super) fn map_fp_to_g1(input: &Bytes, gas_limit: u64) -> PrecompileResult { unsafe { blst_p1_to_affine(&mut p_aff, &p) }; let out = encode_g1_point(&p_aff); - Ok((MAP_FP_TO_G1_BASE, out)) + PrecompileResult::ok(MAP_FP_TO_G1_BASE, out) } diff --git a/crates/precompile/src/bls12_381/pairing.rs b/crates/precompile/src/bls12_381/pairing.rs index 2a699a0859..24b8ce7c29 100644 --- a/crates/precompile/src/bls12_381/pairing.rs +++ b/crates/precompile/src/bls12_381/pairing.rs @@ -34,13 +34,13 @@ pub(super) fn pairing(input: &Bytes, gas_limit: u64) -> PrecompileResult { if input_len == 0 || input_len % INPUT_LENGTH != 0 { return Err(PrecompileError::Other(format!( "Pairing input length should be multiple of {INPUT_LENGTH}, was {input_len}" - ))); + )).into()); } let k = input_len / INPUT_LENGTH; let required_gas: u64 = PAIRING_MULTIPLIER_BASE * k as u64 + PAIRING_OFFSET_BASE; if required_gas > gas_limit { - return Err(PrecompileError::OutOfGas); + return Err(PrecompileError::OutOfGas.into()); } // accumulator for the fp12 multiplications of the miller loops. @@ -52,7 +52,8 @@ pub(super) fn pairing(input: &Bytes, gas_limit: u64) -> PrecompileResult { let p1_aff = &extract_g1_input( &input[i * INPUT_LENGTH..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH], true, - )?; + ) + .unwrap(); // NB: Scalar multiplications, MSMs and pairings MUST perform a subgroup check. // @@ -61,7 +62,8 @@ pub(super) fn pairing(input: &Bytes, gas_limit: u64) -> PrecompileResult { &input[i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH ..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + G2_INPUT_ITEM_LENGTH], true, - )?; + ) + .unwrap(); if i > 0 { // after the first slice (i>0) we use cur_ml to store the current @@ -98,5 +100,5 @@ pub(super) fn pairing(input: &Bytes, gas_limit: u64) -> PrecompileResult { result = 1; } } - Ok((required_gas, B256::with_last_byte(result).into())) + PrecompileResult::ok(required_gas, B256::with_last_byte(result).into()) } diff --git a/crates/precompile/src/bn128.rs b/crates/precompile/src/bn128.rs index ce08da7994..bc14005fc0 100644 --- a/crates/precompile/src/bn128.rs +++ b/crates/precompile/src/bn128.rs @@ -3,6 +3,7 @@ use crate::{ Address, Error, Precompile, PrecompileResult, PrecompileWithAddress, }; use bn::{AffineG1, AffineG2, Fq, Fq2, Group, Gt, G1, G2}; +use revm_primitives::PrecompileErrors; pub mod add { use super::*; @@ -122,30 +123,39 @@ pub fn new_g1_point(px: Fq, py: Fq) -> Result { pub fn run_add(input: &[u8], gas_cost: u64, gas_limit: u64) -> PrecompileResult { if gas_cost > gas_limit { - return Err(Error::OutOfGas); + return Err(Error::OutOfGas.into()); } let input = right_pad::(input); - let p1 = read_point(&input[..64])?; - let p2 = read_point(&input[64..])?; + let p1 = match read_point(&input[..64]) { + Ok(point) => point, + Err(_) => return Err(Error::Bn128FieldPointNotAMember.into()), + }; + let p2 = match read_point(&input[64..]) { + Ok(point) => point, + Err(_) => return Err(Error::Bn128FieldPointNotAMember.into()), + }; let mut output = [0u8; 64]; if let Some(sum) = AffineG1::from_jacobian(p1 + p2) { sum.x().to_big_endian(&mut output[..32]).unwrap(); sum.y().to_big_endian(&mut output[32..]).unwrap(); } - Ok((gas_cost, output.into())) + PrecompileResult::ok(gas_cost, output.into()) } pub fn run_mul(input: &[u8], gas_cost: u64, gas_limit: u64) -> PrecompileResult { if gas_cost > gas_limit { - return Err(Error::OutOfGas); + return Err(Error::OutOfGas.into()); } let input = right_pad::(input); - let p = read_point(&input[..64])?; + let p = match read_point(&input[..64]) { + Ok(point) => point, + Err(_) => return Err(Error::Bn128FieldPointNotAMember.into()), + }; // `Fr::from_slice` can only fail when the length is not 32. let fr = bn::Fr::from_slice(&input[64..96]).unwrap(); @@ -155,7 +165,7 @@ pub fn run_mul(input: &[u8], gas_cost: u64, gas_limit: u64) -> PrecompileResult mul.x().to_big_endian(&mut output[..32]).unwrap(); mul.y().to_big_endian(&mut output[32..]).unwrap(); } - Ok((gas_cost, output.into())) + PrecompileResult::ok(gas_cost, output.into()) } pub fn run_pair( @@ -166,11 +176,11 @@ pub fn run_pair( ) -> PrecompileResult { let gas_used = (input.len() / PAIR_ELEMENT_LEN) as u64 * pair_per_point_cost + pair_base_cost; if gas_used > gas_limit { - return Err(Error::OutOfGas); + return Err(Error::OutOfGas.into()); } if input.len() % PAIR_ELEMENT_LEN != 0 { - return Err(Error::Bn128PairLength); + return Err(Error::Bn128PairLength.into()); } let success = if input.is_empty() { @@ -186,23 +196,48 @@ pub fn run_pair( // SAFETY: We're reading `6 * 32 == PAIR_ELEMENT_LEN` bytes from `input[idx..]` // per iteration. This is guaranteed to be in-bounds. let slice = unsafe { input.get_unchecked(start..start + 32) }; - Fq::from_slice(slice).map_err(|_| Error::Bn128FieldPointNotAMember) + Fq::from_slice(slice) + .map_err(|_| Err(Error::Bn128FieldPointNotAMember.into())) + }; + let ax = match read_fq_at(0) { + Ok(ax) => ax, + Err(err) => return err, + }; + let ay = match read_fq_at(1) { + Ok(ay) => ay, + Err(err) => return err, + }; + let bay = match read_fq_at(2) { + Ok(bay) => bay, + Err(err) => return err, + }; + let bax = match read_fq_at(3) { + Ok(bax) => bax, + Err(err) => return err, + }; + let bby = match read_fq_at(4) { + Ok(bby) => bby, + Err(err) => return err, + }; + let bbx = match read_fq_at(5) { + Ok(bbx) => bbx, + Err(err) => return err, + }; + + let a = match new_g1_point(ax, ay) { + Ok(a) => a, + Err(_) => return Err(Error::Bn128AffineGFailedToCreate.into()), }; - let ax = read_fq_at(0)?; - let ay = read_fq_at(1)?; - let bay = read_fq_at(2)?; - let bax = read_fq_at(3)?; - let bby = read_fq_at(4)?; - let bbx = read_fq_at(5)?; - - let a = new_g1_point(ax, ay)?; let b = { let ba = Fq2::new(bax, bay); let bb = Fq2::new(bbx, bby); if ba.is_zero() && bb.is_zero() { G2::zero() } else { - G2::from(AffineG2::new(ba, bb).map_err(|_| Error::Bn128AffineGFailedToCreate)?) + match AffineG2::new(ba, bb) { + Ok(affine_g2) => G2::from(affine_g2), + Err(_) => return Err(Error::Bn128AffineGFailedToCreate.into()), + } } }; @@ -211,7 +246,7 @@ pub fn run_pair( mul == Gt::one() }; - Ok((gas_used, bool_to_bytes32(success))) + PrecompileResult::ok(gas_used, bool_to_bytes32(success)) } #[cfg(test)] @@ -219,6 +254,7 @@ mod tests { use crate::bn128::add::BYZANTIUM_ADD_GAS_COST; use crate::bn128::mul::BYZANTIUM_MUL_GAS_COST; use crate::bn128::pair::{BYZANTIUM_PAIR_BASE, BYZANTIUM_PAIR_PER_POINT}; + use crate::PrecompileError; use revm_primitives::hex; use super::*; @@ -240,7 +276,7 @@ mod tests { ) .unwrap(); - let (_, res) = run_add(&input, BYZANTIUM_ADD_GAS_COST, 500).unwrap(); + let res = run_add(&input, BYZANTIUM_ADD_GAS_COST, 500).unwrap().output; assert_eq!(res, expected); // zero sum test @@ -259,7 +295,7 @@ mod tests { ) .unwrap(); - let (_, res) = run_add(&input, BYZANTIUM_ADD_GAS_COST, 500).unwrap(); + let res = run_add(&input, BYZANTIUM_ADD_GAS_COST, 500).unwrap().output; assert_eq!(res, expected); // out of gas test @@ -273,8 +309,13 @@ mod tests { .unwrap(); let res = run_add(&input, BYZANTIUM_ADD_GAS_COST, 499); - println!("{:?}", res); - assert!(matches!(res, Err(Error::OutOfGas))); + match res { + PrecompileResult::Ok { .. } => panic!("Expected an OutOfGas error, but got Ok"), + PrecompileResult::Error { error_type } => assert_eq!(error_type, Error::OutOfGas), + PrecompileResult::FatalError { msg } => { + panic!("Expected an OutOfGas error, but got FatalError: {:?}", msg) + } + } // no input test let input = [0u8; 0]; @@ -285,7 +326,7 @@ mod tests { ) .unwrap(); - let (_, res) = run_add(&input, BYZANTIUM_ADD_GAS_COST, 500).unwrap(); + let res = run_add(&input, BYZANTIUM_ADD_GAS_COST, 500).unwrap().output; assert_eq!(res, expected); // point not on curve fail @@ -299,7 +340,18 @@ mod tests { .unwrap(); let res = run_add(&input, BYZANTIUM_ADD_GAS_COST, 500); - assert!(matches!(res, Err(Error::Bn128AffineGFailedToCreate))); + match res { + PrecompileResult::Ok { .. } => { + panic!("Expected a Bn128AffineGFailedToCreate error, but got Ok") + } + PrecompileResult::Error { error_type } => { + assert_eq!(error_type, PrecompileError::Bn128FieldPointNotAMember) + } + PrecompileResult::FatalError { msg } => panic!( + "Expected a Bn128AffineGFailedToCreate error, but got FatalError: {:?}", + msg + ), + } } #[test] @@ -318,7 +370,7 @@ mod tests { ) .unwrap(); - let (_, res) = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 40_000).unwrap(); + let res = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 40_000).unwrap().output; assert_eq!(res, expected); // out of gas test @@ -331,7 +383,15 @@ mod tests { .unwrap(); let res = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 39_999); - assert!(matches!(res, Err(Error::OutOfGas))); + match res { + PrecompileResult::Ok { .. } => panic!("Expected an OutOfGas error, but got Ok"), + PrecompileResult::Error { error_type } => { + assert_eq!(error_type, PrecompileError::OutOfGas) + } + PrecompileResult::FatalError { msg } => { + panic!("Expected an OutOfGas error, but got FatalError: {:?}", msg) + } + } // zero multiplication test let input = hex::decode( @@ -348,7 +408,7 @@ mod tests { ) .unwrap(); - let (_, res) = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 40_000).unwrap(); + let res = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 40_000).unwrap().output; assert_eq!(res, expected); // no input test @@ -360,7 +420,7 @@ mod tests { ) .unwrap(); - let (_, res) = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 40_000).unwrap(); + let res = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 40_000).unwrap().output; assert_eq!(res, expected); // point not on curve fail @@ -373,7 +433,18 @@ mod tests { .unwrap(); let res = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 40_000); - assert!(matches!(res, Err(Error::Bn128AffineGFailedToCreate))); + match res { + PrecompileResult::Ok { .. } => { + panic!("Expected a Bn128AffineGFailedToCreate error, but got Ok") + } + PrecompileResult::Error { error_type } => { + assert_eq!(error_type, PrecompileError::Bn128FieldPointNotAMember) + } + PrecompileResult::FatalError { msg } => panic!( + "Expected a Bn128AffineGFailedToCreate error, but got FatalError: {:?}", + msg + ), + } } #[test] @@ -398,13 +469,13 @@ mod tests { hex::decode("0000000000000000000000000000000000000000000000000000000000000001") .unwrap(); - let (_, res) = run_pair( + let res = run_pair( &input, BYZANTIUM_PAIR_PER_POINT, BYZANTIUM_PAIR_BASE, 260_000, ) - .unwrap(); + .unwrap().output; assert_eq!(res, expected); // out of gas test @@ -425,13 +496,21 @@ mod tests { ) .unwrap(); - let res = run_pair( + let run_result = run_pair( &input, BYZANTIUM_PAIR_PER_POINT, BYZANTIUM_PAIR_BASE, 259_999, ); - assert!(matches!(res, Err(Error::OutOfGas))); + match run_result { + PrecompileResult::Ok { .. } => panic!("Expected an OutOfGas error, but got Ok"), + PrecompileResult::Error { error_type } => { + assert_eq!(error_type, PrecompileError::OutOfGas) + } + PrecompileResult::FatalError { msg } => { + panic!("Expected an OutOfGas error, but got FatalError: {:?}", msg) + } + } // no input test let input = [0u8; 0]; @@ -439,13 +518,13 @@ mod tests { hex::decode("0000000000000000000000000000000000000000000000000000000000000001") .unwrap(); - let (_, res) = run_pair( + let res = run_pair( &input, BYZANTIUM_PAIR_PER_POINT, BYZANTIUM_PAIR_BASE, 260_000, ) - .unwrap(); + .unwrap().output; assert_eq!(res, expected); // point not on curve fail @@ -460,13 +539,24 @@ mod tests { ) .unwrap(); - let res = run_pair( + let run_result = run_pair( &input, BYZANTIUM_PAIR_PER_POINT, BYZANTIUM_PAIR_BASE, 260_000, ); - assert!(matches!(res, Err(Error::Bn128AffineGFailedToCreate))); + match run_result { + PrecompileResult::Ok { .. } => { + panic!("Expected a Bn128AffineGFailedToCreate error, but got Ok") + } + PrecompileResult::Error { error_type } => { + assert_eq!(error_type, PrecompileError::Bn128AffineGFailedToCreate) + } + PrecompileResult::FatalError { msg } => panic!( + "Expected a Bn128AffineGFailedToCreate error, but got FatalError: {:?}", + msg + ), + } // invalid input length let input = hex::decode( @@ -478,12 +568,21 @@ mod tests { ) .unwrap(); - let res = run_pair( + let run_result = run_pair( &input, BYZANTIUM_PAIR_PER_POINT, BYZANTIUM_PAIR_BASE, 260_000, ); - assert!(matches!(res, Err(Error::Bn128PairLength))); + match run_result { + PrecompileResult::Ok { .. } => panic!("Expected a Bn128PairLength error, but got Ok"), + PrecompileResult::Error { error_type } => { + assert_eq!(error_type, PrecompileError::Bn128PairLength) + } + PrecompileResult::FatalError { msg } => panic!( + "Expected a Bn128PairLength error, but got FatalError: {:?}", + msg + ), + } } } diff --git a/crates/precompile/src/hash.rs b/crates/precompile/src/hash.rs index 9fc6a8ae49..316f6a25db 100644 --- a/crates/precompile/src/hash.rs +++ b/crates/precompile/src/hash.rs @@ -1,6 +1,6 @@ use super::calc_linear_cost_u32; use crate::{Error, Precompile, PrecompileResult, PrecompileWithAddress}; -use revm_primitives::Bytes; +use revm_primitives::{Bytes, PrecompileErrors}; use sha2::Digest; pub const SHA256: PrecompileWithAddress = @@ -17,10 +17,10 @@ pub const RIPEMD160: PrecompileWithAddress = PrecompileWithAddress( pub fn sha256_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { let cost = calc_linear_cost_u32(input.len(), 60, 12); if cost > gas_limit { - Err(Error::OutOfGas) + Err(Error::OutOfGas.into()) } else { let output = sha2::Sha256::digest(input); - Ok((cost, output.to_vec().into())) + PrecompileResult::ok(cost, output.to_vec().into()) } } @@ -30,13 +30,13 @@ pub fn sha256_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { pub fn ripemd160_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { let gas_used = calc_linear_cost_u32(input.len(), 600, 120); if gas_used > gas_limit { - Err(Error::OutOfGas) + Err(Error::OutOfGas.into()) } else { let mut hasher = ripemd::Ripemd160::new(); hasher.update(input); let mut output = [0u8; 32]; hasher.finalize_into((&mut output[12..]).into()); - Ok((gas_used, output.to_vec().into())) + PrecompileResult::ok(gas_used, output.to_vec().into()) } } diff --git a/crates/precompile/src/identity.rs b/crates/precompile/src/identity.rs index 85722ea810..2e303fd626 100644 --- a/crates/precompile/src/identity.rs +++ b/crates/precompile/src/identity.rs @@ -1,6 +1,6 @@ use super::calc_linear_cost_u32; use crate::{Error, Precompile, PrecompileResult, PrecompileWithAddress}; -use revm_primitives::Bytes; +use revm_primitives::{Bytes, PrecompileErrors}; pub const FUN: PrecompileWithAddress = PrecompileWithAddress(crate::u64_to_address(4), Precompile::Standard(identity_run)); @@ -19,5 +19,5 @@ pub fn identity_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { if gas_used > gas_limit { return Err(Error::OutOfGas); } - Ok((gas_used, input.clone())) + PrecompileResult::ok(gas_used, input.clone()) } diff --git a/crates/precompile/src/kzg_point_evaluation.rs b/crates/precompile/src/kzg_point_evaluation.rs index 5790186a99..fb67dc93a8 100644 --- a/crates/precompile/src/kzg_point_evaluation.rs +++ b/crates/precompile/src/kzg_point_evaluation.rs @@ -1,6 +1,6 @@ use crate::{Address, Error, Precompile, PrecompileResult, PrecompileWithAddress}; use c_kzg::{Bytes32, Bytes48, KzgProof, KzgSettings}; -use revm_primitives::{hex_literal::hex, Bytes, Env}; +use revm_primitives::{hex_literal::hex, Bytes, Env, PrecompileErrors}; use sha2::{Digest, Sha256}; pub const POINT_EVALUATION: PrecompileWithAddress = @@ -26,19 +26,19 @@ pub const RETURN_VALUE: &[u8; 64] = &hex!( /// with z and y being padded 32 byte big endian values pub fn run(input: &Bytes, gas_limit: u64, env: &Env) -> PrecompileResult { if gas_limit < GAS_COST { - return Err(Error::OutOfGas); + return Err(Error::OutOfGas.into()); } // Verify input length. if input.len() != 192 { - return Err(Error::BlobInvalidInputLength); + return Err(Error::BlobInvalidInputLength.into()); } // Verify commitment matches versioned_hash let versioned_hash = &input[..32]; let commitment = &input[96..144]; if kzg_to_versioned_hash(commitment) != versioned_hash { - return Err(Error::BlobMismatchedVersion); + return Err(Error::BlobMismatchedVersion.into()); } // Verify KZG proof with z and y in big endian format @@ -47,11 +47,11 @@ pub fn run(input: &Bytes, gas_limit: u64, env: &Env) -> PrecompileResult { let y = as_bytes32(&input[64..96]); let proof = as_bytes48(&input[144..192]); if !verify_kzg_proof(commitment, z, y, proof, env.cfg.kzg_settings.get()) { - return Err(Error::BlobVerifyKzgProofFailed); + return Err(Error::BlobVerifyKzgProofFailed.into()); } // Return FIELD_ELEMENTS_PER_BLOB and BLS_MODULUS as padded 32 byte big endian values - Ok((GAS_COST, RETURN_VALUE.into())) + PrecompileResult::ok(GAS_COST, RETURN_VALUE.into()) } /// `VERSIONED_HASH_VERSION_KZG ++ sha256(commitment)[1..]` @@ -113,8 +113,18 @@ mod tests { let expected_output = hex!("000000000000000000000000000000000000000000000000000000000000100073eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001"); let gas = 50000; let env = Env::default(); - let (actual_gas, actual_output) = run(&input.into(), gas, &env).unwrap(); - assert_eq!(actual_gas, gas); - assert_eq!(actual_output[..], expected_output); + let run_result = run(&input.into(), gas, &env); + match run_result { + PrecompileResult::Ok { gas_used, output } => { + assert_eq!(gas_used, gas); + assert_eq!(output[..], expected_output); + } + PrecompileResult::Error { error_type } => { + panic!("run failed with error: {:?}", error_type) + } + PrecompileResult::FatalError { msg } => { + panic!("run failed with fatal error: {:?}", msg) + } + } } } diff --git a/crates/precompile/src/modexp.rs b/crates/precompile/src/modexp.rs index a55b445912..95ef2c68db 100644 --- a/crates/precompile/src/modexp.rs +++ b/crates/precompile/src/modexp.rs @@ -5,7 +5,7 @@ use crate::{ }; use aurora_engine_modexp::modexp; use core::cmp::{max, min}; -use revm_primitives::Bytes; +use revm_primitives::{Bytes, PrecompileErrors}; pub const BYZANTIUM: PrecompileWithAddress = PrecompileWithAddress( crate::u64_to_address(5), @@ -50,7 +50,7 @@ where { // If there is no minimum gas, return error. if min_gas > gas_limit { - return Err(Error::OutOfGas); + return Err(Error::OutOfGas.into()); } // The format of input is: @@ -66,20 +66,20 @@ where // cast base and modulus to usize, it does not make sense to handle larger values let Ok(base_len) = usize::try_from(base_len) else { - return Err(Error::ModexpBaseOverflow); + return Err(Error::ModexpBaseOverflow.into()); }; let Ok(mod_len) = usize::try_from(mod_len) else { - return Err(Error::ModexpModOverflow); + return Err(Error::ModexpModOverflow.into()); }; // Handle a special case when both the base and mod length are zero. if base_len == 0 && mod_len == 0 { - return Ok((min_gas, Bytes::new())); + return PrecompileResult::ok(min_gas, Bytes::new()); } // Cast exponent length to usize, since it does not make sense to handle larger values. let Ok(exp_len) = usize::try_from(exp_len) else { - return Err(Error::ModexpModOverflow); + return Err(Error::ModexpModOverflow.into()); }; // Used to extract ADJUSTED_EXPONENT_LENGTH. @@ -99,7 +99,7 @@ where // Check if we have enough gas. let gas_cost = calc_gas(base_len as u64, exp_len as u64, mod_len as u64, &exp_highp); if gas_cost > gas_limit { - return Err(Error::OutOfGas); + return Err(Error::OutOfGas.into()); } // Padding is needed if the input does not contain all 3 values. @@ -113,7 +113,7 @@ where let output = modexp(base, exponent, modulus); // left pad the result to modulus length. bytes will always by less or equal to modulus length. - Ok((gas_cost, left_pad_vec(&output, mod_len).into_owned().into())) + PrecompileResult::ok(gas_cost, left_pad_vec(&output, mod_len).into_owned().into()) } pub fn byzantium_gas_calc(base_len: u64, exp_len: u64, mod_len: u64, exp_highp: &U256) -> u64 { @@ -347,14 +347,24 @@ mod tests { fn test_byzantium_modexp_gas() { for (test, &test_gas) in TESTS.iter().zip(BYZANTIUM_GAS.iter()) { let input = hex::decode(test.input).unwrap().into(); - let res = byzantium_run(&input, 100_000_000).unwrap(); - let expected = hex::decode(test.expected).unwrap(); - assert_eq!( - res.0, test_gas, - "used gas not matching for test: {}", - test.name - ); - assert_eq!(res.1, expected, "test:{}", test.name); + let run_result = byzantium_run(&input, 100_000_000); + match run_result { + PrecompileResult::Ok { gas_used, output } => { + let expected = hex::decode(test.expected).unwrap(); + assert_eq!( + gas_used, test_gas, + "used gas not matching for test: {}", + test.name + ); + assert_eq!(output, expected, "test:{}", test.name); + } + PrecompileResult::Error { error_type } => { + panic!("byzantium_run failed with error: {:?}", error_type) + } + PrecompileResult::FatalError { msg } => { + panic!("byzantium_run failed with fatal error: {:?}", msg) + } + } } } @@ -362,21 +372,44 @@ mod tests { fn test_berlin_modexp_gas() { for (test, &test_gas) in TESTS.iter().zip(BERLIN_GAS.iter()) { let input = hex::decode(test.input).unwrap().into(); - let res = berlin_run(&input, 100_000_000).unwrap(); - let expected = hex::decode(test.expected).unwrap(); - assert_eq!( - res.0, test_gas, - "used gas not matching for test: {}", - test.name - ); - assert_eq!(res.1, expected, "test:{}", test.name); + let run_result = berlin_run(&input, 100_000_000); + match run_result { + PrecompileResult::Ok { gas_used, output } => { + let expected = hex::decode(test.expected).unwrap(); + assert_eq!( + gas_used, test_gas, + "used gas not matching for test: {}", + test.name + ); + assert_eq!(output, expected, "test:{}", test.name); + } + PrecompileResult::Error { error_type } => { + panic!("berlin_run failed with error: {:?}", error_type) + } + PrecompileResult::FatalError { msg } => { + panic!("berlin_run failed with fatal error: {:?}", msg) + } + } } } #[test] fn test_berlin_modexp_empty_input() { - let res = berlin_run(&Bytes::new(), 100_000).unwrap(); - let expected: Vec = Vec::new(); - assert_eq!(res.1, expected) + let run_result = berlin_run(&Bytes::new(), 100_000); + match run_result { + PrecompileResult::Ok { + gas_used: _, + output, + } => { + let expected: Vec = Vec::new(); + assert_eq!(output, expected); + } + PrecompileResult::Error { error_type } => { + panic!("berlin_run failed with error: {:?}", error_type) + } + PrecompileResult::FatalError { msg } => { + panic!("berlin_run failed with fatal error: {:?}", msg) + } + } } } diff --git a/crates/precompile/src/secp256k1.rs b/crates/precompile/src/secp256k1.rs index 4ad079e1e7..9b16f635c4 100644 --- a/crates/precompile/src/secp256k1.rs +++ b/crates/precompile/src/secp256k1.rs @@ -70,14 +70,14 @@ pub fn ec_recover_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { const ECRECOVER_BASE: u64 = 3_000; if ECRECOVER_BASE > gas_limit { - return Err(Error::OutOfGas); + return Err(Error::OutOfGas.into()); } let input = right_pad::<128>(input); // `v` must be a 32-byte big-endian integer equal to 27 or 28. if !(input[32..63].iter().all(|&b| b == 0) && matches!(input[63], 27 | 28)) { - return Ok((ECRECOVER_BASE, Bytes::new())); + return PrecompileResult::ok(ECRECOVER_BASE, Bytes::new()); } let msg = <&B256>::try_from(&input[0..32]).unwrap(); @@ -87,5 +87,5 @@ pub fn ec_recover_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { let out = secp256k1::ecrecover(sig, recid, msg) .map(|o| o.to_vec().into()) .unwrap_or_default(); - Ok((ECRECOVER_BASE, out)) + PrecompileResult::ok(ECRECOVER_BASE, out) } diff --git a/crates/primitives/src/precompile.rs b/crates/primitives/src/precompile.rs index e585377537..ba014e73ea 100644 --- a/crates/primitives/src/precompile.rs +++ b/crates/primitives/src/precompile.rs @@ -2,11 +2,37 @@ use crate::{Bytes, Env}; use core::fmt; use dyn_clone::DynClone; use std::{boxed::Box, string::String, sync::Arc}; +use revm_precompile::PrecompileOutput; /// A precompile operation result. /// /// Returns either `Ok((gas_used, return_bytes))` or `Err(error)`. -pub type PrecompileResult = Result<(u64, Bytes), PrecompileError>; +#[derive(Debug)] +pub enum PrecompileErrors { + Error(PrecompileError), + Fatal { + msg: String + }, +} + +pub type PrecompileResult = Result; + +impl PrecompileErrors { + pub fn err(err: PrecompileError) -> PrecompileResult { + Err(PrecompileErrors::Error(err)) + } + pub fn fatal_error(msg: impl Into) -> PrecompileResult { + Err(PrecompileErrors::Fatal { + msg: msg.into() + }) + } +} + +impl From for PrecompileErrors { + fn from(err: PrecompileError) -> Self { + PrecompileErrors::Error(err) + } +} pub type StandardPrecompileFn = fn(&Bytes, u64) -> PrecompileResult; pub type EnvPrecompileFn = fn(&Bytes, u64, env: &Env) -> PrecompileResult; @@ -175,7 +201,7 @@ mod test { _gas_price: u64, _env: &Env, ) -> PrecompileResult { - PrecompileResult::Err(PrecompileError::OutOfGas) + Err(PrecompileError::OutOfGas.into()) } } diff --git a/crates/revm/src/builder.rs b/crates/revm/src/builder.rs index 4b2a81ec4f..b9d9a03656 100644 --- a/crates/revm/src/builder.rs +++ b/crates/revm/src/builder.rs @@ -614,7 +614,7 @@ mod test { _gas_price: u64, _context: &mut InnerEvmContext, ) -> PrecompileResult { - Ok((10, Bytes::new())) + PrecompileResult::ok(10, Bytes::new()) } } diff --git a/crates/revm/src/context/evm_context.rs b/crates/revm/src/context/evm_context.rs index b92d711da8..c560584e93 100644 --- a/crates/revm/src/context/evm_context.rs +++ b/crates/revm/src/context/evm_context.rs @@ -1,4 +1,5 @@ use revm_interpreter::CallValue; +use revm_precompile::PrecompileResult; use super::inner_evm_context::InnerEvmContext; use crate::{ @@ -119,21 +120,24 @@ impl EvmContext { }; match out { - Ok((gas_used, data)) => { + PrecompileResult::Ok { gas_used, output } => { if result.gas.record_cost(gas_used) { result.result = InstructionResult::Return; - result.output = data; + result.output = output; } else { result.result = InstructionResult::PrecompileOOG; } } - Err(e) => { - result.result = if e == crate::precompile::Error::OutOfGas { + PrecompileResult::Error { error_type } => { + result.result = if error_type == crate::precompile::Error::OutOfGas { InstructionResult::PrecompileOOG } else { InstructionResult::PrecompileError }; } + PrecompileResult::FatalError { msg: _ } => { + result.result = InstructionResult::FatalExternalError; + } } Some(result) }