Skip to content

Commit c574668

Browse files
committed
feat: add a POC for proposing with real time proofs
1 parent c3d2479 commit c574668

10 files changed

Lines changed: 25943 additions & 13 deletions

File tree

common/src/l2/taiko_driver/models.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub struct BuildPreconfBlockRequestBody {
1414
pub struct BuildPreconfBlockResponse {
1515
pub number: u64,
1616
pub hash: B256,
17+
pub state_root: B256,
1718
pub parent_hash: B256,
1819
}
1920

@@ -28,6 +29,7 @@ impl BuildPreconfBlockResponse {
2829
)
2930
.ok()?,
3031
hash: Self::to_b256(header.get("hash")?.as_str()?)?,
32+
state_root: Self::to_b256(header.get("stateRoot")?.as_str()?)?,
3133
parent_hash: Self::to_b256(header.get("parentHash")?.as_str()?)?,
3234
})
3335
}

shasta/src/l1/execution_layer.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@ use common::{
2222
};
2323
use pacaya::l1::traits::{OperatorError, PreconfOperator, WhitelistProvider};
2424
use std::sync::Arc;
25-
use taiko_bindings::inbox::{
26-
IForcedInclusionStore::ForcedInclusion,
27-
IInbox::CoreState,
28-
Inbox::{self, InboxInstance},
25+
use taiko_bindings::{
26+
anchor::ICheckpointStore::Checkpoint,
27+
inbox::{
28+
IForcedInclusionStore::ForcedInclusion,
29+
IInbox::CoreState,
30+
Inbox::{self, InboxInstance},
31+
},
2932
};
3033
use tokio::sync::mpsc::Sender;
3134
use tracing::info;
@@ -37,6 +40,8 @@ pub struct ExecutionLayer {
3740
pub transaction_monitor: TransactionMonitor,
3841
contract_addresses: ContractAddresses,
3942
inbox_instance: InboxInstance<DynProvider>,
43+
// Surge: For signing the state checkpoints sent as proof with proposal
44+
checkpoint_signer: alloy::signers::local::PrivateKeySigner,
4045
}
4146

4247
impl ELTrait for ExecutionLayer {
@@ -91,6 +96,12 @@ impl ELTrait for ExecutionLayer {
9196
transaction_monitor,
9297
contract_addresses,
9398
inbox_instance,
99+
// Surge: Hard coding the private key for the POC
100+
// (This is the first private key from foundry anvil)
101+
checkpoint_signer: alloy::signers::local::PrivateKeySigner::from_bytes(
102+
&"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
103+
.parse::<alloy::primitives::FixedBytes<32>>()?,
104+
)?,
94105
})
95106
}
96107

