mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-04-18 01:23:08 +00:00
Add random value to block metadata and fix sys_prevrandao (#1207)
* 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
This commit is contained in:
parent
0abc3b9210
commit
8c78271f5c
@ -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"),
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
// Labels for unimplemented syscalls to make the kernel assemble.
|
||||
// Each label should be removed from this file once it is implemented.
|
||||
|
||||
// This is a temporary version that returns the block difficulty (i.e. the old version of this opcode).
|
||||
// TODO: Fix this.
|
||||
// TODO: What semantics will this have for Edge?
|
||||
global sys_prevrandao:
|
||||
// stack: kexit_info
|
||||
%charge_gas_const(@GAS_BASE)
|
||||
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_DIFFICULTY)
|
||||
%stack (difficulty, kexit_info) -> (kexit_info, difficulty)
|
||||
EXIT_KERNEL
|
||||
@ -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
|
||||
|
||||
@ -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] {
|
||||
[
|
||||
@ -109,6 +110,7 @@ impl GlobalMetadata {
|
||||
Self::BlockTimestamp,
|
||||
Self::BlockNumber,
|
||||
Self::BlockDifficulty,
|
||||
Self::BlockRandom,
|
||||
Self::BlockGasLimit,
|
||||
Self::BlockChainId,
|
||||
Self::BlockBaseFee,
|
||||
@ -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",
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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);
|
||||
@ -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);
|
||||
|
||||
@ -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.
|
||||
@ -175,6 +176,7 @@ impl PublicValuesTarget {
|
||||
block_timestamp,
|
||||
block_number,
|
||||
block_difficulty,
|
||||
block_random,
|
||||
block_gaslimit,
|
||||
block_chain_id,
|
||||
block_base_fee,
|
||||
@ -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)?;
|
||||
@ -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()?,
|
||||
@ -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],
|
||||
@ -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,
|
||||
@ -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| {
|
||||
@ -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 {
|
||||
|
||||
@ -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,
|
||||
@ -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,
|
||||
@ -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();
|
||||
@ -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,
|
||||
@ -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)?,
|
||||
|
||||
@ -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;
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
@ -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(),
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
@ -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(),
|
||||
@ -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 {
|
||||
@ -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(),
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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, U256};
|
||||
use ethereum_types::{Address, BigEndianHash, H256, U256};
|
||||
use hex_literal::hex;
|
||||
use keccak_hash::keccak;
|
||||
use plonky2::field::goldilocks_field::GoldilocksField;
|
||||
@ -71,6 +71,7 @@ fn test_simple_transfer() -> 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(),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user