mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-03 14:23:07 +00:00
Constrain genesis block's state trie.
This commit is contained in:
parent
3571f09707
commit
4d7d9ffa3c
@ -640,6 +640,11 @@ where
|
||||
lhs: &ExtraBlockDataTarget,
|
||||
rhs: &ExtraBlockDataTarget,
|
||||
) {
|
||||
// Connect genesis state root values.
|
||||
for (&limb0, &limb1) in pvs.genesis_state_root.iter().zip(&rhs.genesis_state_root) {
|
||||
builder.connect(limb0, limb1);
|
||||
}
|
||||
|
||||
// Connect the transaction number in public values to the lhs and rhs values correctly.
|
||||
builder.connect(pvs.txn_number_before, lhs.txn_number_before);
|
||||
builder.connect(pvs.txn_number_after, rhs.txn_number_after);
|
||||
@ -776,6 +781,16 @@ where
|
||||
builder.connect(limb0, limb1);
|
||||
}
|
||||
|
||||
// Between blocks, the genesis state trie remains unchanged.
|
||||
for (&limb0, limb1) in lhs
|
||||
.extra_block_data
|
||||
.genesis_state_root
|
||||
.iter()
|
||||
.zip(rhs.extra_block_data.genesis_state_root)
|
||||
{
|
||||
builder.connect(limb0, limb1);
|
||||
}
|
||||
|
||||
// Connect block numbers.
|
||||
let one = builder.one();
|
||||
let prev_block_nb = builder.sub(rhs.block_metadata.block_number, one);
|
||||
@ -787,13 +802,23 @@ where
|
||||
// Connect intermediary values for gas_used and bloom filters to the block's final values. We only plug on the right, so there is no need to check the left-handside block.
|
||||
Self::connect_final_block_values_to_intermediary(builder, rhs);
|
||||
|
||||
// Chack that the genesis block number is 0.
|
||||
let zero = builder.zero();
|
||||
let has_not_parent_block = builder.sub(one, has_parent_block.target);
|
||||
// Chack that the genesis block number is 0.
|
||||
let gen_block_constr = builder.mul(has_not_parent_block, rhs.block_metadata.block_number);
|
||||
builder.connect(gen_block_constr, zero);
|
||||
|
||||
// TODO: Check that the genesis block has a predetermined state trie root.
|
||||
// Check that the genesis block has a predetermined state trie root.
|
||||
for (&limb0, limb1) in rhs
|
||||
.trie_roots_before
|
||||
.state_root
|
||||
.iter()
|
||||
.zip(rhs.extra_block_data.genesis_state_root)
|
||||
{
|
||||
let mut constr = builder.sub(limb0, limb1);
|
||||
constr = builder.mul(has_not_parent_block, constr);
|
||||
builder.connect(constr, zero);
|
||||
}
|
||||
}
|
||||
|
||||
fn connect_final_block_values_to_intermediary(
|
||||
@ -981,16 +1006,34 @@ where
|
||||
block_inputs
|
||||
.set_proof_with_pis_target(&self.block.parent_block_proof, parent_block_proof);
|
||||
} else {
|
||||
// Initialize state_root_after and the block number for correct connection between blocks.
|
||||
let state_trie_root_keys = 24..32;
|
||||
let block_number_key = TrieRootsTarget::SIZE * 2 + 6;
|
||||
// Initialize genesis_state_trie, state_root_after and the block number for correct connection between blocks.
|
||||
// Initialize `state_root_after`.
|
||||
let state_trie_root_after_keys = 24..32;
|
||||
let mut nonzero_pis = HashMap::new();
|
||||
for (key, &value) in state_trie_root_keys
|
||||
for (key, &value) in state_trie_root_after_keys
|
||||
.zip_eq(&h256_limbs::<F>(public_values.trie_roots_before.state_root))
|
||||
{
|
||||
nonzero_pis.insert(key, value);
|
||||
}
|
||||
|
||||
// Initialize the genesis state trie digest.
|
||||
let genesis_state_trie_keys = TrieRootsTarget::SIZE * 2
|
||||
+ BlockMetadataTarget::SIZE
|
||||
+ BlockHashesTarget::BLOCK_HASHES_SIZE
|
||||
..TrieRootsTarget::SIZE * 2
|
||||
+ BlockMetadataTarget::SIZE
|
||||
+ BlockHashesTarget::BLOCK_HASHES_SIZE
|
||||
+ 8;
|
||||
for (key, &value) in genesis_state_trie_keys.zip_eq(&h256_limbs::<F>(
|
||||
public_values.extra_block_data.genesis_state_root,
|
||||
)) {
|
||||
nonzero_pis.insert(key, value);
|
||||
}
|
||||
|
||||
// Initialize the block number.
|
||||
let block_number_key = TrieRootsTarget::SIZE * 2 + 6;
|
||||
nonzero_pis.insert(block_number_key, F::NEG_ONE);
|
||||
|
||||
block_inputs.set_proof_with_pis_target(
|
||||
&self.block.parent_block_proof,
|
||||
&cyclic_base_proof(
|
||||
|
||||
@ -48,6 +48,8 @@ pub struct GenerationInputs {
|
||||
pub tries: TrieInputs,
|
||||
/// Expected trie roots after the transactions are executed.
|
||||
pub trie_roots_after: TrieRoots,
|
||||
/// State trie root of the genesis block.
|
||||
pub genesis_state_trie_root: H256,
|
||||
|
||||
/// Mapping between smart contract code hashes and the contract byte code.
|
||||
/// All account smart contracts that are invoked will have an entry present.
|
||||
@ -251,6 +253,7 @@ pub fn generate_traces<F: RichField + Extendable<D>, const D: usize>(
|
||||
let txn_number_after = read_metadata(GlobalMetadata::TxnNumberAfter);
|
||||
|
||||
let extra_block_data = ExtraBlockData {
|
||||
genesis_state_root: inputs.genesis_state_trie_root,
|
||||
txn_number_before: inputs.txn_number_before,
|
||||
txn_number_after,
|
||||
gas_used_before: inputs.gas_used_before,
|
||||
|
||||
@ -116,6 +116,7 @@ fn observe_extra_block_data<
|
||||
challenger: &mut Challenger<F, C::Hasher>,
|
||||
extra_data: &ExtraBlockData,
|
||||
) {
|
||||
challenger.observe_elements(&h256_limbs(extra_data.genesis_state_root));
|
||||
challenger.observe_element(F::from_canonical_u32(extra_data.txn_number_before.as_u32()));
|
||||
challenger.observe_element(F::from_canonical_u32(extra_data.txn_number_after.as_u32()));
|
||||
challenger.observe_element(F::from_canonical_u32(extra_data.gas_used_before.as_u32()));
|
||||
@ -138,6 +139,7 @@ fn observe_extra_block_data_target<
|
||||
) where
|
||||
C::Hasher: AlgebraicHasher<F>,
|
||||
{
|
||||
challenger.observe_elements(&extra_data.genesis_state_root);
|
||||
challenger.observe_element(extra_data.txn_number_before);
|
||||
challenger.observe_element(extra_data.txn_number_after);
|
||||
challenger.observe_element(extra_data.gas_used_before);
|
||||
|
||||
@ -95,6 +95,7 @@ pub struct BlockMetadata {
|
||||
|
||||
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
|
||||
pub struct ExtraBlockData {
|
||||
pub genesis_state_root: H256,
|
||||
pub txn_number_before: U256,
|
||||
pub txn_number_after: U256,
|
||||
pub gas_used_before: U256,
|
||||
@ -166,6 +167,7 @@ impl PublicValuesTarget {
|
||||
buffer.write_target_array(&cur_hash)?;
|
||||
|
||||
let ExtraBlockDataTarget {
|
||||
genesis_state_root,
|
||||
txn_number_before,
|
||||
txn_number_after,
|
||||
gas_used_before,
|
||||
@ -173,6 +175,7 @@ impl PublicValuesTarget {
|
||||
block_bloom_before,
|
||||
block_bloom_after,
|
||||
} = self.extra_block_data;
|
||||
buffer.write_target_array(&genesis_state_root)?;
|
||||
buffer.write_target(txn_number_before)?;
|
||||
buffer.write_target(txn_number_after)?;
|
||||
buffer.write_target(gas_used_before)?;
|
||||
@ -214,6 +217,7 @@ impl PublicValuesTarget {
|
||||
};
|
||||
|
||||
let extra_block_data = ExtraBlockDataTarget {
|
||||
genesis_state_root: buffer.read_target_array()?,
|
||||
txn_number_before: buffer.read_target()?,
|
||||
txn_number_after: buffer.read_target()?,
|
||||
gas_used_before: buffer.read_target()?,
|
||||
@ -381,7 +385,7 @@ pub struct BlockMetadataTarget {
|
||||
}
|
||||
|
||||
impl BlockMetadataTarget {
|
||||
const SIZE: usize = 77;
|
||||
pub const SIZE: usize = 77;
|
||||
|
||||
pub fn from_public_inputs(pis: &[Target]) -> Self {
|
||||
let block_beneficiary = pis[0..5].try_into().unwrap();
|
||||
@ -465,7 +469,7 @@ pub struct BlockHashesTarget {
|
||||
}
|
||||
|
||||
impl BlockHashesTarget {
|
||||
const BLOCK_HASHES_SIZE: usize = 2056;
|
||||
pub const BLOCK_HASHES_SIZE: usize = 2056;
|
||||
pub fn from_public_inputs(pis: &[Target]) -> Self {
|
||||
Self {
|
||||
prev_hashes: pis[0..2048].try_into().unwrap(),
|
||||
@ -505,6 +509,7 @@ impl BlockHashesTarget {
|
||||
|
||||
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
|
||||
pub struct ExtraBlockDataTarget {
|
||||
pub genesis_state_root: [Target; 8],
|
||||
pub txn_number_before: Target,
|
||||
pub txn_number_after: Target,
|
||||
pub gas_used_before: Target,
|
||||
@ -514,17 +519,19 @@ pub struct ExtraBlockDataTarget {
|
||||
}
|
||||
|
||||
impl ExtraBlockDataTarget {
|
||||
const SIZE: usize = 132;
|
||||
const SIZE: usize = 140;
|
||||
|
||||
pub fn from_public_inputs(pis: &[Target]) -> Self {
|
||||
let txn_number_before = pis[0];
|
||||
let txn_number_after = pis[1];
|
||||
let gas_used_before = pis[2];
|
||||
let gas_used_after = pis[3];
|
||||
let block_bloom_before = pis[4..68].try_into().unwrap();
|
||||
let block_bloom_after = pis[68..132].try_into().unwrap();
|
||||
let genesis_state_root = pis[0..8].try_into().unwrap();
|
||||
let txn_number_before = pis[8];
|
||||
let txn_number_after = pis[9];
|
||||
let gas_used_before = pis[10];
|
||||
let gas_used_after = pis[11];
|
||||
let block_bloom_before = pis[12..76].try_into().unwrap();
|
||||
let block_bloom_after = pis[76..140].try_into().unwrap();
|
||||
|
||||
Self {
|
||||
genesis_state_root,
|
||||
txn_number_before,
|
||||
txn_number_after,
|
||||
gas_used_before,
|
||||
@ -541,6 +548,13 @@ impl ExtraBlockDataTarget {
|
||||
ed1: Self,
|
||||
) -> Self {
|
||||
Self {
|
||||
genesis_state_root: core::array::from_fn(|i| {
|
||||
builder.select(
|
||||
condition,
|
||||
ed0.genesis_state_root[i],
|
||||
ed1.genesis_state_root[i],
|
||||
)
|
||||
}),
|
||||
txn_number_before: builder.select(
|
||||
condition,
|
||||
ed0.txn_number_before,
|
||||
@ -571,6 +585,9 @@ impl ExtraBlockDataTarget {
|
||||
ed0: Self,
|
||||
ed1: Self,
|
||||
) {
|
||||
for i in 0..8 {
|
||||
builder.connect(ed0.genesis_state_root[i], ed1.genesis_state_root[i]);
|
||||
}
|
||||
builder.connect(ed0.txn_number_before, ed1.txn_number_before);
|
||||
builder.connect(ed0.txn_number_after, ed1.txn_number_after);
|
||||
builder.connect(ed0.gas_used_before, ed1.gas_used_before);
|
||||
|
||||
@ -808,6 +808,7 @@ pub(crate) fn add_virtual_block_hashes<F: RichField + Extendable<D>, const D: us
|
||||
pub(crate) fn add_virtual_extra_block_data<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> ExtraBlockDataTarget {
|
||||
let genesis_state_root = builder.add_virtual_public_input_arr();
|
||||
let txn_number_before = builder.add_virtual_public_input();
|
||||
let txn_number_after = builder.add_virtual_public_input();
|
||||
let gas_used_before = builder.add_virtual_public_input();
|
||||
@ -815,6 +816,7 @@ pub(crate) fn add_virtual_extra_block_data<F: RichField + Extendable<D>, const D
|
||||
let block_bloom_before: [Target; 64] = builder.add_virtual_public_input_arr();
|
||||
let block_bloom_after: [Target; 64] = builder.add_virtual_public_input_arr();
|
||||
ExtraBlockDataTarget {
|
||||
genesis_state_root,
|
||||
txn_number_before,
|
||||
txn_number_after,
|
||||
gas_used_before,
|
||||
@ -1070,6 +1072,10 @@ pub(crate) fn set_extra_public_values_target<F, W, const D: usize>(
|
||||
F: RichField + Extendable<D>,
|
||||
W: Witness<F>,
|
||||
{
|
||||
witness.set_target_arr(
|
||||
&ed_target.genesis_state_root,
|
||||
&h256_limbs::<F>(ed.genesis_state_root),
|
||||
);
|
||||
witness.set_target(
|
||||
ed_target.txn_number_before,
|
||||
F::from_canonical_usize(ed.txn_number_before.as_usize()),
|
||||
|
||||
@ -149,6 +149,7 @@ fn add11_yml() -> anyhow::Result<()> {
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
block_metadata,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
gas_used_after: 0xa868u64.into(),
|
||||
|
||||
@ -165,6 +165,7 @@ fn test_basic_smart_contract() -> anyhow::Result<()> {
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata,
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
|
||||
@ -57,6 +57,7 @@ fn test_empty_txn_list() -> anyhow::Result<()> {
|
||||
},
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata,
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
|
||||
@ -225,6 +225,7 @@ fn test_log_opcodes() -> anyhow::Result<()> {
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata,
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
@ -423,6 +424,7 @@ fn test_log_with_aggreg() -> anyhow::Result<()> {
|
||||
tries: tries_before,
|
||||
trie_roots_after: tries_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata: block_metadata.clone(),
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
@ -564,6 +566,7 @@ fn test_log_with_aggreg() -> anyhow::Result<()> {
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata,
|
||||
txn_number_before: 1.into(),
|
||||
gas_used_before: gas_used_second,
|
||||
@ -589,6 +592,7 @@ fn test_log_with_aggreg() -> anyhow::Result<()> {
|
||||
trie_roots_before: first_public_values.trie_roots_before,
|
||||
trie_roots_after: public_values.trie_roots_after,
|
||||
extra_block_data: ExtraBlockData {
|
||||
genesis_state_root: first_public_values.extra_block_data.genesis_state_root,
|
||||
txn_number_before: first_public_values.extra_block_data.txn_number_before,
|
||||
txn_number_after: public_values.extra_block_data.txn_number_after,
|
||||
gas_used_before: first_public_values.extra_block_data.gas_used_before,
|
||||
@ -864,6 +868,7 @@ fn test_two_txn() -> anyhow::Result<()> {
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata,
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
|
||||
@ -154,6 +154,7 @@ fn self_balance_gas_cost() -> anyhow::Result<()> {
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata,
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
|
||||
@ -135,6 +135,7 @@ fn test_simple_transfer() -> anyhow::Result<()> {
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata,
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user