Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement challenger proving fault with zkVM proof #386

Merged
merged 6 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions kroma-bindings/bindings/colosseum.go

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions kroma-bindings/bindings/colosseum_more.go

Large diffs are not rendered by default.

19 changes: 4 additions & 15 deletions kroma-bindings/bindings/types.go
100644 → 100755

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions kroma-bindings/bindings/zkproofverifier.go

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions kroma-bindings/bindings/zkproofverifier_more.go

Large diffs are not rendered by default.

35 changes: 21 additions & 14 deletions kroma-chain-ops/genesis/testdata/allocs-l1.json

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions kroma-devnet/devnet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,6 @@ def devnet_deploy(paths):
'--outfile.rollup', paths.rollup_config_path
], cwd=paths.op_node_dir)

rollup_config = read_json(paths.rollup_config_path)
addresses = read_json(paths.addresses_json_path)

# Start the L2.
Expand All @@ -266,8 +265,6 @@ def devnet_deploy(paths):
# Print out the addresses being used for easier debugging.
l2_output_oracle = addresses['L2OutputOracleProxy']
log.info(f'Using L2OutputOracle {l2_output_oracle}')
batch_inbox_address = rollup_config['batch_inbox_address']
log.info(f'Using batch inbox {batch_inbox_address}')
colosseum = addresses['ColosseumProxy']
log.info(f'Using Colosseum {colosseum}')
validator_pool = addresses['ValidatorPoolProxy']
Expand All @@ -278,14 +275,13 @@ def devnet_deploy(paths):
log.info(f'Using AssetManager {asset_manager}')

log.info('Bringing up `kroma-node`, `kroma-batcher` and `kroma-validator`.')
run_command(['docker', 'compose', 'up', '-d', 'kroma-node', 'kroma-batcher', 'kroma-validator'], cwd=paths.ops_bedrock_dir, env={
run_command(['docker', 'compose', 'up', '-d', 'kroma-node', 'kroma-batcher', 'kroma-validator', 'kroma-challenger'], cwd=paths.ops_bedrock_dir, env={
'PWD': paths.ops_bedrock_dir,
'L2OO_ADDRESS': l2_output_oracle,
'COLOSSEUM_ADDRESS': colosseum,
'VALPOOL_ADDRESS': validator_pool,
'VALMGR_ADDRESS': validator_manager,
'ASSETMANAGER_ADDRESS': asset_manager,
'SEQUENCER_BATCH_INBOX_ADDRESS': batch_inbox_address
})

log.info("Deposit ETH into ValidatorPool contract to be a validator...")
Expand Down
147 changes: 0 additions & 147 deletions kroma-validator/challenge/fetcher.go

This file was deleted.

114 changes: 114 additions & 0 deletions kroma-validator/challenge/proof_fetcher.go
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
}
55 changes: 55 additions & 0 deletions kroma-validator/challenge/witness_generator.go
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
}
Loading
Loading