@@ -167,6 +178,7 @@ impl ExecutionLayer {
167178
&self,
168179
l2_blocks: Vec<L2BlockV2>,
169180
num_forced_inclusion: u8,
181+
checkpoint: Checkpoint,
170182
) -> Result<(), Error> {
171183
info!(
172184
"📦 Proposing with {} blocks | num_forced_inclusion: {}",
@@ -176,13 +188,15 @@ impl ExecutionLayer {
176188

177189
// Build propose transaction
178190
// TODO fill extra gas percentege from config
179-
let builder = ProposalTxBuilder::new(self.provider.clone(), 10);
191+
let builder =
192+
ProposalTxBuilder::new(self.provider.clone(), 10, self.checkpoint_signer.clone());
180193
let tx = builder
181194
.build_propose_tx(
182195
l2_blocks,
183196
self.preconfer_address,
184197
self.contract_addresses.shasta_inbox,
185198
num_forced_inclusion,
199+
checkpoint,
186200
)
187201
.await?;
188202

shasta/src/l1/proposal_tx_builder.rs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::l2::bindings::SurgeInbox;
12
use alloy::{
23
consensus::SidecarBuilder,
34
eips::eip4844::BlobTransactionSidecar,
@@ -8,11 +9,14 @@ use alloy::{
89
},
910
providers::{DynProvider, Provider},
1011
rpc::types::TransactionRequest,
12+
signers::Signer,
13+
sol_types::SolValue,
1114
};
1215
use alloy_json_rpc::RpcError;
1316
use anyhow::Error;
1417
use common::l1::{fees_per_gas::FeesPerGas, tools, transaction_error::TransactionError};
1518
use common::shared::l2_block_v2::L2BlockV2;
19+
use taiko_bindings::anchor::ICheckpointStore::Checkpoint;
1620
use taiko_bindings::inbox::{IInbox::ProposeInput, Inbox, LibBlobs::BlobReference};
1721
use taiko_protocol::shasta::{
1822
BlobCoder,
@@ -23,13 +27,19 @@ use tracing::warn;
2327
pub struct ProposalTxBuilder {
2428
provider: DynProvider,
2529
extra_gas_percentage: u64,
30+
checkpoint_signer: alloy::signers::local::PrivateKeySigner,
2631
}
2732

2833
impl ProposalTxBuilder {
29-
pub fn new(provider: DynProvider, extra_gas_percentage: u64) -> Self {
34+
pub fn new(
35+
provider: DynProvider,
36+
extra_gas_percentage: u64,
37+
checkpoint_signer: alloy::signers::local::PrivateKeySigner,
38+
) -> Self {
3039
Self {
3140
provider,
3241
extra_gas_percentage,
42+
checkpoint_signer,
3343
}
3444
}
3545

@@ -40,9 +50,10 @@ impl ProposalTxBuilder {
4050
from: Address,
4151
to: Address,
4252
num_forced_inclusion: u8,
53+
checkpoint: Checkpoint,
4354
) -> Result<TransactionRequest, Error> {
4455
let tx_blob = self
45-
.build_propose_blob(l2_blocks, from, to, num_forced_inclusion)
56+
.build_propose_blob(l2_blocks, from, to, num_forced_inclusion, checkpoint)
4657
.await?;
4758
let tx_blob_gas = match self.provider.estimate_gas(tx_blob.clone()).await {
4859
Ok(gas) => gas,
@@ -87,6 +98,7 @@ impl ProposalTxBuilder {
8798
from: Address,
8899
to: Address,
89100
num_forced_inclusion: u8,
101+
checkpoint: Checkpoint,
90102
) -> Result<TransactionRequest, Error> {
91103
let mut block_manifests = <Vec<BlockManifest>>::with_capacity(l2_blocks.len());
92104
for l2_block in &l2_blocks {
@@ -131,15 +143,36 @@ impl ProposalTxBuilder {
131143
let inbox = Inbox::new(to, self.provider.clone());
132144
let encoded_proposal_input = inbox.encodeProposeInput(input).call().await?;
133145

146+
// Surge: using `proposeWithProof(..)` in Surge Inbox
147+
let proof_data = self.build_proof_data(&checkpoint).await?;
134148
let tx = TransactionRequest::default()
135149
.with_from(from)
136150
.with_to(to)
137151
.with_blob_sidecar(sidecar)
138-
.with_call(&Inbox::proposeCall {
152+
.with_call(&SurgeInbox::proposeWithProofCall {
139153
_lookahead: Bytes::new(),
140154
_data: encoded_proposal_input,
155+
_proof: proof_data,
141156
});
142157

143158
Ok(tx)
144159
}
160+
161+
// Surge: builds the 161-byte proof data
162+
// [0..96: ABI-encoded checkpoint][96..161: signed checkpoint digest]
163+
async fn build_proof_data(&self, checkpoint: &Checkpoint) -> Result<Bytes, Error> {
164+
let checkpoint_encoded = checkpoint.abi_encode();
165+
let checkpoint_digest = alloy::primitives::keccak256(&checkpoint_encoded);
166+
let signature = self.checkpoint_signer.sign_hash(&checkpoint_digest).await?;
167+
168+
let mut signature_bytes = [0_u8; 65];
169+
signature_bytes[..32].copy_from_slice(signature.r().to_be_bytes::<32>().as_slice());
170+
signature_bytes[32..64].copy_from_slice(signature.s().to_be_bytes::<32>().as_slice());
171+
signature_bytes[64] = (signature.v() as u8) + 27;
172+
173+
let mut proof_data = Vec::with_capacity(161);
174+
proof_data.extend_from_slice(&checkpoint_encoded);
175+
proof_data.extend_from_slice(&signature_bytes);
176+
Ok(Bytes::from(proof_data))
177+
}
145178
}

shasta/src/l2/abi/Bridge.json

Lines changed: 24093 additions & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)