-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement challenger proving fault with zkVM proof (#386)
* feat(contracts): revive `getChallenge` method of `Colosseum` * feat(validator): prove fault with witness generator, zkVM prover * feat: verify zkVM program verification key * fix: launch kroma-challenger in devnet * chore(contracts): update bindings and snapshot * feat: use rpc client for proof fetcher, witness generator
- Loading branch information
Showing
23 changed files
with
633 additions
and
488 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package challenge | ||
|
||
import ( | ||
"context" | ||
"encoding/hex" | ||
"fmt" | ||
"math/big" | ||
"strings" | ||
|
||
"github.com/ethereum-optimism/optimism/op-service/client" | ||
"github.com/ethereum/go-ethereum/common" | ||
) | ||
|
||
type ZkEVMProofFetcher struct { | ||
rpc client.RPC | ||
} | ||
|
||
type ZkEVMProveResponse struct { | ||
FinalPair []byte `json:"final_pair"` | ||
Proof []byte `json:"proof"` | ||
} | ||
|
||
type ProofAndPair struct { | ||
Proof []*big.Int | ||
Pair []*big.Int | ||
} | ||
|
||
func NewZkEVMProofFetcher(rpc client.RPC) *ZkEVMProofFetcher { | ||
return &ZkEVMProofFetcher{rpc} | ||
} | ||
|
||
func (z *ZkEVMProofFetcher) FetchProofAndPair(ctx context.Context, trace string) (*ProofAndPair, error) { | ||
var output *ZkEVMProveResponse | ||
err := z.rpc.CallContext(ctx, &output, "prove", trace) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to request prove: %w", err) | ||
} | ||
|
||
proofAndPair := &ProofAndPair{ | ||
Proof: decode(output.Proof), | ||
Pair: decode(output.FinalPair), | ||
} | ||
|
||
return proofAndPair, nil | ||
} | ||
|
||
func decode(data []byte) []*big.Int { | ||
result := make([]*big.Int, len(data)/32) | ||
|
||
for i := 0; i < len(data)/32; i++ { | ||
// The best is data is given in Big Endian. | ||
for j := 0; j < 16; j++ { | ||
data[i*32+j], data[i*32+31-j] = data[i*32+31-j], data[i*32+j] | ||
} | ||
result[i] = new(big.Int).SetBytes(data[i*32 : (i+1)*32]) | ||
} | ||
|
||
return result | ||
} | ||
|
||
type ZkVMProofFetcher struct { | ||
rpc client.RPC | ||
} | ||
|
||
type HexBytes []byte | ||
|
||
type ZkVMProofResponse struct { | ||
RequestStatus RequestStatusType `json:"request_status"` | ||
VKeyHash common.Hash `json:"vkey_hash"` | ||
RequestID string `json:"request_id"` | ||
PublicValues HexBytes `json:"public_values"` | ||
Proof HexBytes `json:"proof"` | ||
} | ||
|
||
func NewZkVMProofFetcher(rpc client.RPC) *ZkVMProofFetcher { | ||
return &ZkVMProofFetcher{rpc} | ||
} | ||
|
||
func (z *ZkVMProofFetcher) Spec(ctx context.Context) (*SpecResponse, error) { | ||
var output *SpecResponse | ||
err := z.rpc.CallContext(ctx, &output, "spec") | ||
return output, err | ||
} | ||
|
||
func (z *ZkVMProofFetcher) RequestProve(ctx context.Context, blockHash string, l1Head string, witness string) (*RequestStatusType, error) { | ||
var output *RequestStatusType | ||
err := z.rpc.CallContext(ctx, &output, "requestProve", blockHash, l1Head, witness) | ||
return output, err | ||
} | ||
|
||
func (z *ZkVMProofFetcher) GetProof(ctx context.Context, blockHash string, l1Head string) (*ZkVMProofResponse, error) { | ||
var output *ZkVMProofResponse | ||
err := z.rpc.CallContext(ctx, &output, "getProof", blockHash, l1Head) | ||
return output, err | ||
} | ||
|
||
// UnmarshalJSON handles the conversion from a hex string to a byte array. | ||
func (h *HexBytes) UnmarshalJSON(data []byte) error { | ||
// Remove quotes around the hex string | ||
str := string(data) | ||
if len(str) >= 2 && str[0] == '"' && str[len(str)-1] == '"' { | ||
str = str[1 : len(str)-1] | ||
} | ||
|
||
// Decode the hex string to byte array | ||
str = strings.TrimPrefix(str, "0x") | ||
decoded, err := hex.DecodeString(str) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
*h = decoded | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package challenge | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/ethereum-optimism/optimism/op-service/client" | ||
"github.com/ethereum/go-ethereum/common" | ||
) | ||
|
||
const ( | ||
RequestNone RequestStatusType = "None" | ||
RequestProcessing RequestStatusType = "Processing" | ||
RequestCompleted RequestStatusType = "Completed" | ||
RequestFailed RequestStatusType = "Failed" | ||
) | ||
|
||
type WitnessGenerator struct { | ||
rpc client.RPC | ||
} | ||
|
||
type SpecResponse struct { | ||
Version string `json:"version"` | ||
SP1Version string `json:"sp1_version"` | ||
VKeyHash common.Hash `json:"vkey_hash"` | ||
} | ||
|
||
type RequestStatusType string | ||
|
||
type WitnessResponse struct { | ||
RequestStatus RequestStatusType `json:"status"` | ||
VKeyHash common.Hash `json:"vkey_hash"` | ||
Witness string `json:"witness"` | ||
} | ||
|
||
func NewWitnessGenerator(rpc client.RPC) *WitnessGenerator { | ||
return &WitnessGenerator{rpc} | ||
} | ||
|
||
func (w *WitnessGenerator) Spec(ctx context.Context) (*SpecResponse, error) { | ||
var output *SpecResponse | ||
err := w.rpc.CallContext(ctx, &output, "spec") | ||
return output, err | ||
} | ||
|
||
func (w *WitnessGenerator) RequestWitness(ctx context.Context, blockHash string, l1Head string) (*RequestStatusType, error) { | ||
var output *RequestStatusType | ||
err := w.rpc.CallContext(ctx, &output, "requestWitness", blockHash, l1Head) | ||
return output, err | ||
} | ||
|
||
func (w *WitnessGenerator) GetWitness(ctx context.Context, blockHash string, l1Head string) (*WitnessResponse, error) { | ||
var output *WitnessResponse | ||
err := w.rpc.CallContext(ctx, &output, "getWitness", blockHash, l1Head) | ||
return output, err | ||
} |
Oops, something went wrong.