Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: bls12-381 g1_add precompile #17

Merged
merged 18 commits into from
Mar 22, 2024
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
26 changes: 26 additions & 0 deletions Cargo.lock

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

41 changes: 13 additions & 28 deletions crates/instructions/src/eip3074.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::InstructionWithOpCode;
use revm::{Database, Evm};
use revm_interpreter::{
gas::memory_gas, next_multiple_of_32, Instruction, InstructionResult, Interpreter,
};
use revm_interpreter::{gas::memory_gas, next_multiple_of_32, InstructionResult, Interpreter};
use revm_primitives::{alloy_primitives::B512, keccak256, Address, B256};
use secp256k1::{
ecdsa::{RecoverableSignature, RecoveryId},
Expand All @@ -15,21 +14,17 @@ const WARM_AUTHORITY_GAS: u64 = 100;
const COLD_AUTHORITY_GAS: u64 = 2600;
const FIXED_FEE_GAS: u64 = 3100;

/// Type alias for a function pointer that initializes instruction objects.
pub type InstructionInitializer<'a, EXT, DB> = fn() -> InstructionWithOpCode<Evm<'a, EXT, DB>>;

/// Constructs and returns a collection of instruction initializers.
pub fn initializers<'a, EXT, DB: Database>() -> Vec<InstructionInitializer<'a, EXT, DB>> {
vec![auth::<EXT, DB>, authcall::<EXT, DB>]
}

/// Association of OpCode and correspondent instruction.
#[derive(Clone, Debug)]
pub struct InstructionWithOpCode<H> {
/// Opcode.
pub opcode: u8,
/// Instruction.
pub instruction: Instruction<H>,
/// eip3074 instructions.
pub fn instructions<'a, EXT: 'a, DB: Database + 'a>(
) -> impl Iterator<Item = InstructionWithOpCode<Evm<'a, EXT, DB>>> {
[
InstructionWithOpCode { opcode: AUTH_OPCODE, instruction: auth_instruction::<EXT, DB> },
InstructionWithOpCode {
opcode: AUTHCALL_OPCODE,
instruction: authcall_instruction::<EXT, DB>,
},
]
.into_iter()
}

// TODO: use ecrecover from revm-precompile::secp256k1.
Expand Down Expand Up @@ -138,20 +133,10 @@ fn auth_instruction<EXT, DB: Database>(interp: &mut Interpreter, evm: &mut Evm<'
}
}

/// AUTH's opcode and instruction.
pub fn auth<'a, EXT, DB: Database>() -> InstructionWithOpCode<Evm<'a, EXT, DB>> {
InstructionWithOpCode { opcode: AUTH_OPCODE, instruction: auth_instruction::<EXT, DB> }
}

fn authcall_instruction<EXT, DB: Database>(interp: &mut Interpreter, _evm: &mut Evm<'_, EXT, DB>) {
interp.gas.record_cost(133);
}

