Skip to content

Commit 7f500c6

Browse files
committed
Merge branch 'feat/aggregation-mode' into feat/aggregation-mode-explorer
2 parents 36a9a93 + 3406e43 commit 7f500c6

File tree

8 files changed

+51
-87
lines changed

8 files changed

+51
-87
lines changed

Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ start_proof_aggregator_local:
155155
cargo run --manifest-path ./aggregation-mode/Cargo.toml --release -- config-files/config-proof-aggregator.yaml
156156

157157
start_proof_aggregator_local_with_proving:
158-
cd aggregation-mode && \
159158
cargo run --manifest-path ./aggregation-mode/Cargo.toml --release --features prove -- config-files/config-proof-aggregator.yaml
160159

161160
_AGGREGATOR_:

aggregation-mode/abi/AlignedProofAggregationService.json

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

aggregation-mode/readme.md

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,59 +4,54 @@
44
## How to run it locally
55

66
1. Deploy aligned contracts on anvil:
7+
78
```shell
89
make deploy_aligned_contracts
910
```
1011

1112
2. Start anvil:
13+
1214
```shell
1315
make anvil_start_with_block_time
1416
```
1517

1618
3. Start batcher
19+
1720
```shell
1821
make start_batcher_local
1922
```
2023

2124
4. Send SP1 proofs:
25+
2226
```shell
2327
make batcher_send_sp1_burst
2428
```
2529

