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

Add random value to block metadata and fix sys_prevrandao #1207

Merged
merged 11 commits into from
Sep 25, 2023
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]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

block_random is connected here, but it isn't set in set_block_metadata_target. This leads to a generators not run error in a recursive proof.

}
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
Loading