mirror of
https://github.com/scroll-tech/scroll.git
synced 2026-01-12 07:28:08 -05:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dab21fc712 | ||
|
|
c44b7f7bf4 | ||
|
|
a8c71b5e36 | ||
|
|
ae2f62df00 | ||
|
|
ce5c6e0aa3 | ||
|
|
e8ddf99184 | ||
|
|
ebf2b429a3 | ||
|
|
db46ce408d | ||
|
|
3d1a8374d0 | ||
|
|
574aa68491 | ||
|
|
589388b288 | ||
|
|
af8175800f | ||
|
|
e6793a85f5 | ||
|
|
7e9f3b7376 | ||
|
|
8b611b443a | ||
|
|
1f62596b0a | ||
|
|
a2b9878733 | ||
|
|
e166dfba48 | ||
|
|
d7d62eb8e6 | ||
|
|
61eb75fbb6 | ||
|
|
e9af5912ac |
4
.github/workflows/bridge.yml
vendored
4
.github/workflows/bridge.yml
vendored
@@ -43,8 +43,6 @@ jobs:
|
||||
version: '0.8.16'
|
||||
- name: Install Geth Tools
|
||||
uses: gacts/install-geth-tools@v1
|
||||
with:
|
||||
version: 1.10.19
|
||||
- name: Lint
|
||||
working-directory: 'bridge'
|
||||
run: |
|
||||
@@ -94,8 +92,6 @@ jobs:
|
||||
version: '0.8.16'
|
||||
- name: Install Geth Tools
|
||||
uses: gacts/install-geth-tools@v1
|
||||
with:
|
||||
version: 1.10.19
|
||||
- name: Build prerequisites
|
||||
run: |
|
||||
make dev_docker
|
||||
|
||||
6
.github/workflows/bump_version.yml
vendored
6
.github/workflows/bump_version.yml
vendored
@@ -15,6 +15,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
- name: check diff
|
||||
id: check_diff
|
||||
run: |
|
||||
@@ -49,7 +51,11 @@ jobs:
|
||||
- name: bump version in common/version/version.go
|
||||
if: steps.check_diff.outputs.result == 'bump'
|
||||
run: node .github/scripts/bump_version_dot_go.mjs
|
||||
|
||||
# Commits made by this Action do not trigger new Workflow runs
|
||||
- uses: stefanzweifel/git-auto-commit-action@3ea6ae190baf489ba007f7c92608f33ce20ef04a
|
||||
if: steps.check_diff.outputs.result == 'bump'
|
||||
with:
|
||||
skip_fetch: true # already did fetch in check diff
|
||||
file_pattern: "common/version/version.go"
|
||||
commit_message: "chore: auto version bump [bot]"
|
||||
|
||||
2
.github/workflows/common.yml
vendored
2
.github/workflows/common.yml
vendored
@@ -88,8 +88,6 @@ jobs:
|
||||
version: '0.8.16'
|
||||
- name: Install Geth Tools
|
||||
uses: gacts/install-geth-tools@v1
|
||||
with:
|
||||
version: 1.10.19
|
||||
- name: Build prerequisites
|
||||
run: |
|
||||
make dev_docker
|
||||
|
||||
2
.github/workflows/coordinator.yml
vendored
2
.github/workflows/coordinator.yml
vendored
@@ -104,8 +104,6 @@ jobs:
|
||||
version: '0.8.16'
|
||||
- name: Install Geth Tools
|
||||
uses: gacts/install-geth-tools@v1
|
||||
with:
|
||||
version: 1.10.19
|
||||
- name: Build prerequisites
|
||||
run: |
|
||||
make dev_docker
|
||||
|
||||
2
.github/workflows/database.yml
vendored
2
.github/workflows/database.yml
vendored
@@ -81,8 +81,6 @@ jobs:
|
||||
version: '0.8.16'
|
||||
- name: Install Geth Tools
|
||||
uses: gacts/install-geth-tools@v1
|
||||
with:
|
||||
version: 1.10.19
|
||||
- name: Build prerequisites
|
||||
run: |
|
||||
make dev_docker
|
||||
|
||||
2
.github/workflows/integration.yaml
vendored
2
.github/workflows/integration.yaml
vendored
@@ -33,8 +33,6 @@ jobs:
|
||||
version: '0.8.16'
|
||||
- name: Install Geth Tools
|
||||
uses: gacts/install-geth-tools@v1
|
||||
with:
|
||||
version: 1.10.19
|
||||
- name: Build prerequisites
|
||||
run: |
|
||||
make dev_docker
|
||||
|
||||
@@ -107,7 +107,7 @@ func action(ctx *cli.Context) error {
|
||||
|
||||
go utils.Loop(subCtx, 2*time.Second, chunkProposer.TryProposeChunk)
|
||||
|
||||
go utils.Loop(subCtx, 2*time.Second, batchProposer.TryProposeBatch)
|
||||
go utils.Loop(subCtx, 10*time.Second, batchProposer.TryProposeBatch)
|
||||
|
||||
go utils.Loop(subCtx, 2*time.Second, l2relayer.ProcessPendingBatches)
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@ func (r *Layer1Relayer) handleConfirmLoop(ctx context.Context) {
|
||||
log.Info("transaction confirmed in layer2", "confirmation", cfm)
|
||||
}
|
||||
case cfm := <-r.gasOracleSender.ConfirmChan():
|
||||
r.metrics.bridgeL1MsgsRelayedConfirmedTotal.Inc()
|
||||
r.metrics.bridgeL1GasOraclerConfirmedTotal.Inc()
|
||||
if !cfm.IsSuccessful {
|
||||
// @discuss: maybe make it pending again?
|
||||
err := r.l1BlockOrm.UpdateL1GasOracleStatusAndOracleTxHash(r.ctx, cfm.ID, types.GasOracleFailed, cfm.TxHash.String())
|
||||
|
||||
@@ -430,10 +430,6 @@ func (r *Layer2Relayer) ProcessCommittedBatches() {
|
||||
case types.ProvingTaskUnassigned, types.ProvingTaskAssigned:
|
||||
// The proof for this block is not ready yet.
|
||||
return
|
||||
case types.ProvingTaskProved:
|
||||
// It's an intermediate state. The prover manager received the proof but has not verified
|
||||
// the proof yet. We don't roll up the proof until it's verified.
|
||||
return
|
||||
case types.ProvingTaskVerified:
|
||||
log.Info("Start to roll up zk proof", "hash", hash)
|
||||
r.metrics.bridgeL2RelayerProcessCommittedBatchesFinalizedTotal.Inc()
|
||||
|
||||
@@ -311,7 +311,7 @@ func (o *Batch) UpdateProvingStatus(ctx context.Context, hash string, status typ
|
||||
updateFields["prover_assigned_at"] = time.Now()
|
||||
case types.ProvingTaskUnassigned:
|
||||
updateFields["prover_assigned_at"] = nil
|
||||
case types.ProvingTaskProved, types.ProvingTaskVerified:
|
||||
case types.ProvingTaskVerified:
|
||||
updateFields["proved_at"] = time.Now()
|
||||
}
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ func (o *Chunk) UpdateProvingStatus(ctx context.Context, hash string, status typ
|
||||
updateFields["prover_assigned_at"] = time.Now()
|
||||
case types.ProvingTaskUnassigned:
|
||||
updateFields["prover_assigned_at"] = nil
|
||||
case types.ProvingTaskProved, types.ProvingTaskVerified:
|
||||
case types.ProvingTaskVerified:
|
||||
updateFields["proved_at"] = time.Now()
|
||||
}
|
||||
|
||||
|
||||
33
common/libzkp/impl/Cargo.lock
generated
33
common/libzkp/impl/Cargo.lock
generated
@@ -32,7 +32,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "aggregator"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.6.5#0cafc84c6dce2c0f385b36445fb3c61ca30d28ef"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.7.3#594b237563a275b4984631882400adb5372164f7"
|
||||
dependencies = [
|
||||
"ark-std",
|
||||
"env_logger 0.10.0",
|
||||
@@ -433,7 +433,7 @@ checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
|
||||
[[package]]
|
||||
name = "bus-mapping"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.6.5#0cafc84c6dce2c0f385b36445fb3c61ca30d28ef"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.7.3#594b237563a275b4984631882400adb5372164f7"
|
||||
dependencies = [
|
||||
"eth-types",
|
||||
"ethers-core",
|
||||
@@ -1049,7 +1049,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "eth-types"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.6.5#0cafc84c6dce2c0f385b36445fb3c61ca30d28ef"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.7.3#594b237563a275b4984631882400adb5372164f7"
|
||||
dependencies = [
|
||||
"ethers-core",
|
||||
"ethers-signers",
|
||||
@@ -1226,7 +1226,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "external-tracer"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.6.5#0cafc84c6dce2c0f385b36445fb3c61ca30d28ef"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.7.3#594b237563a275b4984631882400adb5372164f7"
|
||||
dependencies = [
|
||||
"eth-types",
|
||||
"geth-utils",
|
||||
@@ -1439,7 +1439,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gadgets"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.6.5#0cafc84c6dce2c0f385b36445fb3c61ca30d28ef"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.7.3#594b237563a275b4984631882400adb5372164f7"
|
||||
dependencies = [
|
||||
"digest 0.7.6",
|
||||
"eth-types",
|
||||
@@ -1479,7 +1479,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "geth-utils"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.6.5#0cafc84c6dce2c0f385b36445fb3c61ca30d28ef"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.7.3#594b237563a275b4984631882400adb5372164f7"
|
||||
dependencies = [
|
||||
"env_logger 0.9.3",
|
||||
"gobuild 0.1.0-alpha.2 (git+https://github.com/scroll-tech/gobuild.git)",
|
||||
@@ -2077,7 +2077,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "keccak256"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.6.5#0cafc84c6dce2c0f385b36445fb3c61ca30d28ef"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.7.3#594b237563a275b4984631882400adb5372164f7"
|
||||
dependencies = [
|
||||
"env_logger 0.9.3",
|
||||
"eth-types",
|
||||
@@ -2264,7 +2264,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "mock"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.6.5#0cafc84c6dce2c0f385b36445fb3c61ca30d28ef"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.7.3#594b237563a275b4984631882400adb5372164f7"
|
||||
dependencies = [
|
||||
"eth-types",
|
||||
"ethers-core",
|
||||
@@ -2279,7 +2279,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "mpt-zktrie"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.6.5#0cafc84c6dce2c0f385b36445fb3c61ca30d28ef"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.7.3#594b237563a275b4984631882400adb5372164f7"
|
||||
dependencies = [
|
||||
"bus-mapping",
|
||||
"eth-types",
|
||||
@@ -2754,8 +2754,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "prover"
|
||||
version = "0.6.4"
|
||||
source = "git+https://github.com/scroll-tech/scroll-prover?tag=v0.6.5#ccb3cd457080dcfdf8ae59416eb47ae9b6b6ddd6"
|
||||
version = "0.7.3"
|
||||
source = "git+https://github.com/scroll-tech/scroll-prover?tag=v0.7.3#1b1fb34f8662dbb11af12c8dfd72f8da5ae80422"
|
||||
dependencies = [
|
||||
"aggregator",
|
||||
"anyhow",
|
||||
@@ -3624,7 +3624,7 @@ checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
|
||||
[[package]]
|
||||
name = "snark-verifier"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech//snark-verifier?tag=v0.1.1#11a09d4a37c31c659b29e2dac0ceb544a776ad7b"
|
||||
source = "git+https://github.com/scroll-tech/snark-verifier?tag=v0.1.2#4466059ce9a6dfaf26455e4ffb61d72af775cf52"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"ethereum-types 0.14.1",
|
||||
@@ -3648,7 +3648,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "snark-verifier-sdk"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/scroll-tech//snark-verifier?tag=v0.1.1#11a09d4a37c31c659b29e2dac0ceb544a776ad7b"
|
||||
source = "git+https://github.com/scroll-tech/snark-verifier?tag=v0.1.2#4466059ce9a6dfaf26455e4ffb61d72af775cf52"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"env_logger 0.10.0",
|
||||
@@ -4039,8 +4039,8 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||
|
||||
[[package]]
|
||||
name = "types"
|
||||
version = "0.6.4"
|
||||
source = "git+https://github.com/scroll-tech/scroll-prover?tag=v0.6.5#ccb3cd457080dcfdf8ae59416eb47ae9b6b6ddd6"
|
||||
version = "0.7.3"
|
||||
source = "git+https://github.com/scroll-tech/scroll-prover?tag=v0.7.3#1b1fb34f8662dbb11af12c8dfd72f8da5ae80422"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"blake2",
|
||||
@@ -4491,7 +4491,7 @@ checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9"
|
||||
[[package]]
|
||||
name = "zkevm-circuits"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.6.5#0cafc84c6dce2c0f385b36445fb3c61ca30d28ef"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.7.3#594b237563a275b4984631882400adb5372164f7"
|
||||
dependencies = [
|
||||
"array-init",
|
||||
"bus-mapping",
|
||||
@@ -4536,6 +4536,7 @@ dependencies = [
|
||||
name = "zkp"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"env_logger 0.9.3",
|
||||
"halo2_proofs",
|
||||
"libc",
|
||||
|
||||
@@ -19,23 +19,19 @@ maingate = { git = "https://github.com/scroll-tech/halo2wrong", branch = "halo2-
|
||||
[patch."https://github.com/privacy-scaling-explorations/halo2curves.git"]
|
||||
halo2curves = { git = "https://github.com/scroll-tech/halo2curves.git", branch = "0.3.1-derive-serde" }
|
||||
|
||||
[patch."https://github.com/scroll-tech/snark-verifier"]
|
||||
snark-verifier = { git = "https://github.com/scroll-tech//snark-verifier", tag = "v0.1.1" }
|
||||
snark-verifier-sdk = { git = "https://github.com/scroll-tech//snark-verifier", tag = "v0.1.1" }
|
||||
|
||||
[dependencies]
|
||||
prover = { git = "https://github.com/scroll-tech/scroll-prover", tag = "v0.6.5" }
|
||||
types = { git = "https://github.com/scroll-tech/scroll-prover", tag = "v0.6.5" }
|
||||
prover = { git = "https://github.com/scroll-tech/scroll-prover", tag = "v0.7.3" }
|
||||
types = { git = "https://github.com/scroll-tech/scroll-prover", tag = "v0.7.3" }
|
||||
halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "develop" }
|
||||
|
||||
log = "0.4"
|
||||
base64 = "0.13.0"
|
||||
env_logger = "0.9.0"
|
||||
libc = "0.2"
|
||||
log = "0.4"
|
||||
once_cell = "1.8.0"
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0.66"
|
||||
libc = "0.2"
|
||||
once_cell = "1.8.0"
|
||||
|
||||
|
||||
[profile.test]
|
||||
opt-level = 3
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::utils::{c_char_to_str, c_char_to_vec, vec_to_c_char, OUTPUT_DIR};
|
||||
use crate::utils::{c_char_to_str, c_char_to_vec, string_to_c_char, vec_to_c_char, OUTPUT_DIR};
|
||||
use libc::c_char;
|
||||
use prover::{
|
||||
aggregator::{Prover, Verifier},
|
||||
utils::{chunk_trace_to_witness_block, init_env_and_log},
|
||||
BatchProof, ChunkHash, ChunkProof,
|
||||
};
|
||||
use std::{cell::OnceCell, panic, ptr::null};
|
||||
use std::{cell::OnceCell, env, panic, ptr::null};
|
||||
use types::eth::BlockTrace;
|
||||
|
||||
static mut PROVER: OnceCell<Prover> = OnceCell::new();
|
||||
@@ -13,11 +13,15 @@ static mut VERIFIER: OnceCell<Verifier> = OnceCell::new();
|
||||
|
||||
/// # Safety
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn init_batch_prover(params_dir: *const c_char) {
|
||||
pub unsafe extern "C" fn init_batch_prover(params_dir: *const c_char, assets_dir: *const c_char) {
|
||||
init_env_and_log("ffi_batch_prove");
|
||||
|
||||
let params_dir = c_char_to_str(params_dir);
|
||||
let prover = Prover::from_params_dir(params_dir);
|
||||
let assets_dir = c_char_to_str(assets_dir);
|
||||
|
||||
// TODO: add a settings in scroll-prover.
|
||||
env::set_var("SCROLL_PROVER_ASSETS_DIR", assets_dir);
|
||||
let prover = Prover::from_dirs(params_dir, assets_dir);
|
||||
|
||||
PROVER.set(prover).unwrap();
|
||||
}
|
||||
@@ -30,11 +34,35 @@ pub unsafe extern "C" fn init_batch_verifier(params_dir: *const c_char, assets_d
|
||||
let params_dir = c_char_to_str(params_dir);
|
||||
let assets_dir = c_char_to_str(assets_dir);
|
||||
|
||||
// TODO: add a settings in scroll-prover.
|
||||
env::set_var("SCROLL_PROVER_ASSETS_DIR", assets_dir);
|
||||
let verifier = Verifier::from_dirs(params_dir, assets_dir);
|
||||
|
||||
VERIFIER.set(verifier).unwrap();
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn get_batch_vk() -> *const c_char {
|
||||
let vk_result = panic::catch_unwind(|| PROVER.get_mut().unwrap().get_vk());
|
||||
|
||||
vk_result
|
||||
.ok()
|
||||
.flatten()
|
||||
.map_or(null(), |vk| string_to_c_char(base64::encode(vk)))
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn check_chunk_proofs(chunk_proofs: *const c_char) -> c_char {
|
||||
let chunk_proofs = c_char_to_vec(chunk_proofs);
|
||||
let chunk_proofs = serde_json::from_slice::<Vec<ChunkProof>>(&chunk_proofs).unwrap();
|
||||
assert!(!chunk_proofs.is_empty());
|
||||
|
||||
let valid = panic::catch_unwind(|| PROVER.get().unwrap().check_chunk_proofs(&chunk_proofs));
|
||||
valid.unwrap_or(false) as c_char
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn gen_batch_proof(
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::utils::{c_char_to_str, c_char_to_vec, vec_to_c_char, OUTPUT_DIR};
|
||||
use crate::utils::{c_char_to_str, c_char_to_vec, string_to_c_char, vec_to_c_char, OUTPUT_DIR};
|
||||
use libc::c_char;
|
||||
use prover::{
|
||||
utils::init_env_and_log,
|
||||
zkevm::{Prover, Verifier},
|
||||
ChunkProof,
|
||||
};
|
||||
use std::{cell::OnceCell, panic, ptr::null};
|
||||
use std::{cell::OnceCell, env, panic, ptr::null};
|
||||
use types::eth::BlockTrace;
|
||||
|
||||
static mut PROVER: OnceCell<Prover> = OnceCell::new();
|
||||
@@ -13,10 +13,14 @@ static mut VERIFIER: OnceCell<Verifier> = OnceCell::new();
|
||||
|
||||
/// # Safety
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn init_chunk_prover(params_dir: *const c_char) {
|
||||
pub unsafe extern "C" fn init_chunk_prover(params_dir: *const c_char, assets_dir: *const c_char) {
|
||||
init_env_and_log("ffi_chunk_prove");
|
||||
|
||||
let params_dir = c_char_to_str(params_dir);
|
||||
let assets_dir = c_char_to_str(assets_dir);
|
||||
|
||||
// TODO: add a settings in scroll-prover.
|
||||
env::set_var("SCROLL_PROVER_ASSETS_DIR", assets_dir);
|
||||
let prover = Prover::from_params_dir(params_dir);
|
||||
|
||||
PROVER.set(prover).unwrap();
|
||||
@@ -30,11 +34,24 @@ pub unsafe extern "C" fn init_chunk_verifier(params_dir: *const c_char, assets_d
|
||||
let params_dir = c_char_to_str(params_dir);
|
||||
let assets_dir = c_char_to_str(assets_dir);
|
||||
|
||||
// TODO: add a settings in scroll-prover.
|
||||
env::set_var("SCROLL_PROVER_ASSETS_DIR", assets_dir);
|
||||
let verifier = Verifier::from_dirs(params_dir, assets_dir);
|
||||
|
||||
VERIFIER.set(verifier).unwrap();
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn get_chunk_vk() -> *const c_char {
|
||||
let vk_result = panic::catch_unwind(|| PROVER.get_mut().unwrap().get_vk());
|
||||
|
||||
vk_result
|
||||
.ok()
|
||||
.flatten()
|
||||
.map_or(null(), |vk| string_to_c_char(base64::encode(vk)))
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn gen_chunk_proof(block_traces: *const c_char) -> *const c_char {
|
||||
|
||||
@@ -19,6 +19,10 @@ pub(crate) fn c_char_to_vec(c: *const c_char) -> Vec<u8> {
|
||||
cstr.to_bytes().to_vec()
|
||||
}
|
||||
|
||||
pub(crate) fn string_to_c_char(string: String) -> *const c_char {
|
||||
CString::new(string).unwrap().into_raw()
|
||||
}
|
||||
|
||||
pub(crate) fn vec_to_c_char(bytes: Vec<u8>) -> *const c_char {
|
||||
CString::new(bytes).unwrap().into_raw()
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
void init_batch_prover(char* params_dir);
|
||||
void init_batch_prover(char* params_dir, char* assets_dir);
|
||||
void init_batch_verifier(char* params_dir, char* assets_dir);
|
||||
char* get_batch_vk();
|
||||
char check_chunk_proofs(char* chunk_proofs);
|
||||
char* gen_batch_proof(char* chunk_hashes, char* chunk_proofs);
|
||||
char verify_batch_proof(char* proof);
|
||||
|
||||
void init_chunk_prover(char* params_dir);
|
||||
void init_chunk_prover(char* params_dir, char* assets_dir);
|
||||
void init_chunk_verifier(char* params_dir, char* assets_dir);
|
||||
char* get_chunk_vk();
|
||||
char* gen_chunk_proof(char* block_traces);
|
||||
char verify_chunk_proof(char* proof);
|
||||
|
||||
|
||||
@@ -3,11 +3,13 @@ package types
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"github.com/scroll-tech/go-ethereum/common/hexutil"
|
||||
"github.com/scroll-tech/go-ethereum/core/types"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
)
|
||||
|
||||
// CalldataNonZeroByteGas is the gas consumption per non zero byte in calldata.
|
||||
@@ -22,9 +24,10 @@ func GetKeccak256Gas(size uint64) uint64 {
|
||||
type WrappedBlock struct {
|
||||
Header *types.Header `json:"header"`
|
||||
// Transactions is only used for recover types.Transactions, the from of types.TransactionData field is missing.
|
||||
Transactions []*types.TransactionData `json:"transactions"`
|
||||
WithdrawRoot common.Hash `json:"withdraw_trie_root,omitempty"`
|
||||
RowConsumption *types.RowConsumption `json:"row_consumption"`
|
||||
Transactions []*types.TransactionData `json:"transactions"`
|
||||
WithdrawRoot common.Hash `json:"withdraw_trie_root,omitempty"`
|
||||
RowConsumption *types.RowConsumption `json:"row_consumption"`
|
||||
txPayloadLengthCache map[string]uint64
|
||||
}
|
||||
|
||||
// NumL1Messages returns the number of L1 messages in this block.
|
||||
@@ -95,7 +98,8 @@ func (w *WrappedBlock) EstimateL1CommitCalldataSize() uint64 {
|
||||
if txData.Type == types.L1MessageTxType {
|
||||
continue
|
||||
}
|
||||
size += uint64(len(txData.Data))
|
||||
size += 64 // 60 bytes BlockContext + 4 bytes payload length
|
||||
size += w.getTxPayloadLength(txData)
|
||||
}
|
||||
return size
|
||||
}
|
||||
@@ -110,22 +114,9 @@ func (w *WrappedBlock) EstimateL1CommitGas() uint64 {
|
||||
continue
|
||||
}
|
||||
|
||||
data, _ := hexutil.Decode(txData.Data)
|
||||
tx := types.NewTx(&types.LegacyTx{
|
||||
Nonce: txData.Nonce,
|
||||
To: txData.To,
|
||||
Value: txData.Value.ToInt(),
|
||||
Gas: txData.Gas,
|
||||
GasPrice: txData.GasPrice.ToInt(),
|
||||
Data: data,
|
||||
V: txData.V.ToInt(),
|
||||
R: txData.R.ToInt(),
|
||||
S: txData.S.ToInt(),
|
||||
})
|
||||
rlpTxData, _ := tx.MarshalBinary()
|
||||
txPayloadLength := uint64(len(rlpTxData))
|
||||
txPayloadLength := w.getTxPayloadLength(txData)
|
||||
total += CalldataNonZeroByteGas * txPayloadLength // an over-estimate: treat each byte as non-zero
|
||||
total += CalldataNonZeroByteGas * 4 // size of a uint32 field
|
||||
total += CalldataNonZeroByteGas * 64 // 60 bytes BlockContext + 4 bytes payload length
|
||||
total += GetKeccak256Gas(txPayloadLength) // l2 tx hash
|
||||
}
|
||||
|
||||
@@ -149,3 +140,48 @@ func (w *WrappedBlock) L2TxsNum() uint64 {
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
func (w *WrappedBlock) getTxPayloadLength(txData *types.TransactionData) uint64 {
|
||||
if w.txPayloadLengthCache == nil {
|
||||
w.txPayloadLengthCache = make(map[string]uint64)
|
||||
}
|
||||
|
||||
if length, exists := w.txPayloadLengthCache[txData.TxHash]; exists {
|
||||
return length
|
||||
}
|
||||
|
||||
rlpTxData, err := convertTxDataToRLPEncoding(txData)
|
||||
if err != nil {
|
||||
log.Crit("convertTxDataToRLPEncoding failed, which should not happen", "hash", txData.TxHash, "err", err)
|
||||
return 0
|
||||
}
|
||||
txPayloadLength := uint64(len(rlpTxData))
|
||||
w.txPayloadLengthCache[txData.TxHash] = txPayloadLength
|
||||
return txPayloadLength
|
||||
}
|
||||
|
||||
func convertTxDataToRLPEncoding(txData *types.TransactionData) ([]byte, error) {
|
||||
data, err := hexutil.Decode(txData.Data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode txData.Data: %s, err: %w", txData.Data, err)
|
||||
}
|
||||
|
||||
tx := types.NewTx(&types.LegacyTx{
|
||||
Nonce: txData.Nonce,
|
||||
To: txData.To,
|
||||
Value: txData.Value.ToInt(),
|
||||
Gas: txData.Gas,
|
||||
GasPrice: txData.GasPrice.ToInt(),
|
||||
Data: data,
|
||||
V: txData.V.ToInt(),
|
||||
R: txData.R.ToInt(),
|
||||
S: txData.S.ToInt(),
|
||||
})
|
||||
|
||||
rlpTxData, err := tx.MarshalBinary()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal binary of the tx: %+v, err: %w", tx, err)
|
||||
}
|
||||
|
||||
return rlpTxData, nil
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"github.com/scroll-tech/go-ethereum/common/hexutil"
|
||||
"github.com/scroll-tech/go-ethereum/core/types"
|
||||
"github.com/scroll-tech/go-ethereum/crypto"
|
||||
)
|
||||
@@ -65,23 +64,7 @@ func (c *Chunk) Encode(totalL1MessagePoppedBefore uint64) ([]byte, error) {
|
||||
if txData.Type == types.L1MessageTxType {
|
||||
continue
|
||||
}
|
||||
data, err := hexutil.Decode(txData.Data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// right now we only support legacy tx
|
||||
tx := types.NewTx(&types.LegacyTx{
|
||||
Nonce: txData.Nonce,
|
||||
To: txData.To,
|
||||
Value: txData.Value.ToInt(),
|
||||
Gas: txData.Gas,
|
||||
GasPrice: txData.GasPrice.ToInt(),
|
||||
Data: data,
|
||||
V: txData.V.ToInt(),
|
||||
R: txData.R.ToInt(),
|
||||
S: txData.S.ToInt(),
|
||||
})
|
||||
rlpTxData, err := tx.MarshalBinary()
|
||||
rlpTxData, err := convertTxDataToRLPEncoding(txData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -38,11 +38,15 @@ func TestChunkEncode(t *testing.T) {
|
||||
wrappedBlock := &WrappedBlock{}
|
||||
assert.NoError(t, json.Unmarshal(templateBlockTrace, wrappedBlock))
|
||||
assert.Equal(t, uint64(0), wrappedBlock.NumL1Messages(0))
|
||||
assert.Equal(t, uint64(358), wrappedBlock.EstimateL1CommitCalldataSize())
|
||||
assert.Equal(t, uint64(2), wrappedBlock.L2TxsNum())
|
||||
chunk = &Chunk{
|
||||
Blocks: []*WrappedBlock{
|
||||
wrappedBlock,
|
||||
},
|
||||
}
|
||||
assert.Equal(t, uint64(0), chunk.NumL1Messages(0))
|
||||
assert.Equal(t, uint64(6966), chunk.EstimateL1CommitGas())
|
||||
bytes, err = chunk.Encode(0)
|
||||
hexString := hex.EncodeToString(bytes)
|
||||
assert.NoError(t, err)
|
||||
@@ -56,11 +60,15 @@ func TestChunkEncode(t *testing.T) {
|
||||
wrappedBlock2 := &WrappedBlock{}
|
||||
assert.NoError(t, json.Unmarshal(templateBlockTrace2, wrappedBlock2))
|
||||
assert.Equal(t, uint64(11), wrappedBlock2.NumL1Messages(0)) // 0..=9 skipped, 10 included
|
||||
assert.Equal(t, uint64(96), wrappedBlock2.EstimateL1CommitCalldataSize())
|
||||
assert.Equal(t, uint64(1), wrappedBlock2.L2TxsNum())
|
||||
chunk = &Chunk{
|
||||
Blocks: []*WrappedBlock{
|
||||
wrappedBlock2,
|
||||
},
|
||||
}
|
||||
assert.Equal(t, uint64(11), chunk.NumL1Messages(0))
|
||||
assert.Equal(t, uint64(5002), chunk.EstimateL1CommitGas())
|
||||
bytes, err = chunk.Encode(0)
|
||||
hexString = hex.EncodeToString(bytes)
|
||||
assert.NoError(t, err)
|
||||
@@ -75,6 +83,8 @@ func TestChunkEncode(t *testing.T) {
|
||||
wrappedBlock2,
|
||||
},
|
||||
}
|
||||
assert.Equal(t, uint64(11), chunk.NumL1Messages(0))
|
||||
assert.Equal(t, uint64(9958), chunk.EstimateL1CommitGas())
|
||||
bytes, err = chunk.Encode(0)
|
||||
hexString = hex.EncodeToString(bytes)
|
||||
assert.NoError(t, err)
|
||||
@@ -136,3 +146,81 @@ func TestChunkHash(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "0x2eb7dd63bf8fc29a0f8c10d16c2ae6f9da446907c79d50f5c164d30dc8526b60", hash.Hex())
|
||||
}
|
||||
|
||||
func TestErrorPaths(t *testing.T) {
|
||||
// test 1: Header.Number is not a uint64
|
||||
templateBlockTrace, err := os.ReadFile("../testdata/blockTrace_02.json")
|
||||
assert.NoError(t, err)
|
||||
|
||||
wrappedBlock := &WrappedBlock{}
|
||||
|
||||
assert.NoError(t, json.Unmarshal(templateBlockTrace, wrappedBlock))
|
||||
wrappedBlock.Header.Number = wrappedBlock.Header.Number.Lsh(wrappedBlock.Header.Number, 64)
|
||||
bytes, err := wrappedBlock.Encode(0)
|
||||
assert.Nil(t, bytes)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "block number is not uint64")
|
||||
|
||||
assert.NoError(t, json.Unmarshal(templateBlockTrace, wrappedBlock))
|
||||
for i := 0; i < 65537; i++ {
|
||||
wrappedBlock.Transactions = append(wrappedBlock.Transactions, wrappedBlock.Transactions[0])
|
||||
}
|
||||
|
||||
bytes, err = wrappedBlock.Encode(0)
|
||||
assert.Nil(t, bytes)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "number of transactions exceeds max uint16")
|
||||
|
||||
chunk := &Chunk{
|
||||
Blocks: []*WrappedBlock{
|
||||
wrappedBlock,
|
||||
},
|
||||
}
|
||||
|
||||
bytes, err = chunk.Encode(0)
|
||||
assert.Nil(t, bytes)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "number of transactions exceeds max uint16")
|
||||
|
||||
wrappedBlock.Transactions = wrappedBlock.Transactions[:1]
|
||||
wrappedBlock.Transactions[0].Data = "not-a-hex"
|
||||
bytes, err = chunk.Encode(0)
|
||||
assert.Nil(t, bytes)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "hex string without 0x prefix")
|
||||
|
||||
assert.NoError(t, json.Unmarshal(templateBlockTrace, wrappedBlock))
|
||||
wrappedBlock.Transactions[0].TxHash = "not-a-hex"
|
||||
_, err = chunk.Hash(0)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "invalid byte")
|
||||
|
||||
templateBlockTrace2, err := os.ReadFile("../testdata/blockTrace_04.json")
|
||||
assert.NoError(t, err)
|
||||
|
||||
wrappedBlock2 := &WrappedBlock{}
|
||||
assert.NoError(t, json.Unmarshal(templateBlockTrace2, wrappedBlock2))
|
||||
for i := 0; i < 65535; i++ {
|
||||
tx := &wrappedBlock2.Transactions[i]
|
||||
txCopy := *tx
|
||||
txCopy.Nonce = uint64(i + 1)
|
||||
wrappedBlock2.Transactions = append(wrappedBlock2.Transactions, txCopy)
|
||||
}
|
||||
|
||||
bytes, err = wrappedBlock2.Encode(0)
|
||||
assert.Nil(t, bytes)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "number of L1 messages exceeds max uint16")
|
||||
|
||||
chunk = &Chunk{
|
||||
Blocks: []*WrappedBlock{
|
||||
wrappedBlock2,
|
||||
},
|
||||
}
|
||||
|
||||
bytes, err = chunk.Encode(0)
|
||||
assert.Nil(t, bytes)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "number of L1 messages exceeds max uint16")
|
||||
|
||||
}
|
||||
|
||||
@@ -126,8 +126,8 @@ const (
|
||||
ProvingTaskUnassigned
|
||||
// ProvingTaskAssigned : proving_task is assigned to be proved
|
||||
ProvingTaskAssigned
|
||||
// ProvingTaskProved DEPRECATED: proof has been returned by prover
|
||||
ProvingTaskProved
|
||||
// ProvingTaskProvedDEPRECATED DEPRECATED: proof has been returned by prover
|
||||
ProvingTaskProvedDEPRECATED
|
||||
// ProvingTaskVerified : proof is valid
|
||||
ProvingTaskVerified
|
||||
// ProvingTaskFailed : fail to generate proof
|
||||
@@ -140,7 +140,7 @@ func (ps ProvingStatus) String() string {
|
||||
return "unassigned"
|
||||
case ProvingTaskAssigned:
|
||||
return "assigned"
|
||||
case ProvingTaskProved:
|
||||
case ProvingTaskProvedDEPRECATED:
|
||||
return "proved"
|
||||
case ProvingTaskVerified:
|
||||
return "verified"
|
||||
|
||||
@@ -58,8 +58,8 @@ func TestProvingStatus(t *testing.T) {
|
||||
"assigned",
|
||||
},
|
||||
{
|
||||
"ProvingTaskProved",
|
||||
ProvingTaskProved,
|
||||
"ProvingTaskProvedDEPRECATED",
|
||||
ProvingTaskProvedDEPRECATED,
|
||||
"proved",
|
||||
},
|
||||
{
|
||||
|
||||
@@ -3,10 +3,11 @@ package version
|
||||
import (
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var tag = "v4.1.83"
|
||||
var tag = "v4.1.104"
|
||||
|
||||
var commit = func() string {
|
||||
if info, ok := debug.ReadBuildInfo(); ok {
|
||||
@@ -44,5 +45,41 @@ func CheckScrollProverVersion(proverVersion string) bool {
|
||||
return false
|
||||
}
|
||||
// compare the `scroll_prover` version
|
||||
return remote[2] == local[2] || remote[2] == "8c439b1"
|
||||
return remote[2] == local[2]
|
||||
}
|
||||
|
||||
// CheckScrollProverVersionTag check the "scroll-prover" version's tag, if it's too old, return false
|
||||
func CheckScrollProverVersionTag(proverVersion string) bool {
|
||||
// note the the version is in fact in the format of "tag-commit-scroll_prover-halo2",
|
||||
// so split-by-'-' length should be 4
|
||||
remote := strings.Split(proverVersion, "-")
|
||||
if len(remote) != 4 {
|
||||
return false
|
||||
}
|
||||
remoteTagNums := strings.Split(strings.TrimPrefix(remote[0], "v"), ".")
|
||||
if len(remoteTagNums) != 3 {
|
||||
return false
|
||||
}
|
||||
remoteTagMajor, err := strconv.Atoi(remoteTagNums[0])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
remoteTagMinor, err := strconv.Atoi(remoteTagNums[1])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
remoteTagPatch, err := strconv.Atoi(remoteTagNums[2])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if remoteTagMajor != 4 {
|
||||
return false
|
||||
}
|
||||
if remoteTagMinor != 1 {
|
||||
return false
|
||||
}
|
||||
if remoteTagPatch < 98 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ contract L2USDCGateway is L2ERC20Gateway {
|
||||
require(_token == l2USDC, "only USDC is allowed");
|
||||
require(!withdrawPaused, "withdraw paused");
|
||||
|
||||
// 1. Extract real sender if this call is from L1GatewayRouter.
|
||||
// 1. Extract real sender if this call is from L2GatewayRouter.
|
||||
address _from = msg.sender;
|
||||
if (router == msg.sender) {
|
||||
(_from, _data) = abi.decode(_data, (address, bytes));
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"gorm.io/gorm"
|
||||
|
||||
"scroll-tech/coordinator/internal/config"
|
||||
"scroll-tech/coordinator/internal/logic/verifier"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -25,9 +26,14 @@ var (
|
||||
// InitController inits Controller with database
|
||||
func InitController(cfg *config.Config, db *gorm.DB, reg prometheus.Registerer) {
|
||||
initControllerOnce.Do(func() {
|
||||
vf, err := verifier.NewVerifier(cfg.ProverManager.Verifier)
|
||||
if err != nil {
|
||||
panic("proof receiver new verifier failure")
|
||||
}
|
||||
|
||||
Auth = NewAuthController(db)
|
||||
HealthCheck = NewHealthCheckController()
|
||||
GetTask = NewGetTaskController(cfg, db, reg)
|
||||
SubmitProof = NewSubmitProofController(cfg, db, reg)
|
||||
GetTask = NewGetTaskController(cfg, db, vf, reg)
|
||||
SubmitProof = NewSubmitProofController(cfg, db, vf, reg)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
"scroll-tech/coordinator/internal/config"
|
||||
"scroll-tech/coordinator/internal/logic/provertask"
|
||||
"scroll-tech/coordinator/internal/logic/verifier"
|
||||
coordinatorType "scroll-tech/coordinator/internal/types"
|
||||
)
|
||||
|
||||
@@ -22,9 +23,9 @@ type GetTaskController struct {
|
||||
}
|
||||
|
||||
// NewGetTaskController create a get prover task controller
|
||||
func NewGetTaskController(cfg *config.Config, db *gorm.DB, reg prometheus.Registerer) *GetTaskController {
|
||||
chunkProverTask := provertask.NewChunkProverTask(cfg, db, reg)
|
||||
batchProverTask := provertask.NewBatchProverTask(cfg, db, reg)
|
||||
func NewGetTaskController(cfg *config.Config, db *gorm.DB, vf *verifier.Verifier, reg prometheus.Registerer) *GetTaskController {
|
||||
chunkProverTask := provertask.NewChunkProverTask(cfg, db, vf.ChunkVK, reg)
|
||||
batchProverTask := provertask.NewBatchProverTask(cfg, db, vf.BatchVK, reg)
|
||||
|
||||
ptc := &GetTaskController{
|
||||
proverTasks: make(map[message.ProofType]provertask.ProverTask),
|
||||
@@ -40,7 +41,7 @@ func NewGetTaskController(cfg *config.Config, db *gorm.DB, reg prometheus.Regist
|
||||
func (ptc *GetTaskController) GetTasks(ctx *gin.Context) {
|
||||
var getTaskParameter coordinatorType.GetTaskParameter
|
||||
if err := ctx.ShouldBind(&getTaskParameter); err != nil {
|
||||
nerr := fmt.Errorf("prover tasks parameter invalid, err:%w", err)
|
||||
nerr := fmt.Errorf("prover task parameter invalid, err:%w", err)
|
||||
coordinatorType.RenderJSON(ctx, types.ErrCoordinatorParameterInvalidNo, nerr, nil)
|
||||
return
|
||||
}
|
||||
@@ -48,7 +49,7 @@ func (ptc *GetTaskController) GetTasks(ctx *gin.Context) {
|
||||
proofType := ptc.proofType(&getTaskParameter)
|
||||
proverTask, isExist := ptc.proverTasks[proofType]
|
||||
if !isExist {
|
||||
nerr := fmt.Errorf("parameter wrong proof type")
|
||||
nerr := fmt.Errorf("parameter wrong proof type:%v", proofType)
|
||||
coordinatorType.RenderJSON(ctx, types.ErrCoordinatorParameterInvalidNo, nerr, nil)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@ import (
|
||||
|
||||
"scroll-tech/coordinator/internal/config"
|
||||
"scroll-tech/coordinator/internal/logic/submitproof"
|
||||
coodinatorType "scroll-tech/coordinator/internal/types"
|
||||
"scroll-tech/coordinator/internal/logic/verifier"
|
||||
coordinatorType "scroll-tech/coordinator/internal/types"
|
||||
)
|
||||
|
||||
// SubmitProofController the submit proof api controller
|
||||
@@ -22,18 +23,18 @@ type SubmitProofController struct {
|
||||
}
|
||||
|
||||
// NewSubmitProofController create the submit proof api controller instance
|
||||
func NewSubmitProofController(cfg *config.Config, db *gorm.DB, reg prometheus.Registerer) *SubmitProofController {
|
||||
func NewSubmitProofController(cfg *config.Config, db *gorm.DB, vf *verifier.Verifier, reg prometheus.Registerer) *SubmitProofController {
|
||||
return &SubmitProofController{
|
||||
submitProofReceiverLogic: submitproof.NewSubmitProofReceiverLogic(cfg.ProverManager, db, reg),
|
||||
submitProofReceiverLogic: submitproof.NewSubmitProofReceiverLogic(cfg.ProverManager, db, vf, reg),
|
||||
}
|
||||
}
|
||||
|
||||
// SubmitProof prover submit the proof to coordinator
|
||||
func (spc *SubmitProofController) SubmitProof(ctx *gin.Context) {
|
||||
var spp coodinatorType.SubmitProofParameter
|
||||
var spp coordinatorType.SubmitProofParameter
|
||||
if err := ctx.ShouldBind(&spp); err != nil {
|
||||
nerr := fmt.Errorf("parameter invalid, err:%w", err)
|
||||
coodinatorType.RenderJSON(ctx, types.ErrCoordinatorParameterInvalidNo, nerr, nil)
|
||||
coordinatorType.RenderJSON(ctx, types.ErrCoordinatorParameterInvalidNo, nerr, nil)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -51,7 +52,7 @@ func (spc *SubmitProofController) SubmitProof(ctx *gin.Context) {
|
||||
var tmpChunkProof message.ChunkProof
|
||||
if err := json.Unmarshal([]byte(spp.Proof), &tmpChunkProof); err != nil {
|
||||
nerr := fmt.Errorf("unmarshal parameter chunk proof invalid, err:%w", err)
|
||||
coodinatorType.RenderJSON(ctx, types.ErrCoordinatorParameterInvalidNo, nerr, nil)
|
||||
coordinatorType.RenderJSON(ctx, types.ErrCoordinatorParameterInvalidNo, nerr, nil)
|
||||
return
|
||||
}
|
||||
proofMsg.ChunkProof = &tmpChunkProof
|
||||
@@ -59,7 +60,7 @@ func (spc *SubmitProofController) SubmitProof(ctx *gin.Context) {
|
||||
var tmpBatchProof message.BatchProof
|
||||
if err := json.Unmarshal([]byte(spp.Proof), &tmpBatchProof); err != nil {
|
||||
nerr := fmt.Errorf("unmarshal parameter batch proof invalid, err:%w", err)
|
||||
coodinatorType.RenderJSON(ctx, types.ErrCoordinatorParameterInvalidNo, nerr, nil)
|
||||
coordinatorType.RenderJSON(ctx, types.ErrCoordinatorParameterInvalidNo, nerr, nil)
|
||||
return
|
||||
}
|
||||
proofMsg.BatchProof = &tmpBatchProof
|
||||
@@ -68,8 +69,8 @@ func (spc *SubmitProofController) SubmitProof(ctx *gin.Context) {
|
||||
|
||||
if err := spc.submitProofReceiverLogic.HandleZkProof(ctx, &proofMsg, spp); err != nil {
|
||||
nerr := fmt.Errorf("handle zk proof failure, err:%w", err)
|
||||
coodinatorType.RenderJSON(ctx, types.ErrCoordinatorHandleZkProofFailure, nerr, nil)
|
||||
coordinatorType.RenderJSON(ctx, types.ErrCoordinatorHandleZkProofFailure, nerr, nil)
|
||||
return
|
||||
}
|
||||
coodinatorType.RenderJSON(ctx, types.Success, nil, nil)
|
||||
coordinatorType.RenderJSON(ctx, types.Success, nil, nil)
|
||||
}
|
||||
|
||||
@@ -29,10 +29,11 @@ type Collector struct {
|
||||
chunkOrm *orm.Chunk
|
||||
batchOrm *orm.Batch
|
||||
|
||||
timeoutBatchCheckerRunTotal prometheus.Counter
|
||||
batchProverTaskTimeoutTotal prometheus.Counter
|
||||
timeoutChunkCheckerRunTotal prometheus.Counter
|
||||
chunkProverTaskTimeoutTotal prometheus.Counter
|
||||
timeoutBatchCheckerRunTotal prometheus.Counter
|
||||
batchProverTaskTimeoutTotal prometheus.Counter
|
||||
timeoutChunkCheckerRunTotal prometheus.Counter
|
||||
chunkProverTaskTimeoutTotal prometheus.Counter
|
||||
checkBatchAllChunkReadyRunTotal prometheus.Counter
|
||||
}
|
||||
|
||||
// NewCollector create a collector to cron collect the data to send to prover
|
||||
@@ -62,10 +63,15 @@ func NewCollector(ctx context.Context, db *gorm.DB, cfg *config.Config, reg prom
|
||||
Name: "coordinator_chunk_prover_task_timeout_total",
|
||||
Help: "Total number of chunk timeout prover task.",
|
||||
}),
|
||||
checkBatchAllChunkReadyRunTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
|
||||
Name: "coordinator_check_batch_all_chunk_ready_run_total",
|
||||
Help: "Total number of check batch all chunks ready total",
|
||||
}),
|
||||
}
|
||||
|
||||
go c.timeoutBatchProofTask()
|
||||
go c.timeoutChunkProofTask()
|
||||
go c.checkBatchAllChunkReady()
|
||||
|
||||
log.Info("Start coordinator successfully.")
|
||||
|
||||
@@ -79,7 +85,6 @@ func (c *Collector) Stop() {
|
||||
|
||||
// timeoutTask cron check the send task is timeout. if timeout reached, restore the
|
||||
// chunk/batch task to unassigned. then the batch/chunk collector can retry it.
|
||||
|
||||
func (c *Collector) timeoutBatchProofTask() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
@@ -149,7 +154,7 @@ func (c *Collector) check(assignedProverTasks []orm.ProverTask, timeout promethe
|
||||
// here not update the block batch proving status failed, because the collector loop will check
|
||||
// the attempt times. if reach the times, the collector will set the block batch proving status.
|
||||
for _, assignedProverTask := range assignedProverTasks {
|
||||
if c.proverTaskOrm.TaskTimeoutMoreThanOnce(c.ctx, assignedProverTask.TaskID) {
|
||||
if c.proverTaskOrm.TaskTimeoutMoreThanOnce(c.ctx, message.ProofType(assignedProverTask.TaskType), assignedProverTask.TaskID) {
|
||||
log.Warn("Task timeout more than once", "taskType", message.ProofType(assignedProverTask.TaskType).String(), "hash", assignedProverTask.TaskID)
|
||||
}
|
||||
|
||||
@@ -189,3 +194,60 @@ func (c *Collector) check(assignedProverTasks []orm.ProverTask, timeout promethe
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Collector) checkBatchAllChunkReady() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
nerr := fmt.Errorf("check batch all chunk ready panic error:%v", err)
|
||||
log.Warn(nerr.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
ticker := time.NewTicker(time.Second * 10)
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
c.checkBatchAllChunkReadyRunTotal.Inc()
|
||||
page := 1
|
||||
pageSize := 50
|
||||
for {
|
||||
offset := (page - 1) * pageSize
|
||||
batches, err := c.batchOrm.GetUnassignedAndChunksUnreadyBatches(c.ctx, offset, pageSize)
|
||||
if err != nil {
|
||||
log.Warn("checkBatchAllChunkReady GetUnassignedAndChunksUnreadyBatches", "error", err)
|
||||
break
|
||||
}
|
||||
|
||||
for _, batch := range batches {
|
||||
allReady, checkErr := c.chunkOrm.CheckIfBatchChunkProofsAreReady(c.ctx, batch.Hash)
|
||||
if checkErr != nil {
|
||||
log.Warn("checkBatchAllChunkReady CheckIfBatchChunkProofsAreReady failure", "error", checkErr, "hash", batch.Hash)
|
||||
continue
|
||||
}
|
||||
|
||||
if !allReady {
|
||||
continue
|
||||
}
|
||||
|
||||
if updateErr := c.batchOrm.UpdateChunkProofsStatusByBatchHash(c.ctx, batch.Hash, types.ChunkProofsStatusReady); updateErr != nil {
|
||||
log.Warn("checkBatchAllChunkReady UpdateChunkProofsStatusByBatchHash failure", "error", checkErr, "hash", batch.Hash)
|
||||
}
|
||||
}
|
||||
|
||||
if len(batches) < pageSize {
|
||||
break
|
||||
}
|
||||
page++
|
||||
}
|
||||
|
||||
case <-c.ctx.Done():
|
||||
if c.ctx.Err() != nil {
|
||||
log.Error("manager context canceled with error", "error", c.ctx.Err())
|
||||
}
|
||||
return
|
||||
case <-c.stopTimeoutChan:
|
||||
log.Info("the coordinator run loop exit")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,13 +25,14 @@ import (
|
||||
// BatchProverTask is prover task implement for batch proof
|
||||
type BatchProverTask struct {
|
||||
BaseProverTask
|
||||
vk string
|
||||
|
||||
batchAttemptsExceedTotal prometheus.Counter
|
||||
batchTaskGetTaskTotal prometheus.Counter
|
||||
}
|
||||
|
||||
// NewBatchProverTask new a batch collector
|
||||
func NewBatchProverTask(cfg *config.Config, db *gorm.DB, reg prometheus.Registerer) *BatchProverTask {
|
||||
func NewBatchProverTask(cfg *config.Config, db *gorm.DB, vk string, reg prometheus.Registerer) *BatchProverTask {
|
||||
bp := &BatchProverTask{
|
||||
BaseProverTask: BaseProverTask{
|
||||
db: db,
|
||||
@@ -40,6 +41,7 @@ func NewBatchProverTask(cfg *config.Config, db *gorm.DB, reg prometheus.Register
|
||||
batchOrm: orm.NewBatch(db),
|
||||
proverTaskOrm: orm.NewProverTask(db),
|
||||
},
|
||||
vk: vk,
|
||||
batchAttemptsExceedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
|
||||
Name: "coordinator_batch_attempts_exceed_total",
|
||||
Help: "Total number of batch attempts exceed.",
|
||||
@@ -68,7 +70,15 @@ func (bp *BatchProverTask) Assign(ctx *gin.Context, getTaskParameter *coordinato
|
||||
if !proverVersionExist {
|
||||
return nil, fmt.Errorf("get prover version from context failed")
|
||||
}
|
||||
if !version.CheckScrollProverVersion(proverVersion.(string)) {
|
||||
if getTaskParameter.VK == "" { // allow vk being empty, because for the first time the prover may not know its vk
|
||||
if !version.CheckScrollProverVersionTag(proverVersion.(string)) { // but reject too-old provers
|
||||
return nil, fmt.Errorf("incompatible prover version. please upgrade your prover, expect version: %s, actual version: %s", version.Version, proverVersion.(string))
|
||||
}
|
||||
} else if getTaskParameter.VK != bp.vk { // non-empty vk but different
|
||||
if version.CheckScrollProverVersion(proverVersion.(string)) { // same prover version but different vks
|
||||
return nil, fmt.Errorf("incompatible vk. please check your params files or config files")
|
||||
}
|
||||
// different prover versions and different vks
|
||||
return nil, fmt.Errorf("incompatible prover version. please upgrade your prover, expect version: %s, actual version: %s", version.Version, proverVersion.(string))
|
||||
}
|
||||
|
||||
@@ -91,7 +101,8 @@ func (bp *BatchProverTask) Assign(ctx *gin.Context, getTaskParameter *coordinato
|
||||
}
|
||||
|
||||
if len(batchTasks) != 1 {
|
||||
return nil, fmt.Errorf("get unassigned batch proving task len not 1, batch tasks:%v", batchTasks)
|
||||
log.Error("get unassigned batch proving task len not 1", "length", len(batchTasks), "batch tasks", batchTasks)
|
||||
return nil, ErrCoordinatorInternalFailure
|
||||
}
|
||||
|
||||
batchTask := batchTasks[0]
|
||||
@@ -99,7 +110,9 @@ func (bp *BatchProverTask) Assign(ctx *gin.Context, getTaskParameter *coordinato
|
||||
|
||||
if !bp.checkAttemptsExceeded(batchTask.Hash, message.ProofTypeBatch) {
|
||||
bp.batchAttemptsExceedTotal.Inc()
|
||||
return nil, fmt.Errorf("the batch task id:%s check attempts have reach the maximum", batchTask.Hash)
|
||||
// TODO: retry fetching unassigned batch proving task
|
||||
log.Error("batch task proving attempts reach the maximum", "hash", batchTask.Hash)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
proverTask := orm.ProverTask{
|
||||
@@ -117,13 +130,15 @@ func (bp *BatchProverTask) Assign(ctx *gin.Context, getTaskParameter *coordinato
|
||||
// Store session info.
|
||||
if err = bp.proverTaskOrm.SetProverTask(ctx, &proverTask); err != nil {
|
||||
bp.recoverProvingStatus(ctx, batchTask)
|
||||
return nil, fmt.Errorf("db set session info fail, session id:%s, error:%w", proverTask.TaskID, err)
|
||||
log.Error("db set session info fail", "task hash", batchTask.Hash, "prover name", proverName.(string), "prover pubKey", publicKey.(string), "err", err)
|
||||
return nil, ErrCoordinatorInternalFailure
|
||||
}
|
||||
|
||||
taskMsg, err := bp.formatProverTask(ctx, batchTask.Hash)
|
||||
if err != nil {
|
||||
bp.recoverProvingStatus(ctx, batchTask)
|
||||
return nil, fmt.Errorf("format prover failure, id:%s error:%w", batchTask.Hash, err)
|
||||
log.Error("format prover task failure", "hash", batchTask.Hash, "err", err)
|
||||
return nil, ErrCoordinatorInternalFailure
|
||||
}
|
||||
|
||||
bp.batchTaskGetTaskTotal.Inc()
|
||||
|
||||
@@ -22,16 +22,20 @@ import (
|
||||
coordinatorType "scroll-tech/coordinator/internal/types"
|
||||
)
|
||||
|
||||
// ErrCoordinatorInternalFailure coordinator internal db failure
|
||||
var ErrCoordinatorInternalFailure = fmt.Errorf("coordinator internal error")
|
||||
|
||||
// ChunkProverTask the chunk prover task
|
||||
type ChunkProverTask struct {
|
||||
BaseProverTask
|
||||
vk string
|
||||
|
||||
chunkAttemptsExceedTotal prometheus.Counter
|
||||
chunkTaskGetTaskTotal prometheus.Counter
|
||||
}
|
||||
|
||||
// NewChunkProverTask new a chunk prover task
|
||||
func NewChunkProverTask(cfg *config.Config, db *gorm.DB, reg prometheus.Registerer) *ChunkProverTask {
|
||||
func NewChunkProverTask(cfg *config.Config, db *gorm.DB, vk string, reg prometheus.Registerer) *ChunkProverTask {
|
||||
cp := &ChunkProverTask{
|
||||
BaseProverTask: BaseProverTask{
|
||||
db: db,
|
||||
@@ -40,7 +44,7 @@ func NewChunkProverTask(cfg *config.Config, db *gorm.DB, reg prometheus.Register
|
||||
blockOrm: orm.NewL2Block(db),
|
||||
proverTaskOrm: orm.NewProverTask(db),
|
||||
},
|
||||
|
||||
vk: vk,
|
||||
chunkAttemptsExceedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
|
||||
Name: "coordinator_chunk_attempts_exceed_total",
|
||||
Help: "Total number of chunk attempts exceed.",
|
||||
@@ -69,7 +73,15 @@ func (cp *ChunkProverTask) Assign(ctx *gin.Context, getTaskParameter *coordinato
|
||||
if !proverVersionExist {
|
||||
return nil, fmt.Errorf("get prover version from context failed")
|
||||
}
|
||||
if !version.CheckScrollProverVersion(proverVersion.(string)) {
|
||||
if getTaskParameter.VK == "" { // allow vk being empty, because for the first time the prover may not know its vk
|
||||
if !version.CheckScrollProverVersionTag(proverVersion.(string)) { // but reject too-old provers
|
||||
return nil, fmt.Errorf("incompatible prover version. please upgrade your prover, expect version: %s, actual version: %s", version.Version, proverVersion.(string))
|
||||
}
|
||||
} else if getTaskParameter.VK != cp.vk { // non-empty vk but different
|
||||
if version.CheckScrollProverVersion(proverVersion.(string)) { // same prover version but different vks
|
||||
return nil, fmt.Errorf("incompatible vk. please check your params files or config files")
|
||||
}
|
||||
// different prover versions and different vks
|
||||
return nil, fmt.Errorf("incompatible prover version. please upgrade your prover, expect version: %s, actual version: %s", version.Version, proverVersion.(string))
|
||||
}
|
||||
|
||||
@@ -85,7 +97,8 @@ func (cp *ChunkProverTask) Assign(ctx *gin.Context, getTaskParameter *coordinato
|
||||
// load and send chunk tasks
|
||||
chunkTasks, err := cp.chunkOrm.UpdateUnassignedChunkReturning(ctx, getTaskParameter.ProverHeight, 1)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get unassigned chunk proving tasks, error:%w", err)
|
||||
log.Error("failed to get unassigned chunk proving tasks", "height", getTaskParameter.ProverHeight, "err", err)
|
||||
return nil, ErrCoordinatorInternalFailure
|
||||
}
|
||||
|
||||
if len(chunkTasks) == 0 {
|
||||
@@ -93,7 +106,8 @@ func (cp *ChunkProverTask) Assign(ctx *gin.Context, getTaskParameter *coordinato
|
||||
}
|
||||
|
||||
if len(chunkTasks) != 1 {
|
||||
return nil, fmt.Errorf("get unassigned chunk proving task len not 1, chunk tasks:%v", chunkTasks)
|
||||
log.Error("get unassigned chunk proving task len not 1", "length", len(chunkTasks), "chunk tasks", chunkTasks)
|
||||
return nil, ErrCoordinatorInternalFailure
|
||||
}
|
||||
|
||||
chunkTask := chunkTasks[0]
|
||||
@@ -102,7 +116,9 @@ func (cp *ChunkProverTask) Assign(ctx *gin.Context, getTaskParameter *coordinato
|
||||
|
||||
if !cp.checkAttemptsExceeded(chunkTask.Hash, message.ProofTypeChunk) {
|
||||
cp.chunkAttemptsExceedTotal.Inc()
|
||||
return nil, fmt.Errorf("chunk proof hash id:%s check attempts have reach the maximum", chunkTask.Hash)
|
||||
// TODO: retry fetching unassigned chunk proving task
|
||||
log.Error("chunk task proving attempts reach the maximum", "hash", chunkTask.Hash)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
proverTask := orm.ProverTask{
|
||||
@@ -118,13 +134,15 @@ func (cp *ChunkProverTask) Assign(ctx *gin.Context, getTaskParameter *coordinato
|
||||
}
|
||||
if err = cp.proverTaskOrm.SetProverTask(ctx, &proverTask); err != nil {
|
||||
cp.recoverProvingStatus(ctx, chunkTask)
|
||||
return nil, fmt.Errorf("db set session info fail, session id:%s , public key:%s, err:%w", chunkTask.Hash, publicKey, err)
|
||||
log.Error("db set session info fail", "task hash", chunkTask.Hash, "prover name", proverName.(string), "prover pubKey", publicKey.(string), "err", err)
|
||||
return nil, ErrCoordinatorInternalFailure
|
||||
}
|
||||
|
||||
taskMsg, err := cp.formatProverTask(ctx, chunkTask.Hash)
|
||||
if err != nil {
|
||||
cp.recoverProvingStatus(ctx, chunkTask)
|
||||
return nil, fmt.Errorf("format prover task failure, id:%s error:%w", chunkTask.Hash, err)
|
||||
log.Error("format prover task failure", "hash", chunkTask.Hash, "err", err)
|
||||
return nil, ErrCoordinatorInternalFailure
|
||||
}
|
||||
|
||||
cp.chunkTaskGetTaskTotal.Inc()
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -33,6 +34,12 @@ var (
|
||||
ErrValidatorFailureProofTimeout = errors.New("validator failure submit proof timeout")
|
||||
// ErrValidatorFailureTaskHaveVerifiedSuccess have proved success and verified success
|
||||
ErrValidatorFailureTaskHaveVerifiedSuccess = errors.New("validator failure chunk/batch have proved and verified success")
|
||||
// ErrValidatorFailureVerifiedFailed failed to verify and the verifier returns error
|
||||
ErrValidatorFailureVerifiedFailed = fmt.Errorf("verification failed, verifier returns error")
|
||||
// ErrValidatorSuccessInvalidProof successful verified and the proof is invalid
|
||||
ErrValidatorSuccessInvalidProof = fmt.Errorf("verification succeeded, it's an invalid proof")
|
||||
// ErrCoordinatorInternalFailure coordinator internal db failure
|
||||
ErrCoordinatorInternalFailure = fmt.Errorf("coordinator internal error")
|
||||
)
|
||||
|
||||
// ProofReceiverLogic the proof receiver logic
|
||||
@@ -59,11 +66,7 @@ type ProofReceiverLogic struct {
|
||||
}
|
||||
|
||||
// NewSubmitProofReceiverLogic create a proof receiver logic
|
||||
func NewSubmitProofReceiverLogic(cfg *config.ProverManager, db *gorm.DB, reg prometheus.Registerer) *ProofReceiverLogic {
|
||||
vf, err := verifier.NewVerifier(cfg.Verifier)
|
||||
if err != nil {
|
||||
panic("proof receiver new verifier failure")
|
||||
}
|
||||
func NewSubmitProofReceiverLogic(cfg *config.ProverManager, db *gorm.DB, vf *verifier.Verifier, reg prometheus.Registerer) *ProofReceiverLogic {
|
||||
return &ProofReceiverLogic{
|
||||
chunkOrm: orm.NewChunk(db),
|
||||
batchOrm: orm.NewBatch(db),
|
||||
@@ -132,7 +135,7 @@ func (m *ProofReceiverLogic) HandleZkProof(ctx *gin.Context, proofMsg *message.P
|
||||
return fmt.Errorf("get ProverVersion from context failed")
|
||||
}
|
||||
|
||||
proverTask, err := m.proverTaskOrm.GetProverTaskByTaskIDAndProver(ctx, proofMsg.ID, pk, pv)
|
||||
proverTask, err := m.proverTaskOrm.GetProverTaskByTaskIDAndProver(ctx, proofMsg.Type, proofMsg.ID, pk, pv)
|
||||
if proverTask == nil || err != nil {
|
||||
log.Error("get none prover task for the proof", "key", pk, "taskID", proofMsg.ID, "error", err)
|
||||
return ErrValidatorFailureProverTaskEmpty
|
||||
@@ -165,10 +168,10 @@ func (m *ProofReceiverLogic) HandleZkProof(ctx *gin.Context, proofMsg *message.P
|
||||
log.Info("proof verified by coordinator failed", "proof id", proofMsg.ID, "prover name", proverTask.ProverName,
|
||||
"prover pk", pk, "prove type", proofMsg.Type, "proof time", proofTimeSec, "error", verifyErr)
|
||||
|
||||
if verifyErr == nil {
|
||||
verifyErr = fmt.Errorf("verification succeeded and it's an invalid proof")
|
||||
if verifyErr != nil {
|
||||
return ErrValidatorFailureVerifiedFailed
|
||||
}
|
||||
return verifyErr
|
||||
return ErrValidatorSuccessInvalidProof
|
||||
}
|
||||
|
||||
m.proverTaskProveDuration.Observe(time.Since(proverTask.CreatedAt).Seconds())
|
||||
@@ -179,7 +182,7 @@ func (m *ProofReceiverLogic) HandleZkProof(ctx *gin.Context, proofMsg *message.P
|
||||
if err := m.closeProofTask(ctx, proofMsg.ID, pk, proofMsg, proofTimeSec); err != nil {
|
||||
m.proofSubmitFailure.Inc()
|
||||
m.proofRecover(ctx, proofMsg.ID, pk, proofMsg)
|
||||
return err
|
||||
return ErrCoordinatorInternalFailure
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -231,12 +234,19 @@ func (m *ProofReceiverLogic) validator(ctx context.Context, proverTask *orm.Prov
|
||||
proofTimeSec := uint64(proofTime.Seconds())
|
||||
|
||||
if proofMsg.Status != message.StatusOk {
|
||||
m.proofRecover(ctx, proofMsg.ID, pk, proofMsg)
|
||||
// Temporarily replace "panic" with "pa-nic" to prevent triggering the alert based on logs.
|
||||
failureMsg := strings.Replace(proofParameter.FailureMsg, "panic", "pa-nic", -1)
|
||||
// Verify if the proving task has already been assigned to another prover.
|
||||
// Upon receiving an error message, it's possible the proving status has been reset by another prover
|
||||
// and the task has been reassigned. In this case, the coordinator should avoid resetting the proving status.
|
||||
m.processProverErr(ctx, proofMsg.ID, pk, proofMsg.Type)
|
||||
|
||||
m.validateFailureProverTaskStatusNotOk.Inc()
|
||||
|
||||
log.Info("proof generated by prover failed",
|
||||
"taskType", proofMsg.Type, "hash", proofMsg.ID,
|
||||
"proverName", proverTask.ProverName, "proverVersion", proverTask.ProverVersion,
|
||||
"proverPublicKey", pk, "failureType", proofParameter.FailureType, "failureMessage", proofParameter.FailureMsg)
|
||||
"taskType", proofMsg.Type, "hash", proofMsg.ID, "proverName", proverTask.ProverName,
|
||||
"proverVersion", proverTask.ProverVersion, "proverPublicKey", pk, "failureType", proofParameter.FailureType,
|
||||
"failureMessage", "failureMessage", failureMsg)
|
||||
return ErrValidatorFailureProofMsgStatusNotOk
|
||||
}
|
||||
|
||||
@@ -264,15 +274,6 @@ func (m *ProofReceiverLogic) validator(ctx context.Context, proverTask *orm.Prov
|
||||
return nil
|
||||
}
|
||||
|
||||
//func (m *ProofReceiverLogic) proofFailure(ctx context.Context, hash string, pubKey string, proofMsg *message.ProofMsg) {
|
||||
// log.Info("proof failure update proof status", "hash", hash, "public key", pubKey,
|
||||
// "proof type", proofMsg.Type.String(), "status", types.ProvingTaskFailed.String())
|
||||
//
|
||||
// if err := m.updateProofStatus(ctx, hash, pubKey, proofMsg, types.ProvingTaskFailed, 0); err != nil {
|
||||
// log.Error("failed to updated proof status ProvingTaskFailed", "hash", hash, "pubKey", pubKey, "error", err)
|
||||
// }
|
||||
//}
|
||||
|
||||
func (m *ProofReceiverLogic) proofRecover(ctx context.Context, hash string, pubKey string, proofMsg *message.ProofMsg) {
|
||||
log.Info("proof recover update proof status", "hash", hash, "proverPublicKey", pubKey,
|
||||
"taskType", proofMsg.Type.String(), "status", types.ProvingTaskUnassigned.String())
|
||||
@@ -377,6 +378,33 @@ func (m *ProofReceiverLogic) checkIsTaskSuccess(ctx context.Context, hash string
|
||||
return provingStatus == types.ProvingTaskVerified
|
||||
}
|
||||
|
||||
func (m *ProofReceiverLogic) processProverErr(ctx context.Context, taskID, pk string, taskType message.ProofType) {
|
||||
if updateErr := m.proverTaskOrm.UpdateProverTaskProvingStatus(ctx, taskType, taskID, pk, types.ProverProofInvalid); updateErr != nil {
|
||||
log.Error("update prover task proving status failure", "taskID", taskID, "proverPublicKey", pk, "taskType", taskType, "error", updateErr)
|
||||
}
|
||||
|
||||
proverTasks, err := m.proverTaskOrm.GetAssignedTaskOfOtherProvers(ctx, taskType, taskID, pk)
|
||||
if err != nil {
|
||||
log.Warn("checkIsAssignedToOtherProver failure", "taskID", taskID, "proverPublicKey", pk, "taskType", taskType, "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(proverTasks) > 0 {
|
||||
return
|
||||
}
|
||||
|
||||
switch taskType {
|
||||
case message.ProofTypeChunk:
|
||||
if err := m.chunkOrm.UpdateProvingStatusFromProverError(ctx, taskID, types.ProvingTaskUnassigned); err != nil {
|
||||
log.Error("failed to update chunk proving_status as failed", taskID, "proverPublicKey", pk, "taskType", taskType, "error", err)
|
||||
}
|
||||
case message.ProofTypeBatch:
|
||||
if err := m.batchOrm.UpdateProvingStatusFromProverError(ctx, taskID, types.ProvingTaskUnassigned); err != nil {
|
||||
log.Error("failed to update batch proving_status as failed", taskID, "proverPublicKey", pk, "taskType", taskType, "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *ProofReceiverLogic) updateProverTaskProof(ctx context.Context, pk string, proofMsg *message.ProofMsg) error {
|
||||
// store the proof to prover task
|
||||
var proofBytes []byte
|
||||
|
||||
@@ -8,11 +8,6 @@ import (
|
||||
"scroll-tech/coordinator/internal/config"
|
||||
)
|
||||
|
||||
const InvalidTestProof = "this is a invalid proof"
|
||||
|
||||
// Verifier represents a mock halo2 verifier.
|
||||
type Verifier struct{}
|
||||
|
||||
// NewVerifier Sets up a mock verifier.
|
||||
func NewVerifier(_ *config.VerifierConfig) (*Verifier, error) {
|
||||
return &Verifier{}, nil
|
||||
|
||||
15
coordinator/internal/logic/verifier/types.go
Normal file
15
coordinator/internal/logic/verifier/types.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package verifier
|
||||
|
||||
import (
|
||||
"scroll-tech/coordinator/internal/config"
|
||||
)
|
||||
|
||||
// InvalidTestProof invalid proof used in tests
|
||||
const InvalidTestProof = "this is a invalid proof"
|
||||
|
||||
// Verifier represents a rust ffi to a halo2 verifier.
|
||||
type Verifier struct {
|
||||
cfg *config.VerifierConfig
|
||||
BatchVK string
|
||||
ChunkVK string
|
||||
}
|
||||
@@ -11,7 +11,11 @@ package verifier
|
||||
import "C" //nolint:typecheck
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"unsafe"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
@@ -21,14 +25,6 @@ import (
|
||||
"scroll-tech/common/types/message"
|
||||
)
|
||||
|
||||
// InvalidTestProof invalid proof used in tests
|
||||
const InvalidTestProof = "this is a invalid proof"
|
||||
|
||||
// Verifier represents a rust ffi to a halo2 verifier.
|
||||
type Verifier struct {
|
||||
cfg *config.VerifierConfig
|
||||
}
|
||||
|
||||
// NewVerifier Sets up a rust ffi to call verify.
|
||||
func NewVerifier(cfg *config.VerifierConfig) (*Verifier, error) {
|
||||
if cfg.MockMode {
|
||||
@@ -44,7 +40,21 @@ func NewVerifier(cfg *config.VerifierConfig) (*Verifier, error) {
|
||||
C.init_batch_verifier(paramsPathStr, assetsPathStr)
|
||||
C.init_chunk_verifier(paramsPathStr, assetsPathStr)
|
||||
|
||||
return &Verifier{cfg: cfg}, nil
|
||||
batchVK, err := readVK(path.Join(cfg.AssetsPath, "agg_vk.vkey"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
chunkVK, err := readVK(path.Join(cfg.AssetsPath, "chunk_vk.vkey"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Verifier{
|
||||
cfg: cfg,
|
||||
BatchVK: batchVK,
|
||||
ChunkVK: chunkVK,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// VerifyBatchProof Verify a ZkProof by marshaling it and sending it to the Halo2 Verifier.
|
||||
@@ -96,3 +106,15 @@ func (v *Verifier) VerifyChunkProof(proof *message.ChunkProof) (bool, error) {
|
||||
verified := C.verify_chunk_proof(proofStr)
|
||||
return verified != 0, nil
|
||||
}
|
||||
|
||||
func readVK(filePat string) (string, error) {
|
||||
f, err := os.Open(filePat)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
byt, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(byt), nil
|
||||
}
|
||||
|
||||
@@ -91,11 +91,31 @@ func (o *Batch) GetUnassignedBatches(ctx context.Context, limit int) ([]*Batch,
|
||||
return batches, nil
|
||||
}
|
||||
|
||||
// GetAssignedBatches retrieves all batches whose proving_status is either types.ProvingTaskAssigned or types.ProvingTaskProved.
|
||||
// GetUnassignedAndChunksUnreadyBatches get the batches which is unassigned and chunks is not ready
|
||||
func (o *Batch) GetUnassignedAndChunksUnreadyBatches(ctx context.Context, offset, limit int) ([]*Batch, error) {
|
||||
if offset < 0 || limit < 0 {
|
||||
return nil, errors.New("limit and offset must not be smaller than 0")
|
||||
}
|
||||
|
||||
db := o.db.WithContext(ctx)
|
||||
db = db.Where("proving_status = ?", types.ProvingTaskUnassigned)
|
||||
db = db.Where("chunk_proofs_status = ?", types.ChunkProofsStatusPending)
|
||||
db = db.Order("index ASC")
|
||||
db = db.Offset(offset)
|
||||
db = db.Limit(limit)
|
||||
|
||||
var batches []*Batch
|
||||
if err := db.Find(&batches).Error; err != nil {
|
||||
return nil, fmt.Errorf("Batch.GetUnassignedAndChunksUnreadyBatches error: %w", err)
|
||||
}
|
||||
return batches, nil
|
||||
}
|
||||
|
||||
// GetAssignedBatches retrieves all batches whose proving_status is either types.ProvingTaskAssigned.
|
||||
func (o *Batch) GetAssignedBatches(ctx context.Context) ([]*Batch, error) {
|
||||
db := o.db.WithContext(ctx)
|
||||
db = db.Model(&Batch{})
|
||||
db = db.Where("proving_status IN (?)", []int{int(types.ProvingTaskAssigned), int(types.ProvingTaskProved)})
|
||||
db = db.Where("proving_status = ?", int(types.ProvingTaskAssigned))
|
||||
|
||||
var assignedBatches []*Batch
|
||||
if err := db.Find(&assignedBatches).Error; err != nil {
|
||||
@@ -236,7 +256,7 @@ func (o *Batch) UpdateProvingStatus(ctx context.Context, hash string, status typ
|
||||
updateFields["prover_assigned_at"] = time.Now()
|
||||
case types.ProvingTaskUnassigned:
|
||||
updateFields["prover_assigned_at"] = nil
|
||||
case types.ProvingTaskProved, types.ProvingTaskVerified:
|
||||
case types.ProvingTaskVerified:
|
||||
updateFields["proved_at"] = time.Now()
|
||||
}
|
||||
|
||||
@@ -250,6 +270,30 @@ func (o *Batch) UpdateProvingStatus(ctx context.Context, hash string, status typ
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateProvingStatusFromProverError updates batch proving status when prover prove failed
|
||||
func (o *Batch) UpdateProvingStatusFromProverError(ctx context.Context, hash string, status types.ProvingStatus) error {
|
||||
updateFields := make(map[string]interface{})
|
||||
updateFields["proving_status"] = int(status)
|
||||
|
||||
switch status {
|
||||
case types.ProvingTaskAssigned:
|
||||
updateFields["prover_assigned_at"] = time.Now()
|
||||
case types.ProvingTaskUnassigned:
|
||||
updateFields["prover_assigned_at"] = nil
|
||||
case types.ProvingTaskVerified:
|
||||
updateFields["proved_at"] = time.Now()
|
||||
}
|
||||
|
||||
db := o.db.WithContext(ctx)
|
||||
db = db.Model(&Batch{})
|
||||
db = db.Where("hash", hash).Where("proving_status", types.ProvingTaskAssigned)
|
||||
|
||||
if err := db.Updates(updateFields).Error; err != nil {
|
||||
return fmt.Errorf("Batch.UpdateProvingStatusOptimistic error: %w, batch hash: %v, status: %v", err, hash, status.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateProofByHash updates the batch proof by hash.
|
||||
func (o *Batch) UpdateProofByHash(ctx context.Context, hash string, proof *message.BatchProof, proofTimeSec uint64, dbTX ...*gorm.DB) error {
|
||||
db := o.db
|
||||
|
||||
@@ -155,11 +155,11 @@ func (o *Chunk) GetProvingStatusByHash(ctx context.Context, hash string) (types.
|
||||
return types.ProvingStatus(chunk.ProvingStatus), nil
|
||||
}
|
||||
|
||||
// GetAssignedChunks retrieves all chunks whose proving_status is either types.ProvingTaskAssigned or types.ProvingTaskProved.
|
||||
// GetAssignedChunks retrieves all chunks whose proving_status is either types.ProvingTaskAssigned.
|
||||
func (o *Chunk) GetAssignedChunks(ctx context.Context) ([]*Chunk, error) {
|
||||
db := o.db.WithContext(ctx)
|
||||
db = db.Model(&Chunk{})
|
||||
db = db.Where("proving_status IN (?)", []int{int(types.ProvingTaskAssigned), int(types.ProvingTaskProved)})
|
||||
db = db.Where("proving_status = ?", int(types.ProvingTaskAssigned))
|
||||
|
||||
var chunks []*Chunk
|
||||
if err := db.Find(&chunks).Error; err != nil {
|
||||
@@ -285,7 +285,7 @@ func (o *Chunk) UpdateProvingStatus(ctx context.Context, hash string, status typ
|
||||
updateFields["prover_assigned_at"] = time.Now()
|
||||
case types.ProvingTaskUnassigned:
|
||||
updateFields["prover_assigned_at"] = nil
|
||||
case types.ProvingTaskProved, types.ProvingTaskVerified:
|
||||
case types.ProvingTaskVerified:
|
||||
updateFields["proved_at"] = time.Now()
|
||||
}
|
||||
db := o.db
|
||||
@@ -302,6 +302,29 @@ func (o *Chunk) UpdateProvingStatus(ctx context.Context, hash string, status typ
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateProvingStatusFromProverError updates chunk proving status when prover prove failed
|
||||
func (o *Chunk) UpdateProvingStatusFromProverError(ctx context.Context, hash string, status types.ProvingStatus) error {
|
||||
updateFields := make(map[string]interface{})
|
||||
updateFields["proving_status"] = int(status)
|
||||
|
||||
switch status {
|
||||
case types.ProvingTaskAssigned:
|
||||
updateFields["prover_assigned_at"] = time.Now()
|
||||
case types.ProvingTaskUnassigned:
|
||||
updateFields["prover_assigned_at"] = nil
|
||||
case types.ProvingTaskVerified:
|
||||
updateFields["proved_at"] = time.Now()
|
||||
}
|
||||
db := o.db.WithContext(ctx)
|
||||
db = db.Model(&Chunk{})
|
||||
db = db.Where("hash", hash).Where("proving_status", types.ProvingTaskAssigned)
|
||||
|
||||
if err := db.Updates(updateFields).Error; err != nil {
|
||||
return fmt.Errorf("Chunk.UpdateProvingStatusOptimistic error: %w, chunk hash: %v, status: %v", err, hash, status.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateProofByHash updates the chunk proof by hash.
|
||||
func (o *Chunk) UpdateProofByHash(ctx context.Context, hash string, proof *message.ChunkProof, proofTimeSec uint64, dbTX ...*gorm.DB) error {
|
||||
db := o.db
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"scroll-tech/common/database"
|
||||
"scroll-tech/common/docker"
|
||||
"scroll-tech/common/types"
|
||||
"scroll-tech/common/types/message"
|
||||
"scroll-tech/common/utils"
|
||||
|
||||
"scroll-tech/database/migrate"
|
||||
@@ -67,6 +68,7 @@ func TestProverTaskOrm(t *testing.T) {
|
||||
reward.SetString("18446744073709551616", 10) // 1 << 64, uint64 maximum 1<<64 -1
|
||||
|
||||
proverTask := ProverTask{
|
||||
TaskType: int16(message.ProofTypeChunk),
|
||||
TaskID: "test-hash",
|
||||
ProverName: "prover-0",
|
||||
ProverPublicKey: "0",
|
||||
@@ -77,7 +79,7 @@ func TestProverTaskOrm(t *testing.T) {
|
||||
|
||||
err = proverTaskOrm.SetProverTask(context.Background(), &proverTask)
|
||||
assert.NoError(t, err)
|
||||
proverTasks, err := proverTaskOrm.GetProverTasksByHashes(context.Background(), []string{"test-hash"})
|
||||
proverTasks, err := proverTaskOrm.GetProverTasksByHashes(context.Background(), message.ProofTypeChunk, []string{"test-hash"})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(proverTasks))
|
||||
assert.Equal(t, proverTask.ProverName, proverTasks[0].ProverName)
|
||||
@@ -91,7 +93,7 @@ func TestProverTaskOrm(t *testing.T) {
|
||||
proverTask.AssignedAt = utils.NowUTC()
|
||||
err = proverTaskOrm.SetProverTask(context.Background(), &proverTask)
|
||||
assert.NoError(t, err)
|
||||
proverTasks, err = proverTaskOrm.GetProverTasksByHashes(context.Background(), []string{"test-hash"})
|
||||
proverTasks, err = proverTaskOrm.GetProverTasksByHashes(context.Background(), message.ProofTypeChunk, []string{"test-hash"})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(proverTasks))
|
||||
assert.Equal(t, proverTask.ProvingStatus, proverTasks[0].ProvingStatus)
|
||||
@@ -106,6 +108,7 @@ func TestProverTaskOrmUint256(t *testing.T) {
|
||||
rewardUint256 := big.NewInt(0)
|
||||
rewardUint256.SetString("115792089237316195423570985008687907853269984665640564039457584007913129639935", 10)
|
||||
proverTask := ProverTask{
|
||||
TaskType: int16(message.ProofTypeChunk),
|
||||
TaskID: "test-hash",
|
||||
ProverName: "prover-0",
|
||||
ProverPublicKey: "0",
|
||||
@@ -116,7 +119,7 @@ func TestProverTaskOrmUint256(t *testing.T) {
|
||||
|
||||
err = proverTaskOrm.SetProverTask(context.Background(), &proverTask)
|
||||
assert.NoError(t, err)
|
||||
proverTasksUint256, err := proverTaskOrm.GetProverTasksByHashes(context.Background(), []string{"test-hash"})
|
||||
proverTasksUint256, err := proverTaskOrm.GetProverTasksByHashes(context.Background(), message.ProofTypeChunk, []string{"test-hash"})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(proverTasksUint256))
|
||||
resultRewardUint256 := proverTasksUint256[0].Reward.BigInt()
|
||||
|
||||
@@ -96,13 +96,14 @@ func (o *ProverTask) GetProverTasks(ctx context.Context, fields map[string]inter
|
||||
|
||||
// GetProverTasksByHashes retrieves the ProverTask records associated with the specified hashes.
|
||||
// The returned prover task objects are sorted in ascending order by their ids.
|
||||
func (o *ProverTask) GetProverTasksByHashes(ctx context.Context, hashes []string) ([]*ProverTask, error) {
|
||||
func (o *ProverTask) GetProverTasksByHashes(ctx context.Context, taskType message.ProofType, hashes []string) ([]*ProverTask, error) {
|
||||
if len(hashes) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
db := o.db.WithContext(ctx)
|
||||
db = db.Model(&ProverTask{})
|
||||
db = db.Where("task_type", int(taskType))
|
||||
db = db.Where("task_id IN ?", hashes)
|
||||
db = db.Order("id asc")
|
||||
|
||||
@@ -114,9 +115,10 @@ func (o *ProverTask) GetProverTasksByHashes(ctx context.Context, hashes []string
|
||||
}
|
||||
|
||||
// GetProverTaskByTaskIDAndProver get prover task taskID and public key
|
||||
func (o *ProverTask) GetProverTaskByTaskIDAndProver(ctx context.Context, taskID, proverPublicKey, proverVersion string) (*ProverTask, error) {
|
||||
func (o *ProverTask) GetProverTaskByTaskIDAndProver(ctx context.Context, taskType message.ProofType, taskID, proverPublicKey, proverVersion string) (*ProverTask, error) {
|
||||
db := o.db.WithContext(ctx)
|
||||
db = db.Model(&ProverTask{})
|
||||
db = db.Where("task_type", int(taskType))
|
||||
db = db.Where("task_id", taskID)
|
||||
db = db.Where("prover_public_key", proverPublicKey)
|
||||
db = db.Where("prover_version", proverVersion)
|
||||
@@ -129,11 +131,28 @@ func (o *ProverTask) GetProverTaskByTaskIDAndProver(ctx context.Context, taskID,
|
||||
return &proverTask, nil
|
||||
}
|
||||
|
||||
// GetAssignedTaskOfOtherProvers get the chunk/batch task assigned other provers
|
||||
func (o *ProverTask) GetAssignedTaskOfOtherProvers(ctx context.Context, taskType message.ProofType, taskID, proverPublicKey string) ([]ProverTask, error) {
|
||||
db := o.db.WithContext(ctx)
|
||||
db = db.Model(&ProverTask{})
|
||||
db = db.Where("task_type", int(taskType))
|
||||
db = db.Where("task_id", taskID)
|
||||
db = db.Where("prover_public_key != ?", proverPublicKey)
|
||||
db = db.Where("proving_status = ?", int(types.ProverAssigned))
|
||||
|
||||
var proverTasks []ProverTask
|
||||
if err := db.Find(&proverTasks).Error; err != nil {
|
||||
return nil, fmt.Errorf("ProverTask.GetAssignedProverTask error: %w, taskID: %v", err, taskID)
|
||||
}
|
||||
return proverTasks, nil
|
||||
}
|
||||
|
||||
// GetProvingStatusByTaskID retrieves the proving status of a prover task
|
||||
func (o *ProverTask) GetProvingStatusByTaskID(ctx context.Context, taskID string) (types.ProverProveStatus, error) {
|
||||
func (o *ProverTask) GetProvingStatusByTaskID(ctx context.Context, taskType message.ProofType, taskID string) (types.ProverProveStatus, error) {
|
||||
db := o.db.WithContext(ctx)
|
||||
db = db.Model(&ProverTask{})
|
||||
db = db.Select("proving_status")
|
||||
db = db.Where("task_type", int(taskType))
|
||||
db = db.Where("task_id = ?", taskID)
|
||||
|
||||
var proverTask ProverTask
|
||||
@@ -161,9 +180,10 @@ func (o *ProverTask) GetTimeoutAssignedProverTasks(ctx context.Context, limit in
|
||||
}
|
||||
|
||||
// TaskTimeoutMoreThanOnce get the timeout twice task. a temp design
|
||||
func (o *ProverTask) TaskTimeoutMoreThanOnce(ctx context.Context, taskID string) bool {
|
||||
func (o *ProverTask) TaskTimeoutMoreThanOnce(ctx context.Context, taskType message.ProofType, taskID string) bool {
|
||||
db := o.db.WithContext(ctx)
|
||||
db = db.Model(&ProverTask{})
|
||||
db = db.Where("task_type", int(taskType))
|
||||
db = db.Where("task_id", taskID)
|
||||
db = db.Where("proving_status", int(types.ProverProofInvalid))
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@ package types
|
||||
|
||||
// GetTaskParameter for ProverTasks request parameter
|
||||
type GetTaskParameter struct {
|
||||
ProverHeight int `form:"prover_height" json:"prover_height"`
|
||||
TaskType int `form:"task_type" json:"task_type"`
|
||||
ProverHeight int `form:"prover_height" json:"prover_height"`
|
||||
TaskType int `form:"task_type" json:"task_type"`
|
||||
VK string `form:"vk" json:"vk"`
|
||||
}
|
||||
|
||||
// GetTaskSchema the schema data return to prover for get prover task
|
||||
|
||||
@@ -110,7 +110,7 @@ func setupCoordinator(t *testing.T, proversPerSession uint8, coordinatorURL stri
|
||||
}
|
||||
|
||||
func setEnv(t *testing.T) {
|
||||
version.Version = "v1.2.3-aaa-bbb-ccc"
|
||||
version.Version = "v4.1.98-aaa-bbb-ccc"
|
||||
|
||||
base = docker.NewDockerApp()
|
||||
base.RunDBImage(t)
|
||||
@@ -386,9 +386,9 @@ func testProofGeneratedFailed(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
chunkProverTaskProvingStatus, err = proverTaskOrm.GetProvingStatusByTaskID(context.Background(), dbChunk.Hash)
|
||||
chunkProverTaskProvingStatus, err = proverTaskOrm.GetProvingStatusByTaskID(context.Background(), message.ProofTypeChunk, dbChunk.Hash)
|
||||
assert.NoError(t, err)
|
||||
batchProverTaskProvingStatus, err = proverTaskOrm.GetProvingStatusByTaskID(context.Background(), batch.Hash)
|
||||
batchProverTaskProvingStatus, err = proverTaskOrm.GetProvingStatusByTaskID(context.Background(), message.ProofTypeBatch, batch.Hash)
|
||||
assert.NoError(t, err)
|
||||
if chunkProverTaskProvingStatus == types.ProverProofInvalid && batchProverTaskProvingStatus == types.ProverProofInvalid {
|
||||
return
|
||||
|
||||
@@ -39,7 +39,7 @@ create table chunk
|
||||
);
|
||||
|
||||
comment
|
||||
on column chunk.proving_status is 'undefined, unassigned, assigned, proved, verified, failed';
|
||||
on column chunk.proving_status is 'undefined, unassigned, assigned, proved (deprecated), verified, failed';
|
||||
|
||||
create unique index chunk_index_uindex
|
||||
on chunk (index) where deleted_at IS NULL;
|
||||
|
||||
@@ -50,7 +50,7 @@ comment
|
||||
on column batch.chunk_proofs_status is 'undefined, pending, ready';
|
||||
|
||||
comment
|
||||
on column batch.proving_status is 'undefined, unassigned, assigned, proved, verified, failed';
|
||||
on column batch.proving_status is 'undefined, unassigned, assigned, proved (deprecated), verified, failed';
|
||||
|
||||
comment
|
||||
on column batch.rollup_status is 'undefined, pending, committing, committed, finalizing, finalized, commit_failed, finalize_failed';
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
drop index l1_message_hash_uindex;
|
||||
drop index if exists l1_message_hash_uindex;
|
||||
|
||||
create index l1_message_hash_index
|
||||
create index if not exists l1_message_hash_index
|
||||
on l1_message (msg_hash) where deleted_at IS NULL;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
drop index l1_message_hash_index;
|
||||
drop index if exists l1_message_hash_index;
|
||||
|
||||
create unique index l1_message_hash_uindex
|
||||
create unique index if not exists l1_message_hash_uindex
|
||||
on l1_message (msg_hash) where deleted_at IS NULL;
|
||||
-- +goose StatementEnd
|
||||
|
||||
@@ -43,6 +43,7 @@ type LoginResponse struct {
|
||||
type GetTaskRequest struct {
|
||||
TaskType message.ProofType `json:"task_type"`
|
||||
ProverHeight uint64 `json:"prover_height,omitempty"`
|
||||
VK string `json:"vk"`
|
||||
}
|
||||
|
||||
// GetTaskResponse defines the response structure for GetTask API
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"db_path": "unique-db-path-for-prover-1",
|
||||
"core": {
|
||||
"params_path": "params",
|
||||
"assets_path": "assets",
|
||||
"proof_type": 2
|
||||
},
|
||||
"coordinator": {
|
||||
|
||||
@@ -25,6 +25,7 @@ type Config struct {
|
||||
// ProverCoreConfig load zk prover config.
|
||||
type ProverCoreConfig struct {
|
||||
ParamsPath string `json:"params_path"`
|
||||
AssetsPath string `json:"assets_path"`
|
||||
ProofType message.ProofType `json:"proof_type,omitempty"` // 1: chunk prover (default type), 2: batch prover
|
||||
DumpDir string `json:"dump_dir,omitempty"`
|
||||
}
|
||||
|
||||
@@ -42,3 +42,7 @@ func (p *ProverCore) ProveBatch(taskID string, chunkInfos []*message.ChunkInfo,
|
||||
Vk: _empty[:],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *ProverCore) GetVk() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -28,19 +28,22 @@ import (
|
||||
// ProverCore sends block-traces to rust-prover through ffi and get back the zk-proof.
|
||||
type ProverCore struct {
|
||||
cfg *config.ProverCoreConfig
|
||||
vk string
|
||||
}
|
||||
|
||||
// NewProverCore inits a ProverCore object.
|
||||
func NewProverCore(cfg *config.ProverCoreConfig) (*ProverCore, error) {
|
||||
paramsPathStr := C.CString(cfg.ParamsPath)
|
||||
assetsPathStr := C.CString(cfg.AssetsPath)
|
||||
defer func() {
|
||||
C.free(unsafe.Pointer(paramsPathStr))
|
||||
C.free(unsafe.Pointer(assetsPathStr))
|
||||
}()
|
||||
|
||||
if cfg.ProofType == message.ProofTypeBatch {
|
||||
C.init_batch_prover(paramsPathStr)
|
||||
C.init_batch_prover(paramsPathStr, assetsPathStr)
|
||||
} else if cfg.ProofType == message.ProofTypeChunk {
|
||||
C.init_chunk_prover(paramsPathStr)
|
||||
C.init_chunk_prover(paramsPathStr, assetsPathStr)
|
||||
}
|
||||
|
||||
if cfg.DumpDir != "" {
|
||||
@@ -54,6 +57,26 @@ func NewProverCore(cfg *config.ProverCoreConfig) (*ProverCore, error) {
|
||||
return &ProverCore{cfg: cfg}, nil
|
||||
}
|
||||
|
||||
// GetVk get Base64 format of vk.
|
||||
func (p *ProverCore) GetVk() string {
|
||||
if p.vk != "" { // cached
|
||||
return p.vk
|
||||
}
|
||||
|
||||
var raw *C.char
|
||||
if p.cfg.ProofType == message.ProofTypeBatch {
|
||||
raw = C.get_batch_vk()
|
||||
} else if p.cfg.ProofType == message.ProofTypeChunk {
|
||||
raw = C.get_chunk_vk()
|
||||
}
|
||||
|
||||
if raw != nil {
|
||||
p.vk = C.GoString(raw) // cache it
|
||||
}
|
||||
|
||||
return p.vk
|
||||
}
|
||||
|
||||
// ProveBatch call rust ffi to generate batch proof.
|
||||
func (p *ProverCore) ProveBatch(taskID string, chunkInfos []*message.ChunkInfo, chunkProofs []*message.ChunkProof) (*message.BatchProof, error) {
|
||||
if p.cfg.ProofType != message.ProofTypeBatch {
|
||||
@@ -68,6 +91,11 @@ func (p *ProverCore) ProveBatch(taskID string, chunkInfos []*message.ChunkInfo,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !p.checkChunkProofs(chunkProofsByt) {
|
||||
return nil, fmt.Errorf("Non-match chunk protocol: task-id = %s", taskID)
|
||||
}
|
||||
|
||||
proofByt := p.proveBatch(chunkInfosByt, chunkProofsByt)
|
||||
|
||||
err = p.mayDumpProof(taskID, proofByt)
|
||||
@@ -112,6 +140,20 @@ func (p *ProverCore) TracesToChunkInfo(traces []*types.BlockTrace) (*message.Chu
|
||||
return chunkInfo, json.Unmarshal(chunkInfoByt, chunkInfo)
|
||||
}
|
||||
|
||||
func (p *ProverCore) checkChunkProofs(chunkProofsByt []byte) bool {
|
||||
chunkProofsStr := C.CString(string(chunkProofsByt))
|
||||
|
||||
defer func() {
|
||||
C.free(unsafe.Pointer(chunkProofsStr))
|
||||
}()
|
||||
|
||||
log.Info("Start to check chunk proofs ...")
|
||||
valid := C.check_chunk_proofs(chunkProofsStr)
|
||||
log.Info("Finish checking chunk proofs!")
|
||||
|
||||
return valid != 0
|
||||
}
|
||||
|
||||
func (p *ProverCore) proveBatch(chunkInfosByt []byte, chunkProofsByt []byte) []byte {
|
||||
chunkInfosStr := C.CString(string(chunkInfosByt))
|
||||
chunkProofsStr := C.CString(string(chunkProofsByt))
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package core_test
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"io"
|
||||
@@ -22,9 +23,12 @@ import (
|
||||
|
||||
var (
|
||||
paramsPath = flag.String("params", "/assets/test_params", "params dir")
|
||||
assetsPath = flag.String("assets", "/assets/test_assets", "assets dir")
|
||||
proofDumpPath = flag.String("dump", "/assets/proof_data", "the path proofs dump to")
|
||||
tracePath1 = flag.String("trace1", "/assets/traces/1_transfer.json", "chunk trace 1")
|
||||
tracePath2 = flag.String("trace2", "/assets/traces/10_transfer.json", "chunk trace 2")
|
||||
batchVkPath = flag.String("batch-vk", "/assets/test_assets/agg_vk.vkey", "batch vk")
|
||||
chunkVkPath = flag.String("chunk-vk", "/assets/test_assets/chunk_vk.vkey", "chunk vk")
|
||||
)
|
||||
|
||||
func TestFFI(t *testing.T) {
|
||||
@@ -33,6 +37,7 @@ func TestFFI(t *testing.T) {
|
||||
chunkProverConfig := &config.ProverCoreConfig{
|
||||
DumpDir: *proofDumpPath,
|
||||
ParamsPath: *paramsPath,
|
||||
AssetsPath: *assetsPath,
|
||||
ProofType: message.ProofTypeChunk,
|
||||
}
|
||||
chunkProverCore, err := core.NewProverCore(chunkProverConfig)
|
||||
@@ -83,9 +88,13 @@ func TestFFI(t *testing.T) {
|
||||
as.NoError(err)
|
||||
t.Log("Generated and dumped chunk proof 2")
|
||||
|
||||
as.Equal(chunkProverCore.GetVk(), readVk(*chunkVkPath, as))
|
||||
t.Log("Chunk VKs are equal")
|
||||
|
||||
batchProverConfig := &config.ProverCoreConfig{
|
||||
DumpDir: *proofDumpPath,
|
||||
ParamsPath: *paramsPath,
|
||||
AssetsPath: *assetsPath,
|
||||
ProofType: message.ProofTypeBatch,
|
||||
}
|
||||
batchProverCore, err := core.NewProverCore(batchProverConfig)
|
||||
@@ -96,6 +105,9 @@ func TestFFI(t *testing.T) {
|
||||
_, err = batchProverCore.ProveBatch("batch_proof", chunkInfos, chunkProofs)
|
||||
as.NoError(err)
|
||||
t.Log("Generated and dumped batch proof")
|
||||
|
||||
as.Equal(batchProverCore.GetVk(), readVk(*batchVkPath, as))
|
||||
t.Log("Batch VKs are equal")
|
||||
}
|
||||
|
||||
func readChunkTrace(filePat string, as *assert.Assertions) []*types.BlockTrace {
|
||||
@@ -109,3 +121,12 @@ func readChunkTrace(filePat string, as *assert.Assertions) []*types.BlockTrace {
|
||||
|
||||
return []*types.BlockTrace{trace}
|
||||
}
|
||||
|
||||
func readVk(filePat string, as *assert.Assertions) string {
|
||||
f, err := os.Open(filePat)
|
||||
as.NoError(err)
|
||||
byt, err := io.ReadAll(f)
|
||||
as.NoError(err)
|
||||
|
||||
return base64.StdEncoding.EncodeToString(byt)
|
||||
}
|
||||
|
||||
@@ -177,6 +177,9 @@ func (r *Prover) fetchTaskFromCoordinator() (*store.ProvingTask, error) {
|
||||
// prepare the request
|
||||
req := &client.GetTaskRequest{
|
||||
TaskType: r.Type(),
|
||||
// we may not be able to get the vk at the first time, so we should pass vk to the coordinator every time we getTask
|
||||
// instead of passing vk when we login
|
||||
VK: r.proverCore.GetVk(),
|
||||
}
|
||||
|
||||
if req.TaskType == message.ProofTypeChunk {
|
||||
|
||||
@@ -51,7 +51,7 @@ func TestMain(m *testing.M) {
|
||||
}
|
||||
|
||||
func TestCoordinatorProverInteraction(t *testing.T) {
|
||||
// Start postgres docker containers.
|
||||
// Start postgres docker containers
|
||||
base.RunL2Geth(t)
|
||||
base.RunDBImage(t)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user