Skip to content

Commit

Permalink
feat(client): Re-accelerate precompiles (#866)
Browse files Browse the repository at this point in the history
* feat(client): Re-accelerate precompiles

* fix: lint

---------

Co-authored-by: refcell <[email protected]>
  • Loading branch information
clabby and refcell authored Dec 4, 2024
1 parent cb39d1b commit f2b634f
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 189 deletions.
45 changes: 23 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion bin/client/src/kona.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use kona_preimage::{HintWriter, OracleReader};
use kona_std_fpvm::{FileChannel, FileDescriptor};
use kona_std_fpvm_proc::client_entry;

mod precompiles;

/// The global preimage oracle reader pipe.
static ORACLE_READER_PIPE: FileChannel =
FileChannel::new(FileDescriptor::PreimageRead, FileDescriptor::PreimageWrite);
Expand All @@ -37,5 +39,9 @@ fn main() -> Result<(), String> {
.expect("Failed to set tracing subscriber");
}

kona_proof::block_on(kona_client::run(ORACLE_READER, HINT_WRITER))
kona_proof::block_on(kona_client::run(
ORACLE_READER,
HINT_WRITER,
Some(precompiles::fpvm_handle_register),
))
}
22 changes: 13 additions & 9 deletions bin/client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![warn(missing_debug_implementations, missing_docs, unreachable_pub, rustdoc::all)]
#![deny(unused_must_use, rust_2018_idioms)]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
#![allow(clippy::type_complexity)]
#![no_std]

