diff --git a/coordinator/cmd/tool/verify.go b/coordinator/cmd/tool/verify.go index 414db7948..b3545e647 100644 --- a/coordinator/cmd/tool/verify.go +++ b/coordinator/cmd/tool/verify.go @@ -36,7 +36,7 @@ func verify(cCtx *cli.Context) error { return fmt.Errorf("error reading file: %w", err) } - vf, err := verifier.NewVerifier(cfg.ProverManager.Verifier) + vf, err := verifier.NewVerifier(cfg.ProverManager.Verifier, cfg.L2.ValidiumMode) if err != nil { return err } diff --git a/coordinator/internal/config/config.go b/coordinator/internal/config/config.go index 39aee600a..648aed1e9 100644 --- a/coordinator/internal/config/config.go +++ b/coordinator/internal/config/config.go @@ -65,6 +65,7 @@ type Config struct { // AssetConfig contain assets configurated for each fork, the defaul vkfile name is "OpenVmVk.json". type AssetConfig struct { AssetsPath string `json:"assets_path"` + Version uint8 `json:"version,omitempty"` ForkName string `json:"fork_name"` Vkfile string `json:"vk_file,omitempty"` MinProverVersion string `json:"min_prover_version,omitempty"` diff --git a/coordinator/internal/controller/api/controller.go b/coordinator/internal/controller/api/controller.go index ab8a191fa..d5209a072 100644 --- a/coordinator/internal/controller/api/controller.go +++ b/coordinator/internal/controller/api/controller.go @@ -24,7 +24,9 @@ var ( // InitController inits Controller with database func InitController(cfg *config.Config, chainCfg *params.ChainConfig, db *gorm.DB, reg prometheus.Registerer) { - vf, err := verifier.NewVerifier(cfg.ProverManager.Verifier) + validiumMode := cfg.L2.ValidiumMode + + vf, err := verifier.NewVerifier(cfg.ProverManager.Verifier, validiumMode) if err != nil { panic("proof receiver new verifier failure") } diff --git a/coordinator/internal/logic/verifier/verifier.go b/coordinator/internal/logic/verifier/verifier.go index c2e4cb823..36c018841 100644 --- a/coordinator/internal/logic/verifier/verifier.go +++ b/coordinator/internal/logic/verifier/verifier.go @@ -19,20 +19,34 @@ import ( "scroll-tech/coordinator/internal/config" "scroll-tech/coordinator/internal/logic/libzkp" + "scroll-tech/coordinator/internal/utils" ) // This struct maps to `CircuitConfig` in libzkp/src/verifier.rs // Define a brand new struct here is to eliminate side effects in case fields // in `*config.CircuitConfig` being changed type rustCircuitConfig struct { + Version uint `json:"version"` ForkName string `json:"fork_name"` AssetsPath string `json:"assets_path"` } +var validiumMode bool + func newRustCircuitConfig(cfg config.AssetConfig) *rustCircuitConfig { + ver := cfg.Version + if ver == 0 { + var err error + ver, err = utils.Version(cfg.ForkName, validiumMode) + if err != nil { + panic(err) + } + } + return &rustCircuitConfig{ - ForkName: cfg.ForkName, + Version: uint(ver), AssetsPath: cfg.AssetsPath, + ForkName: cfg.ForkName, } } @@ -60,7 +74,8 @@ type rustVkDump struct { } // NewVerifier Sets up a rust ffi to call verify. -func NewVerifier(cfg *config.VerifierConfig) (*Verifier, error) { +func NewVerifier(cfg *config.VerifierConfig, useValidiumMode bool) (*Verifier, error) { + validiumMode = useValidiumMode verifierConfig := newRustVerifierConfig(cfg) configBytes, err := json.Marshal(verifierConfig) if err != nil { diff --git a/coordinator/internal/utils/version.go b/coordinator/internal/utils/version.go new file mode 100644 index 000000000..dde14109f --- /dev/null +++ b/coordinator/internal/utils/version.go @@ -0,0 +1,33 @@ +package utils + +import ( + "errors" + "strings" +) + +// version get the version for the chain instance +// +// TODO: This is not foolproof and does not cover all scenarios. +func Version(hardForkName string, ValidiumMode bool) (uint8, error) { + + var domain, stfVersion uint8 + + if ValidiumMode { + domain = 1 + stfVersion = 1 + } else { + domain = 0 + switch canonicalName := strings.ToLower(hardForkName); canonicalName { + case "euclidv1": + stfVersion = 6 + case "euclidv2": + stfVersion = 7 + case "feynman": + stfVersion = 8 + default: + return 0, errors.New("unknown fork name " + canonicalName) + } + } + + return (domain << 6) + stfVersion, nil +} diff --git a/crates/libzkp/src/proofs.rs b/crates/libzkp/src/proofs.rs index 58566a33a..f57d3fdf0 100644 --- a/crates/libzkp/src/proofs.rs +++ b/crates/libzkp/src/proofs.rs @@ -8,9 +8,10 @@ use scroll_zkvm_types::{ bundle::BundleInfo, chunk::ChunkInfo, proof::{EvmProof, OpenVmEvmProof, ProofEnum, StarkProof}, - public_inputs::{ForkName, MultiVersionPublicInputs}, + public_inputs::MultiVersionPublicInputs, types_agg::AggregationInput, utils::{serialize_vk, vec_as_base64}, + version, }; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -181,13 +182,13 @@ impl WrappedProof { /// Sanity checks on the wrapped proof: /// /// - pi_hash computed in host does in fact match pi_hash computed in guest - pub fn pi_hash_check(&self, fork_name: ForkName) -> bool { + pub fn pi_hash_check(&self, ver: version::Version) -> bool { let proof_pi = self.proof.public_values(); let expected_pi = self .metadata .pi_hash_info() - .pi_hash_by_fork(fork_name) + .pi_hash_by_version(ver) .0 .as_ref() .iter() diff --git a/crates/libzkp/src/verifier.rs b/crates/libzkp/src/verifier.rs index 5f6168798..67aab8ba6 100644 --- a/crates/libzkp/src/verifier.rs +++ b/crates/libzkp/src/verifier.rs @@ -41,6 +41,7 @@ pub trait ProofVerifier { #[derive(Debug, Serialize, Deserialize)] pub struct CircuitConfig { + pub version: u8, pub fork_name: String, pub assets_path: String, } @@ -61,14 +62,14 @@ pub fn init(config: VerifierConfig) { for cfg in &config.circuits { let canonical_fork_name = cfg.fork_name.to_lowercase(); - let verifier = Verifier::new(&cfg.assets_path, canonical_fork_name.as_str().into()); + let verifier = Verifier::new(&cfg.assets_path, cfg.version); let ret = verifiers.insert(canonical_fork_name, Arc::new(Mutex::new(verifier))); assert!( ret.is_none(), "DO NOT init the same fork {} twice", cfg.fork_name ); - tracing::info!("load verifier config for fork {}", cfg.fork_name); + tracing::info!("load verifier config for fork {} (ver {})", cfg.fork_name, cfg.version); } let ret = VERIFIERS.set(verifiers).is_ok(); diff --git a/crates/libzkp/src/verifier/universal.rs b/crates/libzkp/src/verifier/universal.rs index 5fb8d0958..05a52b737 100644 --- a/crates/libzkp/src/verifier/universal.rs +++ b/crates/libzkp/src/verifier/universal.rs @@ -6,22 +6,22 @@ use crate::{ proofs::{AsRootProof, BatchProof, BundleProof, ChunkProof, IntoEvmProof}, utils::panic_catch, }; -use scroll_zkvm_types::public_inputs::ForkName; +use scroll_zkvm_types::version::Version; use scroll_zkvm_verifier::verifier::UniversalVerifier; use std::path::Path; pub struct Verifier { verifier: UniversalVerifier, - fork: ForkName, + version: Version, } impl Verifier { - pub fn new(assets_dir: &str, fork: ForkName) -> Self { + pub fn new(assets_dir: &str, ver_n: u8) -> Self { let verifier_bin = Path::new(assets_dir); Self { verifier: UniversalVerifier::setup(verifier_bin).expect("Setting up chunk verifier"), - fork, + version: Version::from(ver_n), } } } @@ -31,21 +31,21 @@ impl ProofVerifier for Verifier { panic_catch(|| match task_type { TaskType::Chunk => { let proof = serde_json::from_slice::(proof).unwrap(); - assert!(proof.pi_hash_check(self.fork)); + assert!(proof.pi_hash_check(self.version)); self.verifier .verify_stark_proof(proof.as_root_proof(), &proof.vk) .unwrap() } TaskType::Batch => { let proof = serde_json::from_slice::(proof).unwrap(); - assert!(proof.pi_hash_check(self.fork)); + assert!(proof.pi_hash_check(self.version)); self.verifier .verify_stark_proof(proof.as_root_proof(), &proof.vk) .unwrap() } TaskType::Bundle => { let proof = serde_json::from_slice::(proof).unwrap(); - assert!(proof.pi_hash_check(self.fork)); + assert!(proof.pi_hash_check(self.version)); let vk = proof.vk.clone(); let evm_proof = proof.into_evm_proof(); self.verifier.verify_evm_proof(&evm_proof, &vk).unwrap()