2630
5. Start proof aggregator:
27-
```shell
31+
32+
```shell
2833
# This will not run a real prover but a mocked one see below to run a real prover
2934
make start_proof_aggregator_local
3035
```
31-
Note: it might take a while to compile as it uses more aggressive optimization levels.
32-
33-
You should it will fetch the new batch logs from the BatcherService and aggregate the compressed SP1 proofs from them.
3436

35-
### Run it with proving
37+
or
3638

37-
By default, on dev environments, the proving is mocked and the ProofAggregationService contract skips verification as proves are mocked. To run the service with proving you need to run change the commands on step `1.` and `4.`:
38-
39-
1. Start anvil with verification activated:
40-
```shell
41-
make anvil_start_with_verification
42-
```
43-
44-
4. Start proof aggregator with proving:
4539
```shell
4640
make start_proof_aggregator_local_with_proving
4741
```
4842

49-
Note: Unless you constraint yourself to a few proofs, this requires a powerful machine with GPU.
50-
43+
Note: Proving can be quite slow without GPUs
5144

5245
### Check the logs
5346

5447
1. Get latest aggregated proof:
48+
5549
```shell
5650
cast call 0xcbEAF3BDe82155F56486Fb5a1072cb8baAf547cc "currentAggregatedProofNumber()" --rpc-url http://localhost:8545
5751
```
5852

5953
2. Get aggregated proof info:
54+
6055
```shell
6156
cast call 0xcbEAF3BDe82155F56486Fb5a1072cb8baAf547cc "getAggregatedProof(uint64)(uint8,bytes32,bytes32)" <AGG_PROOF_NUMBER> --rpc-url http://localhost:8545
6257
```

aggregation-mode/src/backend/mod.rs

Lines changed: 27 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ use alloy::{
1313
consensus::{Blob, BlobTransactionSidecar},
1414
eips::eip4844::BYTES_PER_BLOB,
1515
hex,
16-
network::{EthereumWallet, TransactionBuilder4844},
16+
network::EthereumWallet,
1717
primitives::{Address, FixedBytes},
18-
providers::{PendingTransactionError, Provider, ProviderBuilder, WalletProvider},
19-
rpc::types::{TransactionReceipt, TransactionRequest},
18+
providers::{PendingTransactionError, ProviderBuilder},
19+
rpc::types::TransactionReceipt,
2020
signers::local::LocalSigner,
2121
};
2222
use config::Config;
@@ -25,22 +25,21 @@ use merkle_tree::compute_proofs_merkle_root;
2525
use sp1_sdk::HashableKey;
2626
use std::str::FromStr;
2727
use tracing::{error, info, warn};
28-
use types::{
29-
AlignedProofAggregationService, AlignedProofAggregationServiceContract, RPCProviderWithSigner,
30-
};
28+
use types::{AlignedProofAggregationService, AlignedProofAggregationServiceContract};
3129

3230
#[derive(Debug)]
3331
pub enum AggregatedProofSubmissionError {
3432
Aggregation(ProofAggregationError),
35-
SendBlobTransaction,
33+
BuildingBlobCommitment,
34+
BuildingBlobProof,
35+
BuildingBlobVersionedHash,
3636
SendVerifyAggregatedProofTransaction(alloy::contract::Error),
3737
ReceiptError(PendingTransactionError),
3838
FetchingProofs(ProofsFetcherError),
3939
}
4040

4141
pub struct ProofAggregator {
4242
engine: ZKVMEngine,
43-
rpc_provider: RPCProviderWithSigner,
4443
proof_aggregation_service: AlignedProofAggregationServiceContract,
4544
fetcher: ProofsFetcher,
4645
}
@@ -58,15 +57,14 @@ impl ProofAggregator {
5857
let proof_aggregation_service: AlignedProofAggregationService::AlignedProofAggregationServiceInstance<(), alloy::providers::fillers::FillProvider<alloy::providers::fillers::JoinFill<alloy::providers::fillers::JoinFill<alloy::providers::Identity, alloy::providers::fillers::JoinFill<alloy::providers::fillers::GasFiller, alloy::providers::fillers::JoinFill<alloy::providers::fillers::BlobGasFiller, alloy::providers::fillers::JoinFill<alloy::providers::fillers::NonceFiller, alloy::providers::fillers::ChainIdFiller>>>>, alloy::providers::fillers::WalletFiller<EthereumWallet>>, alloy::providers::RootProvider>> = AlignedProofAggregationService::new(
5958
Address::from_str(&config.proof_aggregation_service_address)
6059
.expect("Address to be correct"),
61-
rpc_provider.clone(),
60+
rpc_provider,
6261
);
6362
let fetcher = ProofsFetcher::new(config);
6463

6564
Self {
6665
engine: ZKVMEngine::SP1,
6766
proof_aggregation_service,
6867
fetcher,
69-
rpc_provider,
7068
}
7169
}
7270

@@ -131,16 +129,16 @@ impl ProofAggregator {
131129
};
132130
info!("Proof aggregation program finished");
133131

134-
info!("Sending blob transaction...");
135-
let blob_receipt = self.send_blob_transaction(leaves).await?;
132+
info!("Constructing blob...");
133+
let (blob, blob_versioned_hash) = self.construct_blob(leaves).await?;
136134
info!(
137-
"Blob transaction sent, hash: {:?}",
138-
blob_receipt.transaction_hash
135+
"Blob constructed, versioned hash: {}",
136+
hex::encode(blob_versioned_hash)
139137
);
140138

141139
info!("Sending proof to ProofAggregationService contract...");
142140
let receipt = self
143-
.send_proof_to_verify_on_chain(&blob_receipt.transaction_hash, output.proof)
141+
.send_proof_to_verify_on_chain(blob, blob_versioned_hash, output.proof)
144142
.await?;
145143
info!(
146144
"Proof sent and verified, tx hash {:?}",
@@ -152,19 +150,21 @@ impl ProofAggregator {
152150

153151
async fn send_proof_to_verify_on_chain(
154152
&self,
155-
blob_tx_hash: &[u8; 32],
153+
blob: BlobTransactionSidecar,
154+
blob_versioned_hash: [u8; 32],
156155
aggregated_proof: AggregatedProof,
157156
) -> Result<TransactionReceipt, AggregatedProofSubmissionError> {
158157
match aggregated_proof {
159158
AggregatedProof::SP1(proof) => {
160159
let res = self
161160
.proof_aggregation_service
162161
.verify(
163-
blob_tx_hash.into(),
162+
blob_versioned_hash.into(),
164163
proof.vk().bytes32_raw().into(),
165164
proof.proof.public_values.to_vec().into(),
166165
proof.proof.bytes().into(),
167166
)
167+
.sidecar(blob)
168168
.send()
169169
.await
170170
.map_err(
@@ -178,10 +178,10 @@ impl ProofAggregator {
178178
}
179179
}
180180

181-
async fn send_blob_transaction(
181+
async fn construct_blob(
182182
&self,
183183
leaves: Vec<[u8; 32]>,
184-
) -> Result<TransactionReceipt, AggregatedProofSubmissionError> {
184+
) -> Result<(BlobTransactionSidecar, [u8; 32]), AggregatedProofSubmissionError> {
185185
let data: Vec<u8> = leaves.iter().flat_map(|arr| arr.iter().copied()).collect();
186186
let mut blob_data: [u8; BYTES_PER_BLOB] = [0u8; BYTES_PER_BLOB];
187187

@@ -193,32 +193,23 @@ impl ProofAggregator {
193193
let settings = c_kzg::ethereum_kzg_settings();
194194
let blob = c_kzg::Blob::new(blob_data);
195195
let commitment = c_kzg::KzgCommitment::blob_to_kzg_commitment(&blob, settings)
196-
.map_err(|_| AggregatedProofSubmissionError::SendBlobTransaction)?;
196+
.map_err(|_| AggregatedProofSubmissionError::BuildingBlobCommitment)?;
197197
let proof =
198198
c_kzg::KzgProof::compute_blob_kzg_proof(&blob, &commitment.to_bytes(), settings)
199-
.map_err(|_| AggregatedProofSubmissionError::SendBlobTransaction)?;
199+
.map_err(|_| AggregatedProofSubmissionError::BuildingBlobProof)?;
200200

201201
// convert to alloy types
202202
let blob = Blob::from_slice(&blob_data);
203203
let commitment: FixedBytes<48> = FixedBytes::from_slice(commitment.to_bytes().as_slice());
204204
let proof: FixedBytes<48> = FixedBytes::from_slice(proof.to_bytes().as_slice());
205205

206-
let blob_sidecar = BlobTransactionSidecar::new(vec![blob], vec![commitment], vec![proof]);
207-
// send transaction to itself
208-
let to = self.rpc_provider.signer_addresses().collect::<Vec<_>>()[0];
209-
let tx = TransactionRequest::default()
210-
.to(to)
211-
.with_blob_sidecar(blob_sidecar);
212-
213-
let res = self
214-
.rpc_provider
215-
.send_transaction(tx)
216-
.await
217-
.map_err(|_| AggregatedProofSubmissionError::SendBlobTransaction)?;
206+
let blob = BlobTransactionSidecar::new(vec![blob], vec![commitment], vec![proof]);
207+
let blob_versioned_hash = blob
208+
.versioned_hash_for_blob(0)
209+
.ok_or(AggregatedProofSubmissionError::BuildingBlobVersionedHash)?
210+
.0;
218211

219-
res.get_receipt()
220-
.await
221-
.map_err(AggregatedProofSubmissionError::ReceiptError)
212+
Ok((blob, blob_versioned_hash))
222213
}
223214

224215
async fn set_aggregated_proof_as_missed(

aggregation-mode/src/backend/types.rs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -65,23 +65,3 @@ pub type RPCProvider = alloy::providers::fillers::FillProvider<
6565
>,
6666
alloy::providers::RootProvider,
6767
>;
68-
69-
pub type RPCProviderWithSigner = alloy::providers::fillers::FillProvider<
70-
alloy::providers::fillers::JoinFill<
71-
alloy::providers::fillers::JoinFill<
72-
alloy::providers::Identity,
73-
alloy::providers::fillers::JoinFill<
74-
alloy::providers::fillers::GasFiller,
75-
alloy::providers::fillers::JoinFill<
76-
alloy::providers::fillers::BlobGasFiller,
77-
alloy::providers::fillers::JoinFill<
78-
alloy::providers::fillers::NonceFiller,
79-
alloy::providers::fillers::ChainIdFiller,
80-
>,
81-
>,
82-
>,
83-
>,
84-
alloy::providers::fillers::WalletFiller<EthereumWallet>,
85-
>,
86-
alloy::providers::RootProvider,
87-
>;

contracts/scripts/anvil/state/alignedlayer-deployed-anvil-state.json

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

contracts/src/core/AlignedProofAggregationService.sol

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,32 +46,33 @@ contract AlignedProofAggregationService is
4646
}
4747

4848
function verify(
49-
bytes32 blobTransactionHash,
49+
bytes32 blobVersionedHash,
5050
bytes32 sp1ProgramVKey,
5151
bytes calldata sp1PublicValues,
5252
bytes calldata sp1ProofBytes
5353
) public onlyAlignedAggregator {
5454
// In dev mode, poofs are mocked, so we skip the verification part
5555
if (sp1VerifierAddress == VERIFIER_MOCK_ADDRESS) {
5656
(bytes32 merkleRoot) = abi.decode(sp1PublicValues, (bytes32));
57-
_newAggregatedProof(merkleRoot, blobTransactionHash);
57+
_newAggregatedProof(merkleRoot, blobVersionedHash);
5858
return;
5959
}
6060

6161
try ISP1Verifier(sp1VerifierAddress).verifyProof(sp1ProgramVKey, sp1PublicValues, sp1ProofBytes) {
6262
(bytes32 merkleRoot) = abi.decode(sp1PublicValues, (bytes32));
63-
_newAggregatedProof(merkleRoot, blobTransactionHash);
63+
_newAggregatedProof(merkleRoot, blobVersionedHash);
6464
} catch {
6565
AggregatedProof storage proof = aggregatedProofs[currentAggregatedProofNumber];
6666
proof.status = AggregatedProofStatus.Failed;
67-
emit AggregatedProofFailed(currentAggregatedProofNumber);
67+
emit NewAggregatedProof(currentAggregatedProofNumber, AggregatedProofStatus.Failed, 0x0, 0x0);
68+
currentAggregatedProofNumber += 1;
6869
}
6970
}
7071

7172
function markCurrentAggregatedProofAsMissed() public onlyAlignedAggregator {
7273
AggregatedProof storage proof = aggregatedProofs[currentAggregatedProofNumber];
7374
proof.status = AggregatedProofStatus.Missed;
74-
emit AggregatedProofMissed(currentAggregatedProofNumber);
75+
emit NewAggregatedProof(currentAggregatedProofNumber, AggregatedProofStatus.Missed, 0x0, 0x0);
7576
currentAggregatedProofNumber += 1;
7677
}
7778

@@ -80,7 +81,7 @@ contract AlignedProofAggregationService is
8081
proof.merkleRoot = merkleRoot;
8182
proof.blobHash = blobHash;
8283
proof.status = AggregatedProofStatus.Verified;
83-
emit NewAggregatedProofVerified(currentAggregatedProofNumber, merkleRoot, blobHash);
84+
emit NewAggregatedProof(currentAggregatedProofNumber, AggregatedProofStatus.Verified, merkleRoot, blobHash);
8485
currentAggregatedProofNumber += 1;
8586
}
8687

contracts/src/core/IAlignedProofAggregationService.sol

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ interface IAlignedProofAggregationService {
2424
/// @notice Method to verify an aggregated proof from aligned
2525
/// @dev This function is called by the aligned proof aggregator after collecting the proofs and aggregating them
2626
/// to be verified on-chain. We expect the blobTransactionHash to be called before
27-
/// @param blobTransactionHash the hash of the blob transaction that contains the leaves that compose the merkle root.
27+
/// @param blobVersionedHash the versioned hash of the blob transaction that contains the leaves that compose the merkle root.
2828
/// @param sp1ProgramVKey Public verifying key
2929
/// @param sp1PublicValues Values used to perform the execution
3030
/// @param sp1ProofBytes Groth16 proof
3131
function verify(
32-
bytes32 blobTransactionHash,
32+
bytes32 blobVersionedHash,
3333
bytes32 sp1ProgramVKey,
3434
bytes calldata sp1PublicValues,
3535
bytes calldata sp1ProofBytes
@@ -43,11 +43,9 @@ interface IAlignedProofAggregationService {
4343
function markCurrentAggregatedProofAsMissed() external;
4444

4545
/// @notice event that gets emitted after a successful aggregated proof verification
46-
event NewAggregatedProofVerified(uint64 indexed proofNumber, bytes32 merkleRoot, bytes32 blobTransactionHash);
47-
/// @notice event that gets emitted after a successful aggregated proof verification
48-
event AggregatedProofMissed(uint64 indexed proofNumber);
49-
/// @notice event that gets emitted after a successful aggregated proof verification
50-
event AggregatedProofFailed(uint64 indexed proofNumber);
46+
event NewAggregatedProof(
47+
uint64 indexed proofNumber, AggregatedProofStatus status, bytes32 merkleRoot, bytes32 blobVersionedHash
48+
);
5149

5250
error OnlyAlignedAggregator(address sender);
5351
}

0 commit comments

Comments
 (0)