Skip to content

Commit 735abd8

Browse files
committed
tmp
1 parent effe773 commit 735abd8

27 files changed

Lines changed: 1552 additions & 121 deletions

Cargo.lock

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

common/types/message/message.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,14 @@ type OpenVMProof struct {
169169
PublicValues []byte `json:"public_values"`
170170
}
171171

172-
// Proof for flatten VM stark proof (v0.9.0+)
172+
// Proof for flatten VM stark proof (v0.9.0+).
173+
// Mirrors scroll_zkvm_types::proof::StarkProof used by the OpenVM v2 prover.
173174
type OpenVMStarkProof struct {
174-
Proof []byte `json:"proofs"`
175-
PublicValues []byte `json:"public_values"`
176-
UserPvsProof []byte `json:"user_pvs_proof"`
177-
Stat *OpenVMProofStat `json:"stat,omitempty"`
175+
Proof []byte `json:"proof"`
176+
UserPvsProof []byte `json:"user_pvs_proof"`
177+
Baseline []byte `json:"baseline,omitempty"`
178+
DeferralMerkleProofs []byte `json:"deferral_merkle_proofs,omitempty"`
179+
Stat *OpenVMProofStat `json:"stat,omitempty"`
178180
}
179181

180182
// Proof for flatten EVM proof
@@ -254,10 +256,10 @@ func (ap *OpenVMBatchProof) SanityCheck() error {
254256
return errors.New("vk not ready")
255257
}
256258
pf := ap.StarkProof
257-
if pf.Proof == nil {
259+
if len(pf.Proof) == 0 {
258260
return errors.New("proof data not ready")
259261
}
260-
if len(pf.PublicValues) == 0 {
262+
if len(pf.UserPvsProof) == 0 {
261263
return errors.New("proof public value not ready")
262264
}
263265
}

coordinator/internal/controller/api/get_task.go

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package api
33
import (
44
"errors"
55
"fmt"
6-
"math/rand"
6+
"sort"
77

88
"github.com/gin-gonic/gin"
99
"github.com/prometheus/client_golang/prometheus"
@@ -79,7 +79,9 @@ func (ptc *GetTaskController) incGetTaskAccessCounter(ctx *gin.Context) error {
7979
return nil
8080
}
8181

82-
// GetTasks get assigned chunk/batch task
82+
// GetTasks get assigned chunk/batch/bundle task, trying proof types in priority
83+
// order: Bundle > Batch > Chunk. This lets the pipeline finalize the earliest
84+
// ready bundle before proving unrelated chunks/batches further ahead.
8385
func (ptc *GetTaskController) GetTasks(ctx *gin.Context) {
8486
var getTaskParameter coordinatorType.GetTaskParameter
8587
if err := ctx.ShouldBind(&getTaskParameter); err != nil {
@@ -99,35 +101,36 @@ func (ptc *GetTaskController) GetTasks(ctx *gin.Context) {
99101
}
100102
}
101103

102-
proofType := ptc.proofType(&getTaskParameter)
103-
proverTask, isExist := ptc.proverTasks[proofType]
104-
if !isExist {
105-
nerr := fmt.Errorf("parameter wrong proof type:%v", proofType)
106-
types.RenderFailure(ctx, types.ErrCoordinatorParameterInvalidNo, nerr)
107-
return
108-
}
104+
proofTypes := ptc.prioritizedProofTypes(&getTaskParameter)
109105

110106
if err := ptc.incGetTaskAccessCounter(ctx); err != nil {
111107
log.Warn("get_task access counter inc failed", "error", err.Error())
112108
}
113109

114-
result, err := proverTask.Assign(ctx, &getTaskParameter)
115-
if err != nil {
116-
nerr := fmt.Errorf("return prover task err:%w", err)
117-
types.RenderFailure(ctx, types.ErrCoordinatorGetTaskFailure, nerr)
118-
return
119-
}
110+
for _, proofType := range proofTypes {
111+
proverTask, isExist := ptc.proverTasks[proofType]
112+
if !isExist {
113+
continue
114+
}
120115

121-
if result == nil {
122-
nerr := errors.New("get empty prover task")
123-
types.RenderFailure(ctx, types.ErrCoordinatorEmptyProofData, nerr)
124-
return
116+
result, err := proverTask.Assign(ctx, &getTaskParameter)
117+
if err != nil {
118+
nerr := fmt.Errorf("return prover task err:%w", err)
119+
types.RenderFailure(ctx, types.ErrCoordinatorGetTaskFailure, nerr)
120+
return
121+
}
122+
123+
if result != nil {
124+
types.RenderSuccess(ctx, result)
125+
return
126+
}
125127
}
126128

127-
types.RenderSuccess(ctx, result)
129+
nerr := errors.New("get empty prover task")
130+
types.RenderFailure(ctx, types.ErrCoordinatorEmptyProofData, nerr)
128131
}
129132

130-
func (ptc *GetTaskController) proofType(para *coordinatorType.GetTaskParameter) message.ProofType {
133+
func (ptc *GetTaskController) prioritizedProofTypes(para *coordinatorType.GetTaskParameter) []message.ProofType {
131134
var proofTypes []message.ProofType
132135
for _, proofType := range para.TaskTypes {
133136
proofTypes = append(proofTypes, message.ProofType(proofType))
@@ -141,8 +144,9 @@ func (ptc *GetTaskController) proofType(para *coordinatorType.GetTaskParameter)
141144
}
142145
}
143146

144-
rand.Shuffle(len(proofTypes), func(i, j int) {
145-
proofTypes[i], proofTypes[j] = proofTypes[j], proofTypes[i]
147+
// Bundle (3) > Batch (2) > Chunk (1)
148+
sort.Slice(proofTypes, func(i, j int) bool {
149+
return proofTypes[i] > proofTypes[j]
146150
})
147-
return proofTypes[0]
151+
return proofTypes
148152
}

coordinator/internal/orm/batch.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,13 +211,25 @@ func (o *Batch) GetAttemptsByHash(ctx context.Context, hash string) (int16, int1
211211
func (o *Batch) CheckIfBundleBatchProofsAreReady(ctx context.Context, bundleHash string) (bool, error) {
212212
db := o.db.WithContext(ctx)
213213
db = db.Model(&Batch{})
214+
db = db.Where("bundle_hash = ?", bundleHash)
215+
216+
var totalCount int64
217+
if err := db.Count(&totalCount).Error; err != nil {
218+
return false, fmt.Errorf("Batch.CheckIfBundleBatchProofsAreReady error: %w, bundle hash: %v", err, bundleHash)
219+
}
220+
if totalCount == 0 {
221+
return false, nil
222+
}
223+
224+
db = o.db.WithContext(ctx)
225+
db = db.Model(&Batch{})
214226
db = db.Where("bundle_hash = ? AND proving_status != ?", bundleHash, types.ProvingTaskVerified)
215227

216-
var count int64
217-
if err := db.Count(&count).Error; err != nil {
218-
return false, fmt.Errorf("Chunk.CheckIfBundleBatchProofsAreReady error: %w, bundle hash: %v", err, bundleHash)
228+
var unreadyCount int64
229+
if err := db.Count(&unreadyCount).Error; err != nil {
230+
return false, fmt.Errorf("Batch.CheckIfBundleBatchProofsAreReady error: %w, bundle hash: %v", err, bundleHash)
219231
}
220-
return count == 0, nil
232+
return unreadyCount == 0, nil
221233
}
222234

223235
// GetBatchByHash retrieves the given batch.

coordinator/internal/orm/chunk.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,25 @@ func (o *Chunk) GetProvingStatusByHash(ctx context.Context, hash string) (types.
171171
func (o *Chunk) CheckIfBatchChunkProofsAreReady(ctx context.Context, batchHash string) (bool, error) {
172172
db := o.db.WithContext(ctx)
173173
db = db.Model(&Chunk{})
174+
db = db.Where("batch_hash = ?", batchHash)
175+
176+
var totalCount int64
177+
if err := db.Count(&totalCount).Error; err != nil {
178+
return false, fmt.Errorf("Chunk.CheckIfBatchChunkProofsAreReady error: %w, batch hash: %v", err, batchHash)
179+
}
180+
if totalCount == 0 {
181+
return false, nil
182+
}
183+
184+
db = o.db.WithContext(ctx)
185+
db = db.Model(&Chunk{})
174186
db = db.Where("batch_hash = ? AND proving_status != ?", batchHash, types.ProvingTaskVerified)
175187

176-
var count int64
177-
if err := db.Count(&count).Error; err != nil {
188+
var unreadyCount int64
189+
if err := db.Count(&unreadyCount).Error; err != nil {
178190
return false, fmt.Errorf("Chunk.CheckIfBatchChunkProofsAreReady error: %w, batch hash: %v", err, batchHash)
179191
}
180-
return count == 0, nil
192+
return unreadyCount == 0, nil
181193
}
182194

183195
// GetChunkByHash retrieves the given chunk.

crates/prover-bin/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ futures-util = "0.3"
2323
reqwest = { version = "0.12", features = ["gzip", "stream"] }
2424
hex = "0.4.3"
2525

26+
# OpenVM v2+ deferred STARK verification helpers for batch/bundle proving.
27+
openvm-circuit = { git = "https://github.com/openvm-org/openvm.git", tag = "v2.0.0" }
28+
openvm-continuations = { git = "https://github.com/openvm-org/openvm.git", tag = "v2.0.0" }
29+
openvm-sdk = { git = "https://github.com/openvm-org/openvm.git", tag = "v2.0.0" }
30+
openvm-stark-sdk = { git = "https://github.com/openvm-org/stark-backend.git", tag = "v2.0.0" }
31+
openvm-verify-stark-circuit = { git = "https://github.com/openvm-org/openvm.git", tag = "v2.0.0" }
32+
openvm-verify-stark-host = { git = "https://github.com/openvm-org/openvm.git", tag = "v2.0.0" }
33+
2634
rand = "0.8.5"
2735
tokio = "1.37.0"
2836
async-trait = "0.1"

crates/prover-bin/src/deferral.rs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
use eyre::Result;
2+
use openvm_circuit::system::memory::merkle::public_values::UserPublicValuesProof;
3+
use openvm_sdk::SC;
4+
use openvm_stark_sdk::openvm_stark_backend::{codec::Decode, proof::Proof};
5+
use openvm_verify_stark_host::{
6+
deferral::DeferralMerkleProofs,
7+
vk::{VerificationBaseline, VmStarkVerifyingKey},
8+
VmStarkProof,
9+
};
10+
use openvm_sdk::DeferralInput;
11+
use scroll_zkvm_types::proof::StarkProof;
12+
use std::io::Cursor;
13+
14+
/// Compute deferred STARK verification data required by OpenVM v2+ aggregation circuits.
15+
///
16+
/// For batch/bundle proving the guest reads `input_commits` from stdin and the host must
17+
/// additionally supply `DeferralInput`s and `DeferralState`s to the SDK prover. This function
18+
/// derives all three from the child STARK proofs, the child aggregation VK and the parent's
19+
/// deferral cached commit.
20+
pub fn compute_deferral_data(
21+
child_agg_vk: &openvm_stark_sdk::openvm_stark_backend::keygen::types::MultiStarkVerifyingKey<SC>,
22+
parent_deferral_cached_commit: openvm_continuations::CommitBytes,
23+
proofs: &[&StarkProof],
24+
) -> Result<(Vec<[u8; 32]>, Vec<DeferralInput>, Vec<openvm_circuit::arch::deferral::DeferralState>)> {
25+
let mvk = (*child_agg_vk).clone();
26+
27+
let (vm_proofs, baselines): (Vec<VmStarkProof>, Vec<VerificationBaseline>) = proofs
28+
.iter()
29+
.map(|p| decode_stark_proof(p))
30+
.collect::<Result<Vec<_>>>()?
31+
.into_iter()
32+
.unzip();
33+
34+
let baseline = baselines
35+
.first()
36+
.cloned()
37+
.ok_or_else(|| eyre::eyre!("no child proofs to compute deferral data"))?;
38+
for (i, b) in baselines.iter().enumerate().skip(1) {
39+
if b.app_exe_commit != baseline.app_exe_commit || b.app_vk_commit != baseline.app_vk_commit
40+
{
41+
eyre::bail!(
42+
"child proof {i} has a different verification baseline; all child proofs must use the same app exe/vk commitment"
43+
);
44+
}
45+
}
46+
47+
let vk = VmStarkVerifyingKey { mvk, baseline };
48+
49+
let cached_commit: openvm_stark_sdk::config::baby_bear_poseidon2::Digest =
50+
parent_deferral_cached_commit.into();
51+
52+
let raw_results = openvm_verify_stark_circuit::extension::get_raw_deferral_results(
53+
&vk,
54+
&vm_proofs,
55+
cached_commit,
56+
)
57+
.map_err(|e| eyre::eyre!("get_raw_deferral_results failed: {e}"))?;
58+
59+
let input_commits: Vec<[u8; 32]> = raw_results
60+
.iter()
61+
.map(|r| {
62+
r.input
63+
.as_slice()
64+
.try_into()
65+
.expect("input commit must be 32 bytes")
66+
})
67+
.collect();
68+
69+
let deferral_inputs = vec![DeferralInput::from_inputs(&vm_proofs)];
70+
71+
let deferral_state = openvm_verify_stark_circuit::extension::get_deferral_state(
72+
&vk,
73+
&vm_proofs,
74+
cached_commit,
75+
0,
76+
)
77+
.map_err(|e| eyre::eyre!("get_deferral_state failed: {e}"))?;
78+
79+
Ok((input_commits, deferral_inputs, vec![deferral_state]))
80+
}
81+
82+
fn decode_stark_proof(proof: &StarkProof) -> Result<(VmStarkProof, VerificationBaseline)> {
83+
let inner = Proof::<SC>::decode_from_bytes(&proof.proof)
84+
.map_err(|e| eyre::eyre!("decode proof failed: {e}"))?;
85+
let user_pvs_proof =
86+
UserPublicValuesProof::decode::<SC, _>(&mut Cursor::new(&proof.user_pvs_proof))
87+
.map_err(|e| eyre::eyre!("decode user_pvs_proof failed: {e}"))?;
88+
let deferral_merkle_proofs = if proof.deferral_merkle_proofs.is_empty() {
89+
None
90+
} else {
91+
Some(
92+
DeferralMerkleProofs::decode(&mut Cursor::new(&proof.deferral_merkle_proofs))
93+
.map_err(|e| eyre::eyre!("decode deferral_merkle_proofs failed: {e}"))?,
94+
)
95+
};
96+
let baseline = if proof.baseline.is_empty() {
97+
eyre::bail!("stark proof missing verification baseline");
98+
} else {
99+
serde_json::from_slice(&proof.baseline)
100+
.map_err(|e| eyre::eyre!("decode baseline failed: {e}"))?
101+
};
102+
Ok((
103+
VmStarkProof {
104+
inner,
105+
user_pvs_proof,
106+
deferral_merkle_proofs,
107+
},
108+
baseline,
109+
))
110+
}

crates/prover-bin/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod dumper;
2+
mod deferral;
23
mod prover;
34
mod types;
45
mod zk_circuits_handler;

0 commit comments

Comments
 (0)