mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-03 22:33:06 +00:00
More constants for kernel ASM
- `GlobalMetadata` - offsets for global kernel variables in memory - `ContextMetadata` - offsets for context-specific kernel variables in memory - `GAS_CONSTANTS`, based on the yellowpaper Also move constants to a separate module since `aggregator` was getting long.
This commit is contained in:
parent
94c9b1b09c
commit
3f08cca116
@ -1,49 +1,14 @@
|
||||
//! Loads each kernel assembly file and concatenates them.
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use ethereum_types::U256;
|
||||
use hex_literal::hex;
|
||||
use itertools::Itertools;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use super::assembler::{assemble, Kernel};
|
||||
use crate::cpu::kernel::constants::evm_constants;
|
||||
use crate::cpu::kernel::parser::parse;
|
||||
use crate::cpu::kernel::txn_fields::NormalizedTxnField;
|
||||
use crate::memory::segments::Segment;
|
||||
|
||||
pub static KERNEL: Lazy<Kernel> = Lazy::new(combined_kernel);
|
||||
|
||||
const EC_CONSTANTS: [(&str, [u8; 32]); 3] = [
|
||||
(
|
||||
"BN_BASE",
|
||||
hex!("30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"),
|
||||
),
|
||||
(
|
||||
"SECP_BASE",
|
||||
hex!("fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),
|
||||
),
|
||||
(
|
||||
"SECP_SCALAR",
|
||||
hex!("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),
|
||||
),
|
||||
];
|
||||
|
||||
pub fn evm_constants() -> HashMap<String, U256> {
|
||||
let mut c = HashMap::new();
|
||||
for (name, value) in EC_CONSTANTS {
|
||||
c.insert(name.into(), U256::from_big_endian(&value));
|
||||
}
|
||||
for segment in Segment::all() {
|
||||
c.insert(segment.var_name().into(), (segment as u32).into());
|
||||
}
|
||||
for txn_field in NormalizedTxnField::all() {
|
||||
c.insert(txn_field.var_name().into(), (txn_field as u32).into());
|
||||
}
|
||||
c
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // TODO: Should be used once witness generation is done.
|
||||
pub(crate) fn combined_kernel() -> Kernel {
|
||||
let files = vec![
|
||||
include_str!("asm/curve/bn254/curve_add.asm"),
|
||||
|
||||
87
evm/src/cpu/kernel/constants.rs
Normal file
87
evm/src/cpu/kernel/constants.rs
Normal file
@ -0,0 +1,87 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use ethereum_types::U256;
|
||||
use hex_literal::hex;
|
||||
|
||||
use crate::cpu::kernel::context_metadata::ContextMetadata;
|
||||
use crate::cpu::kernel::global_metadata::GlobalMetadata;
|
||||
use crate::cpu::kernel::txn_fields::NormalizedTxnField;
|
||||
use crate::memory::segments::Segment;
|
||||
|
||||
/// Constants that are accessible to our kernel assembly code.
|
||||
pub fn evm_constants() -> HashMap<String, U256> {
|
||||
let mut c = HashMap::new();
|
||||
for (name, value) in EC_CONSTANTS {
|
||||
c.insert(name.into(), U256::from_big_endian(&value));
|
||||
}
|
||||
for (name, value) in GAS_CONSTANTS {
|
||||
c.insert(name.into(), U256::from(value));
|
||||
}
|
||||
for segment in Segment::all() {
|
||||
c.insert(segment.var_name().into(), (segment as u32).into());
|
||||
}
|
||||
for txn_field in NormalizedTxnField::all() {
|
||||
c.insert(txn_field.var_name().into(), (txn_field as u32).into());
|
||||
}
|
||||
for txn_field in GlobalMetadata::all() {
|
||||
c.insert(txn_field.var_name().into(), (txn_field as u32).into());
|
||||
}
|
||||
for txn_field in ContextMetadata::all() {
|
||||
c.insert(txn_field.var_name().into(), (txn_field as u32).into());
|
||||
}
|
||||
c
|
||||
}
|
||||
|
||||
const EC_CONSTANTS: [(&str, [u8; 32]); 3] = [
|
||||
(
|
||||
"BN_BASE",
|
||||
hex!("30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"),
|
||||
),
|
||||
(
|
||||
"SECP_BASE",
|
||||
hex!("fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),
|
||||
),
|
||||
(
|
||||
"SECP_SCALAR",
|
||||
hex!("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),
|
||||
),
|
||||
];
|
||||
|
||||
const GAS_CONSTANTS: [(&str, u16); 36] = [
|
||||
("GAS_ZERO", 0),
|
||||
("GAS_JUMPDEST", 1),
|
||||
("GAS_BASE", 2),
|
||||
("GAS_VERYLOW", 3),
|
||||
("GAS_LOW", 5),
|
||||
("GAS_MID", 8),
|
||||
("GAS_HIGH", 10),
|
||||
("GAS_WARMACCESS", 100),
|
||||
("GAS_ACCESSLISTADDRESS", 2_400),
|
||||
("GAS_ACCESSLISTSTORAGE", 1_900),
|
||||
("GAS_COLDACCOUNTACCESS", 2_600),
|
||||
("GAS_COLDSLOAD", 2_100),
|
||||
("GAS_SSET", 20_000),
|
||||
("GAS_SRESET", 2_900),
|
||||
("REFUND_SCLEAR", 15_000),
|
||||
("REFUND_SELFDESTRUCT", 24_000),
|
||||
("GAS_SELFDESTRUCT", 5_000),
|
||||
("GAS_CREATE", 32_000),
|
||||
("GAS_CODEDEPOSIT", 200),
|
||||
("GAS_CALLVALUE", 9_000),
|
||||
("GAS_CALLSTIPEND", 2_300),
|
||||
("GAS_NEWACCOUNT", 25_000),
|
||||
("GAS_EXP", 10),
|
||||
("GAS_EXPBYTE", 50),
|
||||
("GAS_MEMORY", 3),
|
||||
("GAS_TXCREATE", 32_000),
|
||||
("GAS_TXDATAZERO", 4),
|
||||
("GAS_TXDATANONZERO", 16),
|
||||
("GAS_TRANSACTION", 21_000),
|
||||
("GAS_LOG", 375),
|
||||
("GAS_LOGDATA", 8),
|
||||
("GAS_LOGTOPIC", 375),
|
||||
("GAS_KECCAK256", 30),
|
||||
("GAS_KECCAK256WORD", 6),
|
||||
("GAS_COPY", 3),
|
||||
("GAS_BLOCKHASH", 20),
|
||||
];
|
||||
33
evm/src/cpu/kernel/context_metadata.rs
Normal file
33
evm/src/cpu/kernel/context_metadata.rs
Normal file
@ -0,0 +1,33 @@
|
||||
/// These metadata fields contain VM state specific to a particular context.
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
|
||||
pub(crate) enum ContextMetadata {
|
||||
/// The ID of the context which created this one.
|
||||
ParentContext = 0,
|
||||
/// The program counter to return to when we return to the parent context.
|
||||
ParentProgramCounter = 1,
|
||||
CalldataSize = 2,
|
||||
ReturndataSize = 3,
|
||||
}
|
||||
|
||||
impl ContextMetadata {
|
||||
pub(crate) const COUNT: usize = 4;
|
||||
|
||||
pub(crate) fn all() -> [Self; Self::COUNT] {
|
||||
[
|
||||
Self::ParentContext,
|
||||
Self::ParentProgramCounter,
|
||||
Self::CalldataSize,
|
||||
Self::ReturndataSize,
|
||||
]
|
||||
}
|
||||
|
||||
/// The variable name that gets passed into kernel assembly code.
|
||||
pub(crate) fn var_name(&self) -> &'static str {
|
||||
match self {
|
||||
ContextMetadata::ParentContext => "CTX_METADATA_PARENT_CONTEXT",
|
||||
ContextMetadata::ParentProgramCounter => "CTX_METADATA_PARENT_PC",
|
||||
ContextMetadata::CalldataSize => "CTX_METADATA_CALLDATA_SIZE",
|
||||
ContextMetadata::ReturndataSize => "CTX_METADATA_RETURNDATA_SIZE",
|
||||
}
|
||||
}
|
||||
}
|
||||
23
evm/src/cpu/kernel/global_metadata.rs
Normal file
23
evm/src/cpu/kernel/global_metadata.rs
Normal file
@ -0,0 +1,23 @@
|
||||
/// These metadata fields contain global VM state, stored in the `Segment::Metadata` segment of the
|
||||
/// kernel's context (which is zero).
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
|
||||
pub(crate) enum GlobalMetadata {
|
||||
/// The larger context ID that has been used so far in this execution. Tracking this allows us
|
||||
/// give each new context a unique ID, so that its memory will be zero-initialized.
|
||||
LargestContext = 0,
|
||||
}
|
||||
|
||||
impl GlobalMetadata {
|
||||
pub(crate) const COUNT: usize = 1;
|
||||
|
||||
pub(crate) fn all() -> [Self; Self::COUNT] {
|
||||
[Self::LargestContext]
|
||||
}
|
||||
|
||||
/// The variable name that gets passed into kernel assembly code.
|
||||
pub(crate) fn var_name(&self) -> &'static str {
|
||||
match self {
|
||||
GlobalMetadata::LargestContext => "GLOBAL_METADATA_LARGEST_CONTEXT",
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,9 @@
|
||||
pub mod aggregator;
|
||||
pub mod assembler;
|
||||
mod ast;
|
||||
mod constants;
|
||||
mod context_metadata;
|
||||
mod global_metadata;
|
||||
pub(crate) mod keccak_util;
|
||||
mod opcodes;
|
||||
mod parser;
|
||||
@ -17,7 +20,7 @@ mod tests;
|
||||
use assembler::assemble;
|
||||
use parser::parse;
|
||||
|
||||
use crate::cpu::kernel::aggregator::evm_constants;
|
||||
use crate::cpu::kernel::constants::evm_constants;
|
||||
|
||||
/// Assemble files, outputting bytes.
|
||||
/// This is for debugging the kernel only.
|
||||
|
||||
@ -13,20 +13,21 @@ pub(crate) enum Segment {
|
||||
Returndata = 4,
|
||||
/// A segment which contains a few fixed-size metadata fields, such as the caller's context, or the
|
||||
/// size of `CALLDATA` and `RETURNDATA`.
|
||||
Metadata = 5,
|
||||
GlobalMetadata = 5,
|
||||
ContextMetadata = 6,
|
||||
/// General purpose kernel memory, used by various kernel functions.
|
||||
/// In general, calling a helper function can result in this memory being clobbered.
|
||||
KernelGeneral = 6,
|
||||
KernelGeneral = 7,
|
||||
/// Contains normalized transaction fields; see `TxnField`.
|
||||
TxnFields = 7,
|
||||
TxnFields = 8,
|
||||
/// Contains the data field of a transaction.
|
||||
TxnData = 8,
|
||||
TxnData = 9,
|
||||
/// Raw RLP data.
|
||||
RlpRaw = 9,
|
||||
RlpRaw = 10,
|
||||
}
|
||||
|
||||
impl Segment {
|
||||
pub(crate) const COUNT: usize = 10;
|
||||
pub(crate) const COUNT: usize = 11;
|
||||
|
||||
pub(crate) fn all() -> [Self; Self::COUNT] {
|
||||
[
|
||||
@ -35,7 +36,8 @@ impl Segment {
|
||||
Self::MainMemory,
|
||||
Self::Calldata,
|
||||
Self::Returndata,
|
||||
Self::Metadata,
|
||||
Self::GlobalMetadata,
|
||||
Self::ContextMetadata,
|
||||
Self::KernelGeneral,
|
||||
Self::TxnFields,
|
||||
Self::TxnData,
|
||||
@ -51,7 +53,8 @@ impl Segment {
|
||||
Segment::MainMemory => "SEGMENT_MAIN_MEMORY",
|
||||
Segment::Calldata => "SEGMENT_CALLDATA",
|
||||
Segment::Returndata => "SEGMENT_RETURNDATA",
|
||||
Segment::Metadata => "SEGMENT_METADATA",
|
||||
Segment::GlobalMetadata => "SEGMENT_GLOBAL_METADATA",
|
||||
Segment::ContextMetadata => "SEGMENT_CONTEXT_METADATA",
|
||||
Segment::KernelGeneral => "SEGMENT_KERNEL_GENERAL",
|
||||
Segment::TxnFields => "SEGMENT_NORMALIZED_TXN",
|
||||
Segment::TxnData => "SEGMENT_TXN_DATA",
|
||||
@ -67,7 +70,8 @@ impl Segment {
|
||||
Segment::MainMemory => 8,
|
||||
Segment::Calldata => 8,
|
||||
Segment::Returndata => 8,
|
||||
Segment::Metadata => 256,
|
||||
Segment::GlobalMetadata => 256,
|
||||
Segment::ContextMetadata => 256,
|
||||
Segment::KernelGeneral => 256,
|
||||
Segment::TxnFields => 256,
|
||||
Segment::TxnData => 256,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user