/// AUTHCALL's opcode and instruction.
pub fn authcall<'a, EXT, DB: Database>() -> InstructionWithOpCode<Evm<'a, EXT, DB>> {
InstructionWithOpCode { opcode: AUTHCALL_OPCODE, instruction: authcall_instruction::<EXT, DB> }
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
11 changes: 11 additions & 0 deletions crates/instructions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,16 @@
//!
//! Custom instructions for Alphanet.

use revm_interpreter::Instruction;

/// EIP-3074 custom instructions.
pub mod eip3074;

/// Association of OpCode and correspondent instruction.
#[derive(Clone, Debug)]
pub struct InstructionWithOpCode<H> {
/// Opcode.
pub opcode: u8,
/// Instruction.
pub instruction: Instruction<H>,
}
2 changes: 2 additions & 0 deletions crates/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ alphanet-instructions.workspace = true
reth.workspace = true
reth-node-api.workspace = true
reth-node-optimism.workspace = true
revm-interpreter.workspace = true
revm-precompile.workspace = true

[lints]
workspace = true
38 changes: 29 additions & 9 deletions crates/node/src/evm.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use alphanet_instructions::eip3074;
use alphanet_precompile::secp256r1::P256VERIFY;
use alphanet_instructions::{eip3074, InstructionWithOpCode};
use alphanet_precompile::{bls12_381, secp256r1};
use reth::{
primitives::{
revm::{config::revm_spec, env::fill_op_tx_env},
Expand All @@ -13,13 +13,36 @@ use reth::{
},
};
use reth_node_api::{ConfigureEvm, ConfigureEvmEnv};
use revm_interpreter::{opcode::InstructionTables, Host};
use revm_precompile::PrecompileWithAddress;
use std::sync::Arc;

/// Custom EVM configuration
#[derive(Debug, Clone, Copy, Default)]
#[non_exhaustive]
pub struct AlphaNetEvmConfig;

// Inserts the given precompiles with address in the context precompiles.
fn insert_precompiles<I>(precompiles: &mut Precompiles, precompiles_with_address: I)
where
I: Iterator<Item = PrecompileWithAddress>,
{
for precompile_with_address in precompiles_with_address {
precompiles.inner.insert(precompile_with_address.0, precompile_with_address.1);
}
}

// Inserts the given instructions with opcodes in the instructions table.
fn insert_instructions<'a, I, H>(table: &mut InstructionTables<'a, H>, instructions_with_opcodes: I)
where
I: Iterator<Item = InstructionWithOpCode<H>>,
H: Host + 'a,
{
for instruction_with_opcode in instructions_with_opcodes {
table.insert(instruction_with_opcode.opcode, instruction_with_opcode.instruction);
}
}

impl AlphaNetEvmConfig {
/// Sets the precompiles to the EVM handler
///
Expand All @@ -37,7 +60,9 @@ impl AlphaNetEvmConfig {
// install the precompiles
handler.pre_execution.load_precompiles = Arc::new(move || {
let mut precompiles = Precompiles::new(PrecompileSpecId::from_spec_id(spec_id)).clone();
precompiles.inner.insert(P256VERIFY.0, P256VERIFY.1);
insert_precompiles(&mut precompiles, secp256r1::precompiles());
insert_precompiles(&mut precompiles, bls12_381::precompiles());

precompiles.into()
});
}
Expand All @@ -53,12 +78,7 @@ impl AlphaNetEvmConfig {
DB: Database,
{
if let Some(ref mut table) = handler.instruction_table {
let eip3074_initializers = eip3074::initializers::<EXT, DB>();

for init in eip3074_initializers {
let instruction_with_opcode = init();
table.insert(instruction_with_opcode.opcode, instruction_with_opcode.instruction);
}
insert_instructions(table, eip3074::instructions());
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/precompile/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ keywords.workspace = true
categories.workspace = true

[dependencies]
bls12_381 = "0.8.0"
p256 = { version = "0.13.2", features = ["ecdsa"] }
revm-precompile.workspace = true
revm-primitives.workspace = true
Expand Down
12 changes: 12 additions & 0 deletions crates/precompile/src/addresses.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//! Constants for the addresses used for each of the precompiled contracts.

pub(crate) const BLS12_G1ADD_ADDRESS: u64 = 0x0b;
pub(crate) const BLS12_G1MUL_ADDRESS: u64 = 0x0c;
pub(crate) const BLS12_G1MULTIEXP_ADDRESS: u64 = 0x0d;
pub(crate) const BLS12_G2ADD_ADDRESS: u64 = 0x0e;
pub(crate) const BLS12_G2MUL_ADDRESS: u64 = 0x0f;
pub(crate) const BLS12_G2MULTIEXP_ADDRESS: u64 = 0x10;
pub(crate) const BLS12_PAIRING_ADDRESS: u64 = 0x11;
pub(crate) const BLS12_MAP_FP_TO_G1_ADDRESS: u64 = 0x12;
pub(crate) const BLS12_MAP_FP2_TO_G2_ADDRESS: u64 = 0x13;
pub(crate) const P256VERIFY_ADDRESS: u64 = 0x14;
fgimenez marked this conversation as resolved.
Show resolved Hide resolved
Loading