Skip to content
This repository has been archived by the owner on May 3, 2024. It is now read-only.

A6 pi #173

Merged
merged 6 commits into from
Dec 11, 2023
Merged

A6 pi #173

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
252 changes: 109 additions & 143 deletions bus-mapping/src/circuit_input_builder/protocol_instance.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#![allow(missing_docs)]

use alloy_dyn_abi::DynSolValue;
use alloy_primitives::{B256, U160, U256};
use alloy_primitives::{B256, U256};

use alloy_sol_types::{sol, SolValue};
use eth_types::{Address, Bytes, ToBigEndian, ToWord};
use eth_types::Address;
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use sha3::{Digest, Keccak256};
use std::{iter, str::FromStr};
use std::str::FromStr;

/// L1 signal service
pub static L1_SIGNAL_SERVICE: Lazy<Address> = Lazy::new(|| {
Expand All @@ -28,170 +28,136 @@ pub static TREASURY: Lazy<Address> = Lazy::new(|| {
.expect("invalid treasury account")
});

sol! {
#[derive(Debug, Default, Deserialize, Serialize)]
struct EthDeposit {
address recipient;
uint96 amount;
uint64 id;
}
}
pub const ANCHOR_METHOD_SIGNATURE: u32 = 0xda69d3db;

sol! {
#[derive(Debug, Default, Deserialize, Serialize)]
struct BlockMetadata {
bytes32 l1Hash; // constrain: anchor call
bytes32 difficulty; // constrain: l2 block's difficulty
bytes32 txListHash; // constrain: l2 txlist
bytes32 extraData; // constrain: l2 block's extra data
uint64 id; // constrain: l2 block's number
uint64 timestamp; // constrain: l2 block's timestamp
uint64 l1Height; // constrain: anchor
uint32 gasLimit; // constrain: l2 block's gas limit - anchor gas limit
address coinbase; // constrain: L2 coinbase
EthDeposit[] depositsProcessed; // constrain: l2 withdraw root
}
}

#[inline]
pub fn keccak(data: impl AsRef<[u8]>) -> [u8; 32] {
// TODO: Remove this benchmarking code once performance testing is complete.
// std::hint::black_box(sha2::Sha256::digest(&data));
Keccak256::digest(data).into()
}

impl BlockMetadata {
pub fn withdraws_root(&self) -> B256 {
// FIXME: mpt root
keccak(self.depositsProcessed.abi_encode()).into()
bytes32 l1Hash; // slot 1
bytes32 difficulty; // slot 2
bytes32 blobHash; //or txListHash (if Blob not yet supported), // slot 3
bytes32 extraData; // slot 4
bytes32 depositsHash; // slot 5
address coinbase; // L2 coinbase, // slot 6
uint64 id;
uint32 gasLimit;
uint64 timestamp; // slot 7
uint64 l1Height;
uint24 txListByteOffset;
uint24 txListByteSize;
uint16 minTier;
bool blobUsed;
bytes32 parentMetaHash; // slot 8
}

// function hashMetadata(TaikoData.BlockMetadata memory meta)
// internal
// pure
// returns (bytes32 hash)
// {
// uint256[7] memory inputs;
// inputs[0] = uint256(meta.l1Hash);
// inputs[1] = uint256(meta.difficulty);
// inputs[2] = uint256(meta.txListHash);
// inputs[3] = uint256(meta.extraData);
// inputs[4] = (uint256(meta.id)) | (uint256(meta.timestamp) << 64)
// | (uint256(meta.l1Height) << 128) | (uint256(meta.gasLimit) << 192);
// inputs[5] = uint256(uint160(meta.coinbase));
// inputs[6] = uint256(keccak256(abi.encode(meta.depositsProcessed)));

// assembly {
// hash := keccak256(inputs, 224 /*mul(7, 32)*/ )
// }
// }

pub fn hash(&self) -> B256 {
let field0 = self.l1Hash;
let field1 = self.difficulty;
let field2 = self.txListHash;
let field3 = self.extraData;
let field4: U256 = U256::from(self.id)
| U256::from(self.timestamp) << 64
| U256::from(self.l1Height) << 128
| U256::from(self.gasLimit) << 192;
let coinbase: U160 = self.coinbase.into();
let field5 = U256::from(coinbase);
let field6 = keccak(self.depositsProcessed.abi_encode());
let input: Vec<u8> = iter::empty()
.chain(field0)
.chain(field1)
.chain(field2)
.chain(field3)
.chain(field4.to_be_bytes_vec())
.chain(field5.to_be_bytes_vec())
.chain(field6)
.collect();
keccak(input).into()
#[derive(Debug, Default, Deserialize, Serialize)]
struct Transition {
bytes32 parentHash;
bytes32 blockHash;
bytes32 signalRoot;
bytes32 graffiti;
}
}

sol! {
#[derive(Debug, Default, Deserialize, Serialize)]
struct BlockEvidence {
BlockMetadata blockMetadata;
bytes32 parentHash; // constrain: l2 parent hash
bytes32 blockHash; // constrain: l2 block hash
bytes32 signalRoot; // constrain: ??l2 service account storage root??
bytes32 graffiti; // constrain: l2 block's graffiti
struct PseZkVerifierCalcInstance {
bytes32 parentHash;
bytes32 blockHash;
bytes32 signalRoot;
bytes32 graffiti;
bytes32 metaHash;
address prover;
bytes32 txListHash;
uint256 pointValue;
}

}

#[derive(Debug)]
pub enum EvidenceType {
Sgx {
prover: Address,
new_pubkey: Address, // the evidence signature public key
},
PseZk {
prover: Address,
},
PseZk,
}

impl BlockEvidence {
// keccak256(
// abi.encode(
// evidence.metaHash,
// evidence.parentHash,
// evidence.blockHash,
// evidence.signalRoot,
// evidence.graffiti,
// assignedProver,
// newPubKey
// )
// );
pub fn abi_encode(&self, evidence_type: EvidenceType) -> Vec<u8> {
use DynSolValue::*;
let mut abi_encode_tuple = vec![
FixedBytes(self.blockMetadata.hash(), 32),
FixedBytes(self.parentHash, 32),
FixedBytes(self.blockHash, 32),
FixedBytes(self.signalRoot, 32),
FixedBytes(self.graffiti, 32),
];
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct ProtocolInstance {
pub transition: Transition,
pub block_metadata: BlockMetadata,
pub prover: Address,
}

impl ProtocolInstance {
/// PseZkVerifier.sol
// function calcInstance(
// TaikoData.Transition memory tran,
// address prover,
// bytes32 metaHash,
// bytes32 txListHash,
// uint256 pointValue
// )
// return keccak256(abi.encode(tran, prover, metaHash, txListHash, pointValue));
pub fn hash(&self, evidence_type: EvidenceType) -> B256 {
match evidence_type {
EvidenceType::Sgx { prover, new_pubkey } => {
abi_encode_tuple.extend(vec![
Address(prover.to_fixed_bytes().into()),
Address(new_pubkey.to_fixed_bytes().into()),
]);
}
EvidenceType::PseZk { prover } => {
abi_encode_tuple.push(Address(prover.to_fixed_bytes().into()));
EvidenceType::Sgx { new_pubkey: _ } => todo!(),
EvidenceType::PseZk => {
// keccak256(abi.encode(tran, prover, metaHash, txListHash, pointValue));
keccak(self.abi_encode()).into()
}
};
// println!("BlockEvidence abi_encode_tuple: {:?}", abi_encode_tuple);
Tuple(abi_encode_tuple).abi_encode()
}
}

pub fn hash(&self, evidence_type: EvidenceType) -> B256 {
keccak(self.abi_encode(evidence_type)).into()
pub fn abi_encode(&self) -> Vec<u8> {
let meta_hash = keccak(self.block_metadata.abi_encode());
PseZkVerifierCalcInstance {
parentHash: self.transition.parentHash,
blockHash: self.transition.blockHash,
signalRoot: self.transition.signalRoot,
graffiti: self.transition.graffiti,
metaHash: meta_hash.into(),
prover: self.prover.as_fixed_bytes().into(),
txListHash: self.block_metadata.blobHash,
pointValue: U256::from(0),
}
.abi_encode()
}
}

#[derive(Debug, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ProtocolInstance {
pub block_evidence: BlockEvidence,
pub prover: Address,
}
pub fn parentHash(&self) -> Vec<u8> {
self.transition.parentHash.abi_encode()
}

pub const ANCHOR_METHOD_SIGNATURE: u32 = 0xda69d3db;
pub fn blockHash(&self) -> Vec<u8> {
self.transition.blockHash.abi_encode()
}

impl ProtocolInstance {
/// gen anchor call
// anchor(l1_hash,signal_root,l1_height,parent_gas_used)
pub fn anchor_call(&self, parent_gas_used: u32) -> Bytes {
let mut result = Vec::new();
result.extend_from_slice(&ANCHOR_METHOD_SIGNATURE.to_be_bytes());
result.extend_from_slice(self.block_evidence.blockMetadata.l1Hash.as_slice());
result.extend_from_slice(self.block_evidence.signalRoot.as_slice());
result.extend_from_slice(self.block_evidence.blockMetadata.l1Hash.as_slice());
result.extend_from_slice(&(parent_gas_used as u64).to_word().to_be_bytes());
result.into()
pub fn signalRoot(&self) -> Vec<u8> {
self.transition.signalRoot.abi_encode()
}

pub fn graffiti(&self) -> Vec<u8> {
self.transition.graffiti.abi_encode()
}

pub fn prover(&self) -> Vec<u8> {
self.prover.as_fixed_bytes().abi_encode()
}

pub fn meta_hash(&self) -> Vec<u8> {
keccak(self.block_metadata.abi_encode()).into()
}

pub fn tx_list_hash(&self) -> Vec<u8> {
self.block_metadata.blobHash.abi_encode()
}

pub fn point_value(&self) -> Vec<u8> {
U256::from(0).abi_encode()
}
}

#[inline]
pub fn keccak(data: impl AsRef<[u8]>) -> [u8; 32] {
// TODO: Remove this benchmarking code once performance testing is complete.
// std::hint::black_box(sha2::Sha256::digest(&data));
Keccak256::digest(data).into()
}
18 changes: 9 additions & 9 deletions integration-tests/src/integration_public_data_circuits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod public_data_test {
use crate::get_client;
use bus_mapping::{
circuit_input_builder::{
protocol_instance::{BlockEvidence, BlockMetadata},
protocol_instance::{BlockMetadata, Transition},
BuilderClient, CircuitsParams, ProtocolInstance,
},
rpc::BlockNumber,
Expand Down Expand Up @@ -336,13 +336,13 @@ mod public_data_test {
}

fn gen_requests() -> Vec<ProtocolInstance> {
let metadata = BlockMetadata {
l1Hash: parse_hash("8374d2fde2f3e5640f0ce4f6bb557e988336c2dae71e55cb3734c5c6be450820")
let block_metadata = BlockMetadata {
l1Hash: parse_hash("6e3b781b2d9a04e21ecba49e67dc3fb0a8242408cc07fa6fed5d8bd0eca2c985")
.unwrap()
.as_fixed_bytes()
.into(),
txListHash: parse_hash(
"b3de7eaf38c3c84a34d7d80100c1b133bd7734f03b5c8e86cb806d684b718d85",
blobHash: parse_hash(
"569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd",
)
.unwrap()
.as_fixed_bytes()
Expand All @@ -357,8 +357,7 @@ mod public_data_test {
..Default::default()
};

let block_evidence = BlockEvidence {
blockMetadata: metadata,
let transition = Transition {
parentHash: parse_hash(
"beb327617555bd45c05ac7e33d2c509c77192eb8c372873483696b1a7367750a",
)
Expand All @@ -381,7 +380,8 @@ mod public_data_test {
};

let protocol_instance = ProtocolInstance {
block_evidence,
transition,
block_metadata,
..Default::default()
};
vec![protocol_instance]
Expand All @@ -391,7 +391,7 @@ mod public_data_test {
circuits_params: CircuitsParams,
protocol_instance: ProtocolInstance,
) -> Block<Fr> {
let block_num = protocol_instance.block_evidence.blockMetadata.id;
let block_num = protocol_instance.block_metadata.id;
let cli = get_client();

let cli = BuilderClient::new(cli, circuits_params, Some(protocol_instance.clone()))
Expand Down
1 change: 0 additions & 1 deletion zkevm-circuits/src/table/keccak_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ impl KeccakTable {
challenge,
)
});

vec![[
Value::known(F::ONE),
input_rlc,
Expand Down
Loading
Loading