extern crate alloc;
Expand All @@ -11,7 +12,7 @@ use alloy_consensus::{Header, Sealed};
use alloy_primitives::B256;
use core::fmt::Debug;
use kona_driver::{Driver, DriverError};
use kona_executor::{ExecutorError, TrieDBProvider};
use kona_executor::{ExecutorError, KonaHandleRegister, TrieDBProvider};
use kona_preimage::{
CommsClient, HintWriterClient, PreimageKey, PreimageKeyType, PreimageOracleClient,
};
Expand All @@ -26,12 +27,6 @@ use kona_proof::{
use thiserror::Error;
use tracing::{error, info, warn};

mod precompiles;
pub use precompiles::{
EcPairingAccelerated, EcPairingAcceleratedGranite, EcRecoverAccelerated,
KZGPointEvalAccelerated, ECPAIRING_ADDRESS, ECRECOVER_ADDRESS, POINT_EVAL_ADDRESS,
};

/// An error that can occur when running the fault proof program.
#[derive(Error, Debug)]
pub enum FaultProofProgramError {
Expand All @@ -48,7 +43,16 @@ pub enum FaultProofProgramError {

/// Executes the fault proof program with the given [PreimageOracleClient] and [HintWriterClient].
#[inline]
pub async fn run<P, H>(oracle_client: P, hint_client: H) -> Result<(), FaultProofProgramError>
pub async fn run<P, H>(
oracle_client: P,
hint_client: H,
handle_register: Option<
KonaHandleRegister<
OracleL2ChainProvider<CachingOracle<P, H>>,
OracleL2ChainProvider<CachingOracle<P, H>>,
>,
>,
) -> Result<(), FaultProofProgramError>
where
P: PreimageOracleClient + Send + Sync + Debug + Clone,
H: HintWriterClient + Send + Sync + Debug + Clone,
Expand Down Expand Up @@ -112,7 +116,7 @@ where
l1_provider.clone(),
l2_provider.clone(),
);
let executor = KonaExecutor::new(&cfg, l2_provider.clone(), l2_provider, None, None);
let executor = KonaExecutor::new(&cfg, l2_provider.clone(), l2_provider, handle_register, None);
let mut driver = Driver::new(cursor, executor, pipeline);

// Run the derivation pipeline until we are able to produce the output root of the claimed
Expand Down
89 changes: 18 additions & 71 deletions bin/client/src/precompiles/bn128_pair.rs
Original file line number Diff line number Diff line change
@@ -1,82 +1,32 @@
//! Contains the accelerated version of the `ecPairing` precompile.
use alloc::{string::ToString, sync::Arc, vec::Vec};
use crate::{HINT_WRITER, ORACLE_READER};
use alloc::{string::ToString, vec::Vec};
use alloy_primitives::{keccak256, Address, Bytes};
use kona_preimage::{errors::PreimageOracleError, CommsClient, PreimageKey, PreimageKeyType};
use kona_preimage::{
errors::PreimageOracleError, HintWriterClient, PreimageKey, PreimageKeyType,
PreimageOracleClient,
};
use kona_proof::{errors::OracleProviderError, HintType};
use revm::{
precompile::{
bn128::pair::{ISTANBUL_PAIR_BASE, ISTANBUL_PAIR_PER_POINT},
u64_to_address, Error as PrecompileError,
u64_to_address, Error as PrecompileError, PrecompileWithAddress,
},
primitives::{PrecompileOutput, PrecompileResult, StatefulPrecompile},
primitives::{Precompile, PrecompileOutput, PrecompileResult},
};

/// The address of the `ecPairing` precompile.
pub const ECPAIRING_ADDRESS: Address = u64_to_address(8);

/// The length of a single pair element.
const ECPAIRING_ADDRESS: Address = u64_to_address(8);
const PAIR_ELEMENT_LEN: usize = 64 + 128;

/// An accelerated version of the `ecPairing` precompile that calls out to the host for the
/// result of the precompile execution.
#[derive(Debug)]
pub struct EcPairingAccelerated<C>
where
C: CommsClient,
{
/// The comms client.
comms_client: Arc<C>,
}

impl<C> EcPairingAccelerated<C>
where
C: CommsClient,
{
/// Creates a new [EcPairingAccelerated] instance.
pub fn new(comms_client: Arc<C>) -> Self {
Self { comms_client }
}
}

impl<C> StatefulPrecompile for EcPairingAccelerated<C>
where
C: CommsClient + Send + Sync,
{
fn call(&self, input: &Bytes, gas_limit: u64, _: &revm::primitives::Env) -> PrecompileResult {
fpvm_ecpairing(self.comms_client.as_ref(), input, gas_limit)
}
}

/// An accelerated version of the `ecPairing` precompile that calls out to the host for the
/// result of the precompile execution after the Granite hardfork.
#[derive(Debug)]
pub struct EcPairingAcceleratedGranite<C> {
/// The comms client.
comms_client: Arc<C>,
}

impl<C> EcPairingAcceleratedGranite<C> {
/// Creates a new [EcPairingAcceleratedGranite] instance.
pub fn new(comms_client: Arc<C>) -> Self {
Self { comms_client }
}
}
pub(crate) const FPVM_ECPAIRING: PrecompileWithAddress =
PrecompileWithAddress(ECPAIRING_ADDRESS, Precompile::Standard(fpvm_ecpairing));

impl<C> StatefulPrecompile for EcPairingAcceleratedGranite<C>
where
C: CommsClient + Send + Sync,
{
fn call(&self, input: &Bytes, gas_limit: u64, _: &revm::primitives::Env) -> PrecompileResult {
fpvm_ecpairing_granite(self.comms_client.as_ref(), input, gas_limit)
}
}
pub(crate) const FPVM_ECPAIRING_GRANITE: PrecompileWithAddress =
PrecompileWithAddress(ECPAIRING_ADDRESS, Precompile::Standard(fpvm_ecpairing_granite));

/// Performs an FPVM-accelerated `ecpairing` precompile call.
fn fpvm_ecpairing<C>(comms_client: &C, input: &Bytes, gas_limit: u64) -> PrecompileResult
where
C: CommsClient,
{
fn fpvm_ecpairing(input: &Bytes, gas_limit: u64) -> PrecompileResult {
let gas_used =
(input.len() / PAIR_ELEMENT_LEN) as u64 * ISTANBUL_PAIR_PER_POINT + ISTANBUL_PAIR_BASE;

Expand All @@ -91,7 +41,7 @@ where
let result_data = kona_proof::block_on(async move {
// Write the hint for the ecrecover precompile run.
let hint_data = &[ECPAIRING_ADDRESS.as_ref(), input.as_ref()];
comms_client
HINT_WRITER
.write(&HintType::L1Precompile.encode_with(hint_data))
.await
.map_err(OracleProviderError::Preimage)?;
Expand All @@ -101,7 +51,7 @@ where
let key_hash = keccak256(&raw_key_data);

// Fetch the result of the ecrecover precompile run from the host.
let result_data = comms_client
let result_data = ORACLE_READER
.get(PreimageKey::new(*key_hash, PreimageKeyType::Precompile))
.await
.map_err(OracleProviderError::Preimage)?;
Expand Down Expand Up @@ -129,14 +79,11 @@ where
}

/// Performs an FPVM-accelerated `ecpairing` precompile call after the Granite hardfork.
fn fpvm_ecpairing_granite<C>(comms_client: &C, input: &Bytes, gas_limit: u64) -> PrecompileResult
where
C: CommsClient,
{
fn fpvm_ecpairing_granite(input: &Bytes, gas_limit: u64) -> PrecompileResult {
const BN256_MAX_PAIRING_SIZE_GRANITE: usize = 112_687;
if input.len() > BN256_MAX_PAIRING_SIZE_GRANITE {
return Err(PrecompileError::Bn128PairLength.into());
}

fpvm_ecpairing(comms_client, input, gas_limit)
fpvm_ecpairing(input, gas_limit)
}
Loading

0 comments on commit f2b634f

Please sign in to comment.