Skip to content

Commit

Permalink
Add random value to block metadata and fix sys_prevrandao (#1207)
Browse files Browse the repository at this point in the history
* Add random to block metadata and fix `sys_prevrandao`

* Minor

* Observe block_random

* Write block_random

* cargo fmt

* block_random: H256

* Move sys_prevrandao to metadata.asm and delete syscall_stubs.asm

* Set block_random in set_block_metadata_target

* Minor

* Minor
  • Loading branch information
wborgeaud authored Sep 25, 2023
1 parent 0abc3b9 commit 8c78271
Show file tree
Hide file tree
Showing 14 changed files with 90 additions and 53 deletions.
1 change: 0 additions & 1 deletion evm/src/cpu/kernel/aggregator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ pub(crate) fn combined_kernel() -> Kernel {
include_str!("asm/core/nonce.asm"),
include_str!("asm/core/process_txn.asm"),
include_str!("asm/core/syscall.asm"),
include_str!("asm/core/syscall_stubs.asm"),
include_str!("asm/core/terminate.asm"),
include_str!("asm/core/transfer.asm"),
include_str!("asm/core/util.asm"),
Expand Down
12 changes: 0 additions & 12 deletions evm/src/cpu/kernel/asm/core/syscall_stubs.asm

This file was deleted.

7 changes: 7 additions & 0 deletions evm/src/cpu/kernel/asm/memory/metadata.asm
Original file line number Diff line number Diff line change
Expand Up @@ -383,3 +383,10 @@ zero_hash:
%decrement
%mstore_global_metadata(@GLOBAL_METADATA_CALL_STACK_DEPTH)
%endmacro

global sys_prevrandao:
// stack: kexit_info
%charge_gas_const(@GAS_BASE)
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_RANDOM)
%stack (random, kexit_info) -> (kexit_info, random)
EXIT_KERNEL
59 changes: 31 additions & 28 deletions evm/src/cpu/kernel/constants/global_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,55 +39,56 @@ pub(crate) enum GlobalMetadata {
BlockTimestamp = 15,
BlockNumber = 16,
BlockDifficulty = 17,
BlockGasLimit = 18,
BlockChainId = 19,
BlockBaseFee = 20,
BlockGasUsed = 21,
BlockRandom = 18,
BlockGasLimit = 19,
BlockChainId = 20,
BlockBaseFee = 21,
BlockGasUsed = 22,
/// Before current transactions block values.
BlockGasUsedBefore = 22,
BlockGasUsedBefore = 23,
/// After current transactions block values.
BlockGasUsedAfter = 23,
BlockGasUsedAfter = 24,
/// Current block header hash
BlockCurrentHash = 24,
BlockCurrentHash = 25,

/// Gas to refund at the end of the transaction.
RefundCounter = 25,
RefundCounter = 26,
/// Length of the addresses access list.
AccessedAddressesLen = 26,
AccessedAddressesLen = 27,
/// Length of the storage keys access list.
AccessedStorageKeysLen = 27,
AccessedStorageKeysLen = 28,
/// Length of the self-destruct list.
SelfDestructListLen = 28,
SelfDestructListLen = 29,
/// Length of the bloom entry buffer.
BloomEntryLen = 29,
BloomEntryLen = 30,

/// Length of the journal.
JournalLen = 30,
JournalLen = 31,
/// Length of the `JournalData` segment.
JournalDataLen = 31,
JournalDataLen = 32,
/// Current checkpoint.
CurrentCheckpoint = 32,
TouchedAddressesLen = 33,
CurrentCheckpoint = 33,
TouchedAddressesLen = 34,
// Gas cost for the access list in type-1 txns. See EIP-2930.
AccessListDataCost = 34,
AccessListDataCost = 35,
// Start of the access list in the RLP for type-1 txns.
AccessListRlpStart = 35,
AccessListRlpStart = 36,
// Length of the access list in the RLP for type-1 txns.
AccessListRlpLen = 36,
AccessListRlpLen = 37,
// Boolean flag indicating if the txn is a contract creation txn.
ContractCreation = 37,
IsPrecompileFromEoa = 38,
CallStackDepth = 39,
ContractCreation = 38,
IsPrecompileFromEoa = 39,
CallStackDepth = 40,
/// Transaction logs list length
LogsLen = 40,
LogsDataLen = 41,
LogsPayloadLen = 42,
TxnNumberBefore = 43,
TxnNumberAfter = 44,
LogsLen = 41,
LogsDataLen = 42,
LogsPayloadLen = 43,
TxnNumberBefore = 44,
TxnNumberAfter = 45,
}

impl GlobalMetadata {
pub(crate) const COUNT: usize = 45;
pub(crate) const COUNT: usize = 46;

pub(crate) fn all() -> [Self; Self::COUNT] {
[
Expand All @@ -109,6 +110,7 @@ impl GlobalMetadata {
Self::BlockTimestamp,
Self::BlockNumber,
Self::BlockDifficulty,
Self::BlockRandom,
Self::BlockGasLimit,
Self::BlockChainId,
Self::BlockBaseFee,
Expand Down Expand Up @@ -160,6 +162,7 @@ impl GlobalMetadata {
Self::BlockTimestamp => "GLOBAL_METADATA_BLOCK_TIMESTAMP",
Self::BlockNumber => "GLOBAL_METADATA_BLOCK_NUMBER",
Self::BlockDifficulty => "GLOBAL_METADATA_BLOCK_DIFFICULTY",
Self::BlockRandom => "GLOBAL_METADATA_BLOCK_RANDOM",
Self::BlockGasLimit => "GLOBAL_METADATA_BLOCK_GAS_LIMIT",
Self::BlockChainId => "GLOBAL_METADATA_BLOCK_CHAIN_ID",
Self::BlockBaseFee => "GLOBAL_METADATA_BLOCK_BASE_FEE",
Expand Down
4 changes: 4 additions & 0 deletions evm/src/generation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ fn apply_metadata_and_tries_memops<F: RichField + Extendable<D>, const D: usize>
(GlobalMetadata::BlockTimestamp, metadata.block_timestamp),
(GlobalMetadata::BlockNumber, metadata.block_number),
(GlobalMetadata::BlockDifficulty, metadata.block_difficulty),
(
GlobalMetadata::BlockRandom,
metadata.block_random.into_uint(),
),
(GlobalMetadata::BlockGasLimit, metadata.block_gaslimit),
(GlobalMetadata::BlockChainId, metadata.block_chain_id),
(GlobalMetadata::BlockBaseFee, metadata.block_base_fee),
Expand Down
2 changes: 2 additions & 0 deletions evm/src/get_challenges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ fn observe_block_metadata<
challenger.observe_element(u256_to_u32(block_metadata.block_number)?);
challenger.observe_element(u256_to_u32(block_metadata.block_difficulty)?);
challenger.observe_element(u256_to_u32(block_metadata.block_gaslimit)?);
challenger.observe_elements(&h256_limbs::<F>(block_metadata.block_random));
challenger.observe_element(u256_to_u32(block_metadata.block_chain_id)?);
let basefee = u256_to_u64(block_metadata.block_base_fee)?;
challenger.observe_element(basefee.0);
Expand All @@ -91,6 +92,7 @@ fn observe_block_metadata_target<
challenger.observe_element(block_metadata.block_timestamp);
challenger.observe_element(block_metadata.block_number);
challenger.observe_element(block_metadata.block_difficulty);
challenger.observe_elements(&block_metadata.block_random);
challenger.observe_element(block_metadata.block_gaslimit);
challenger.observe_element(block_metadata.block_chain_id);
challenger.observe_elements(&block_metadata.block_base_fee);
Expand Down
25 changes: 19 additions & 6 deletions evm/src/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ pub struct BlockMetadata {
pub block_number: U256,
/// The difficulty (before PoS transition) of this block.
pub block_difficulty: U256,
pub block_random: H256,
/// The gas limit of this block. It must fit in a `u32`.
pub block_gaslimit: U256,
/// The chain id of this block.
Expand Down Expand Up @@ -175,6 +176,7 @@ impl PublicValuesTarget {
block_timestamp,
block_number,
block_difficulty,
block_random,
block_gaslimit,
block_chain_id,
block_base_fee,
Expand All @@ -186,6 +188,7 @@ impl PublicValuesTarget {
buffer.write_target(block_timestamp)?;
buffer.write_target(block_number)?;
buffer.write_target(block_difficulty)?;
buffer.write_target_array(&block_random)?;
buffer.write_target(block_gaslimit)?;
buffer.write_target(block_chain_id)?;
buffer.write_target_array(&block_base_fee)?;
Expand Down Expand Up @@ -235,6 +238,7 @@ impl PublicValuesTarget {
block_timestamp: buffer.read_target()?,
block_number: buffer.read_target()?,
block_difficulty: buffer.read_target()?,
block_random: buffer.read_target_array()?,
block_gaslimit: buffer.read_target()?,
block_chain_id: buffer.read_target()?,
block_base_fee: buffer.read_target_array()?,
Expand Down Expand Up @@ -407,6 +411,7 @@ pub struct BlockMetadataTarget {
pub block_timestamp: Target,
pub block_number: Target,
pub block_difficulty: Target,
pub block_random: [Target; 8],
pub block_gaslimit: Target,
pub block_chain_id: Target,
pub block_base_fee: [Target; 2],
Expand All @@ -415,24 +420,26 @@ pub struct BlockMetadataTarget {
}

impl BlockMetadataTarget {
const SIZE: usize = 77;
const SIZE: usize = 85;

pub fn from_public_inputs(pis: &[Target]) -> Self {
let block_beneficiary = pis[0..5].try_into().unwrap();
let block_timestamp = pis[5];
let block_number = pis[6];
let block_difficulty = pis[7];
let block_gaslimit = pis[8];
let block_chain_id = pis[9];
let block_base_fee = pis[10..12].try_into().unwrap();
let block_gas_used = pis[12];
let block_bloom = pis[13..77].try_into().unwrap();
let block_random = pis[8..16].try_into().unwrap();
let block_gaslimit = pis[16];
let block_chain_id = pis[17];
let block_base_fee = pis[18..20].try_into().unwrap();
let block_gas_used = pis[20];
let block_bloom = pis[21..85].try_into().unwrap();

Self {
block_beneficiary,
block_timestamp,
block_number,
block_difficulty,
block_random,
block_gaslimit,
block_chain_id,
block_base_fee,
Expand All @@ -458,6 +465,9 @@ impl BlockMetadataTarget {
block_timestamp: builder.select(condition, bm0.block_timestamp, bm1.block_timestamp),
block_number: builder.select(condition, bm0.block_number, bm1.block_number),
block_difficulty: builder.select(condition, bm0.block_difficulty, bm1.block_difficulty),
block_random: core::array::from_fn(|i| {
builder.select(condition, bm0.block_random[i], bm1.block_random[i])
}),
block_gaslimit: builder.select(condition, bm0.block_gaslimit, bm1.block_gaslimit),
block_chain_id: builder.select(condition, bm0.block_chain_id, bm1.block_chain_id),
block_base_fee: core::array::from_fn(|i| {
Expand All @@ -481,6 +491,9 @@ impl BlockMetadataTarget {
builder.connect(bm0.block_timestamp, bm1.block_timestamp);
builder.connect(bm0.block_number, bm1.block_number);
builder.connect(bm0.block_difficulty, bm1.block_difficulty);
for i in 0..8 {
builder.connect(bm0.block_random[i], bm1.block_random[i]);
}
builder.connect(bm0.block_gaslimit, bm1.block_gaslimit);
builder.connect(bm0.block_chain_id, bm1.block_chain_id);
for i in 0..2 {
Expand Down
14 changes: 12 additions & 2 deletions evm/src/recursive_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,11 +548,15 @@ pub(crate) fn get_memory_extra_looking_products_circuit<
),
];

let beneficiary_base_fee_cur_hash_fields: [(usize, &[Target]); 3] = [
let beneficiary_random_base_fee_cur_hash_fields: [(usize, &[Target]); 4] = [
(
GlobalMetadata::BlockBeneficiary as usize,
&public_values.block_metadata.block_beneficiary,
),
(
GlobalMetadata::BlockRandom as usize,
&public_values.block_metadata.block_random,
),
(
GlobalMetadata::BlockBaseFee as usize,
&public_values.block_metadata.block_base_fee,
Expand All @@ -576,7 +580,7 @@ pub(crate) fn get_memory_extra_looking_products_circuit<
);
});

beneficiary_base_fee_cur_hash_fields.map(|(field, targets)| {
beneficiary_random_base_fee_cur_hash_fields.map(|(field, targets)| {
product = add_data_write(
builder,
challenge,
Expand Down Expand Up @@ -772,6 +776,7 @@ pub(crate) fn add_virtual_block_metadata<F: RichField + Extendable<D>, const D:
let block_timestamp = builder.add_virtual_public_input();
let block_number = builder.add_virtual_public_input();
let block_difficulty = builder.add_virtual_public_input();
let block_random = builder.add_virtual_public_input_arr();
let block_gaslimit = builder.add_virtual_public_input();
let block_chain_id = builder.add_virtual_public_input();
let block_base_fee = builder.add_virtual_public_input_arr();
Expand All @@ -782,6 +787,7 @@ pub(crate) fn add_virtual_block_metadata<F: RichField + Extendable<D>, const D:
block_timestamp,
block_number,
block_difficulty,
block_random,
block_gaslimit,
block_chain_id,
block_base_fee,
Expand Down Expand Up @@ -1014,6 +1020,10 @@ where
block_metadata_target.block_difficulty,
u256_to_u32(block_metadata.block_difficulty)?,
);
witness.set_target_arr(
&block_metadata_target.block_random,
&h256_limbs(block_metadata.block_random),
);
witness.set_target(
block_metadata_target.block_gaslimit,
u256_to_u32(block_metadata.block_gaslimit)?,
Expand Down
6 changes: 5 additions & 1 deletion evm/src/verifier.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::any::type_name;

use anyhow::{ensure, Result};
use ethereum_types::U256;
use ethereum_types::{BigEndianHash, U256};
use itertools::Itertools;
use plonky2::field::extension::{Extendable, FieldExtension};
use plonky2::field::types::Field;
Expand Down Expand Up @@ -157,6 +157,10 @@ where
GlobalMetadata::BlockNumber,
public_values.block_metadata.block_number,
),
(
GlobalMetadata::BlockRandom,
public_values.block_metadata.block_random.into_uint(),
),
(
GlobalMetadata::BlockDifficulty,
public_values.block_metadata.block_difficulty,
Expand Down
3 changes: 2 additions & 1 deletion evm/tests/add11_yml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::time::Duration;
use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV};
use eth_trie_utils::nibbles::Nibbles;
use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie};
use ethereum_types::{Address, H256};
use ethereum_types::{Address, BigEndianHash, H256};
use hex_literal::hex;
use keccak_hash::keccak;
use plonky2::field::goldilocks_field::GoldilocksField;
Expand Down Expand Up @@ -83,6 +83,7 @@ fn add11_yml() -> anyhow::Result<()> {
block_timestamp: 0x03e8.into(),
block_number: 1.into(),
block_difficulty: 0x020000.into(),
block_random: H256::from_uint(&0x020000.into()),
block_gaslimit: 0xff112233u32.into(),
block_chain_id: 1.into(),
block_base_fee: 0xa.into(),
Expand Down
1 change: 1 addition & 0 deletions evm/tests/basic_smart_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ fn test_basic_smart_contract() -> anyhow::Result<()> {
block_gas_used: gas_used.into(),
block_bloom: [0.into(); 8],
block_base_fee: 0xa.into(),
block_random: Default::default(),
};

let mut contract_code = HashMap::new();
Expand Down
5 changes: 4 additions & 1 deletion evm/tests/log_opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use bytes::Bytes;
use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV};
use eth_trie_utils::nibbles::Nibbles;
use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie};
use ethereum_types::{Address, H256, U256};
use ethereum_types::{Address, BigEndianHash, H256, U256};
use hex_literal::hex;
use keccak_hash::keccak;
use plonky2::field::goldilocks_field::GoldilocksField;
Expand Down Expand Up @@ -135,6 +135,7 @@ fn test_log_opcodes() -> anyhow::Result<()> {
block_timestamp: 0x03e8.into(),
block_number: 1.into(),
block_difficulty: 0x020000.into(),
block_random: H256::from_uint(&0x020000.into()),
block_gaslimit: 0xffffffffu32.into(),
block_chain_id: 1.into(),
block_base_fee: 0xa.into(),
Expand Down Expand Up @@ -365,6 +366,7 @@ fn test_log_with_aggreg() -> anyhow::Result<()> {
.unwrap(),
U256::from_dec_str("2722259584404615024560450425766186844160").unwrap(),
],
block_random: Default::default(),
};

let beneficiary_account_after = AccountRlp {
Expand Down Expand Up @@ -791,6 +793,7 @@ fn test_two_txn() -> anyhow::Result<()> {
block_timestamp: 0x03e8.into(),
block_number: 1.into(),
block_difficulty: 0x020000.into(),
block_random: H256::from_uint(&0x020000.into()),
block_gaslimit: 0xffffffffu32.into(),
block_chain_id: 1.into(),
block_base_fee: 0xa.into(),
Expand Down
1 change: 1 addition & 0 deletions evm/tests/self_balance_gas_cost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ fn self_balance_gas_cost() -> anyhow::Result<()> {
block_gas_used: gas_used.into(),
block_bloom: [0.into(); 8],
block_base_fee: 0xa.into(),
block_random: Default::default(),
};

let mut contract_code = HashMap::new();
Expand Down
Loading

0 comments on commit 8c78271

Please sign in to comment.