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
8 changes: 7 additions & 1 deletion src/precompile/bn128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub mod pair {
const BN128_PAIRING_PRECOMPILE_INDEX: u64 = 8;

/// The BN128 pairing precompile address.
const BN128_PAIRING_PRECOMPILE_ADDRESS: Address =
pub const BN128_PAIRING_PRECOMPILE_ADDRESS: Address =
u64_to_address(BN128_PAIRING_PRECOMPILE_INDEX);

/// The number of pairing inputs per pairing operation. If the inputs provided to the precompile
Expand Down Expand Up @@ -48,4 +48,10 @@ pub mod pair {
}
run_pair(input, ISTANBUL_PAIR_PER_POINT, ISTANBUL_PAIR_BASE, gas_limit)
}

/// The BN128 PAIRING precompile with address.
pub const FEYNMAN: PrecompileWithAddress =
PrecompileWithAddress(BN128_PAIRING_PRECOMPILE_ADDRESS, |input, gas_limit| {
run_pair(input, ISTANBUL_PAIR_PER_POINT, ISTANBUL_PAIR_BASE, gas_limit)
});
}
40 changes: 39 additions & 1 deletion src/precompile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ impl ScrollPrecompileProvider {
let precompiles = match spec {
ScrollSpecId::SHANGHAI => pre_bernoulli(),
ScrollSpecId::BERNOULLI | ScrollSpecId::CURIE | ScrollSpecId::DARWIN => bernoulli(),
ScrollSpecId::EUCLID | ScrollSpecId::FEYNMAN => euclid(),
ScrollSpecId::EUCLID => euclid(),
ScrollSpecId::FEYNMAN => feynman(),
};
Self { precompile_provider: EthPrecompiles { precompiles, spec: SpecId::default() }, spec }
}
Expand Down Expand Up @@ -91,6 +92,16 @@ pub(crate) fn euclid() -> &'static Precompiles {
})
}

/// Returns precompiles for Feynman spec.
pub(crate) fn feynman() -> &'static Precompiles {
static INSTANCE: OnceBox<Precompiles> = OnceBox::new();
INSTANCE.get_or_init(|| {
let mut precompiles = euclid().clone();
precompiles.extend([bn128::pair::FEYNMAN]);
Box::new(precompiles)
})
}

impl<CTX> PrecompileProvider<CTX> for ScrollPrecompileProvider
where
CTX: ContextTr<Cfg: Cfg<Spec = ScrollSpecId>>,
Expand Down Expand Up @@ -134,3 +145,30 @@ impl Default for ScrollPrecompileProvider {
Self::new_with_spec(ScrollSpecId::default())
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::precompile::bn128::pair::BN128_PAIRING_PRECOMPILE_ADDRESS;
use revm::primitives::hex;

#[test]
fn test_bn128_large_input() {
// test case copied from geth
let input = hex::decode("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d").unwrap();

let expected =
hex::decode("0000000000000000000000000000000000000000000000000000000000000001")
.unwrap();

// Euclid version should reject this input
let f = euclid().get(&BN128_PAIRING_PRECOMPILE_ADDRESS).expect("precompile exists");
let outcome = f(&input, u64::MAX);
assert!(outcome.is_err());

// Feynman version should accept this input
let f = feynman().get(&BN128_PAIRING_PRECOMPILE_ADDRESS).expect("precompile exists");
let outcome = f(&input, u64::MAX).expect("call succeeds");
assert_eq!(outcome.bytes, expected);
}
}