diff --git a/cmd/flags/prover.go b/cmd/flags/prover.go index 409111149..8cd2ecac1 100644 --- a/cmd/flags/prover.go +++ b/cmd/flags/prover.go @@ -53,6 +53,16 @@ var ( "`lowerBound-upperBound` (e.g. `30m-1h`), testing purposes only", Category: proverCategory, } + ProverIdx = cli.UintFlag{ + Name: "proverIdx", + Value: 0, + Category: proverCategory, + } + TotalProvers = cli.UintFlag{ + Name: "totalProvers", + Value: 0, + Category: proverCategory, + } ) // All prover flags. @@ -64,4 +74,6 @@ var ProverFlags = MergeFlags(CommonFlags, []cli.Flag{ &MaxConcurrentProvingJobs, &Dummy, &RandomDummyProofDelay, + &ProverIdx, + &TotalProvers, }) diff --git a/prover/config.go b/prover/config.go index 92554da8d..b09e2dd42 100644 --- a/prover/config.go +++ b/prover/config.go @@ -27,6 +27,8 @@ type Config struct { Dummy bool RandomDummyProofDelayLowerBound *time.Duration RandomDummyProofDelayUpperBound *time.Duration + Idx uint + Total uint } // NewConfigFromCliContext creates a new config instance from command line flags. @@ -85,5 +87,7 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { Dummy: c.Bool(flags.Dummy.Name), RandomDummyProofDelayLowerBound: randomDummyProofDelayLowerBound, RandomDummyProofDelayUpperBound: randomDummyProofDelayUpperBound, + Idx: c.Uint(flags.ProverIdx.Name), + Total: c.Uint(flags.TotalProvers.Name), }, nil } diff --git a/prover/proof_producer/zkevm_cmd_producer.go b/prover/proof_producer/zkevm_cmd_producer.go new file mode 100644 index 000000000..f54f8ee6c --- /dev/null +++ b/prover/proof_producer/zkevm_cmd_producer.go @@ -0,0 +1,153 @@ +package producer + +import ( + "bytes" + "encoding/json" + "fmt" + "math/big" + "os" + "os/exec" + "path/filepath" + "strings" + "time" + + "github.com/cenkalti/backoff/v4" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/taikoxyz/taiko-client/bindings" +) + +// ZkevmCmdProducer is responsible for generating zk proofs from the given command line binary file. +type ZkevmCmdProducer struct { + CmdPath string + L2Endpoint string // a L2 execution engine's RPC endpoint +} + +// NewZkevmCmdProducer creates a new NewZkevmCmdProducer instance. +func NewZkevmCmdProducer( + cmdPath string, + l2Endpoint string, +) (*ZkevmCmdProducer, error) { + return &ZkevmCmdProducer{cmdPath, l2Endpoint}, nil +} + +// RequestProof implements the ProofProducer interface. +func (d *ZkevmCmdProducer) RequestProof( + opts *ProofRequestOptions, + blockID *big.Int, + meta *bindings.TaikoDataBlockMetadata, + header *types.Header, + resultCh chan *ProofWithHeader, +) error { + log.Info( + "Request proof from ZKEVM CMD", + "blockID", blockID, + "beneficiary", meta.Beneficiary, + "height", header.Number, + "hash", header.Hash(), + "cmd", d.CmdPath, + ) + + var ( + proof []byte + err error + ) + if err := backoff.Retry(func() error { + if proof, err = d.ExecProverCmd(opts.Height); err != nil { + log.Error("Execute prover cmd error", "error", err) + return err + } + + return nil + }, backoff.NewConstantBackOff(3*time.Second)); err != nil { + log.Error("Failed to generate proof", "error", err) + } + + resultCh <- &ProofWithHeader{ + BlockID: blockID, + Header: header, + Meta: meta, + ZkProof: proof, + } + + return nil +} + +type ProverCmdOutput struct { + Instances []string `json:"instances"` + Proof []byte `json:"proof"` +} + +func (d *ZkevmCmdProducer) ExecProverCmd(height *big.Int) ([]byte, error) { + start := time.Now() + cmd := exec.Command(d.CmdPath, d.L2Endpoint, height.String()) + + var stdout, stderr bytes.Buffer + + cmd.Stdout = &stdout + cmd.Stderr = &stderr + + if err := cmd.Run(); err != nil { + log.Info("Exec output", "stdout", stdout.String(), "stderr", stderr.String()) + return nil, err + } + + wd, err := os.Getwd() + if err != nil { + return nil, err + } + outputPath := filepath.Join(wd, fmt.Sprintf("./block-%s_proof.json", height)) + + log.Info("Exec prover cmd finished", "outputPath", outputPath, "time", time.Since(start)) + + if _, err := os.Stat(outputPath); err != nil { + return nil, err + } + + defer func() { + if err := os.Remove(outputPath); err != nil { + log.Warn("Remove prover cmd output file error", "error", err) + } + }() + + outputJSONBytes, err := os.ReadFile(outputPath) + if err != nil { + return nil, err + } + + var proverCmdOutput ProverCmdOutput + if err := json.Unmarshal(outputJSONBytes, &proverCmdOutput); err != nil { + return nil, err + } + + return d.outputToCalldata(&proverCmdOutput), nil +} + +func (d *ZkevmCmdProducer) outputToCalldata(output *ProverCmdOutput) []byte { + calldata := []byte{} + bufLen := len(output.Instances)*32 + len(output.Proof) + + for i := 0; i < len(output.Instances); i++ { + uint256Bytes := [32]byte{} + evenHexLen := len(output.Instances[i]) - 2 + (len(output.Instances[i]) % 2) + instanceHex := output.Instances[i][2:] + if len(instanceHex) < evenHexLen { + instanceHex = strings.Repeat("0", evenHexLen-len(instanceHex)) + instanceHex + } + instanceBytes := common.Hex2Bytes(instanceHex) + + for j := 0; j < len(instanceBytes); j++ { + uint256Bytes[31-j] = instanceBytes[len(instanceBytes)-1-j] + } + for k := 0; k < 32; k++ { + calldata = append(calldata, uint256Bytes[k]) + } + } + + for i := 0; i < len(output.Proof); i++ { + calldata = append(calldata, output.Proof...) + } + + return calldata[:bufLen] +} diff --git a/prover/proof_producer/zkevm_cmd_producer_test.go b/prover/proof_producer/zkevm_cmd_producer_test.go new file mode 100644 index 000000000..27e8b07b4 --- /dev/null +++ b/prover/proof_producer/zkevm_cmd_producer_test.go @@ -0,0 +1,26 @@ +package producer + +import ( + "encoding/json" + "os" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/require" +) + +func TestZkevmCmdProducerOutputToCalldata(t *testing.T) { + output, err := os.ReadFile("../../testutils/testdata/block-5_proof.json") + require.Nil(t, err) + + var ( + testCalldataHexHash = common.HexToHash("0xfbc74eec1aa02cadd59cf2fdfb8c311b199a4f83d0046fd20a1a53081bb0de22") + proverCmdOutput ProverCmdOutput + ) + require.Nil(t, json.Unmarshal(output, &proverCmdOutput)) + + calldata := new(ZkevmCmdProducer).outputToCalldata(&proverCmdOutput) + + require.Equal(t, testCalldataHexHash, crypto.Keccak256Hash(calldata)) +} diff --git a/prover/proof_producer/zkevm_rpcd_producer.go b/prover/proof_producer/zkevm_rpcd_producer.go index a260e1a2b..5dc2ec8f2 100644 --- a/prover/proof_producer/zkevm_rpcd_producer.go +++ b/prover/proof_producer/zkevm_rpcd_producer.go @@ -1,26 +1,73 @@ package producer import ( + "bytes" + "encoding/json" "errors" + "fmt" + "io" "math/big" "net/http" + "strings" + "time" + "github.com/cenkalti/backoff/v4" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/taikoxyz/taiko-client/bindings" ) var ( - errRpcdUnhealthy = errors.New("ZKEVM RPCD endpoint is unhealthy") + errRpcdUnhealthy = errors.New("ZKEVM RPCD endpoint is unhealthy") + errProofGenerating = errors.New("proof is generating") ) +// ZkevmRpcdProducer is responsible for requesting zk proofs from the given proverd endpoint. type ZkevmRpcdProducer struct { - RpcdEndpoint string - Param string // parameter file to use - L2Endpoint string // a L2 execution engine's RPC endpoint - Retry bool // retry proof computation if error + RpcdEndpoint string // a proverd RPC endpoint + Param string // parameter file to use + L2Endpoint string // a L2 execution engine's RPC endpoint + Retry bool // retry proof computation if error + CustomProofHook func() ([]byte, error) // only for testing purposes } +// RequestProofBody represents the JSON body for requesting the proof. +type RequestProofBody struct { + JsonRPC string `json:"jsonrpc"` + ID *big.Int `json:"id"` + Method string `json:"method"` + Params []*RequestProofBodyParam `json:"params"` +} + +// RequestProofBody represents the JSON body of RequestProofBody's `param` field. +type RequestProofBodyParam struct { + Circuit string `json:"circuit"` + Block *big.Int `json:"block"` + RPC string `json:"rpc"` + Retry bool `json:"retry"` + Param string `json:"param"` + VerifyProof bool `json:"verify_proof"` + Mock bool `json:"mock"` + Aggregate bool `json:"aggregate"` +} + +// RequestProofBodyResponse represents the JSON body of the response of the proof requests. +type RequestProofBodyResponse struct { + JsonRPC string `json:"jsonrpc"` + ID *big.Int `json:"id"` + Result *RpcdOutput `json:"result"` +} + +// RpcdOutput represents the JSON body of RequestProofBodyResponse's `result` field. +type RpcdOutput struct { + Circuit struct { + Instances []string `json:"instance"` + Proof string `json:"proof"` + } `json:"circuit"` +} + +// NewZkevmRpcdProducer creates a new `ZkevmRpcdProducer` instance. func NewZkevmRpcdProducer( rpcdEndpoint string, param string, @@ -47,21 +94,144 @@ func (d *ZkevmRpcdProducer) RequestProof( resultCh chan *ProofWithHeader, ) error { log.Info( - "Request proof from ZKEVM RPCD service", + "Request proof from zkevm-chain proverd service", "blockID", blockID, "beneficiary", meta.Beneficiary, "height", header.Number, "hash", header.Hash(), ) - // TODO: call zkevm RPCD to get a proof. - go func() { - resultCh <- &ProofWithHeader{ - BlockID: blockID, - Header: header, - Meta: meta, - ZkProof: []byte{0x00}, - } - }() + var ( + proof []byte + err error + ) + if d.CustomProofHook != nil { + proof, err = d.CustomProofHook() + } else { + proof, err = d.callProverDaemon(opts) + } + if err != nil { + return err + } + + resultCh <- &ProofWithHeader{ + BlockID: blockID, + Header: header, + Meta: meta, + ZkProof: proof, + } + return nil } + +// callProverDaemon keeps polling the proverd service to get the requested proof. +func (d *ZkevmRpcdProducer) callProverDaemon(opts *ProofRequestOptions) ([]byte, error) { + var ( + proof []byte + start = time.Now() + ) + if err := backoff.Retry(func() error { + output, err := d.requestProof(opts) + if err != nil { + log.Error("Failed to request proof", "height", opts.Height, "err", err, "endpoint", d.RpcdEndpoint) + return err + } + + log.Info("Request proof", "height", opts.Height, "output", output) + + if output == nil { + return errProofGenerating + } + proof = d.outputToCalldata(output) + log.Info("Proof generated", "height", opts.Height, "time", time.Since(start)) + return nil + }, backoff.NewConstantBackOff(10*time.Second)); err != nil { + return nil, err + } + return proof, nil +} + +// requestProof sends a RPC request to proverd to try to get the requested proof. +func (d *ZkevmRpcdProducer) requestProof(opts *ProofRequestOptions) (*RpcdOutput, error) { + reqBody := RequestProofBody{ + JsonRPC: "2.0", + ID: common.Big1, + Method: "proof", + Params: []*RequestProofBodyParam{{ + Circuit: "pi", + Block: opts.Height, + RPC: d.L2Endpoint, + Retry: true, + Param: d.Param, + VerifyProof: true, + Mock: false, + Aggregate: false, + }}, + } + + jsonValue, err := json.Marshal(reqBody) + if err != nil { + return nil, err + } + + res, err := http.Post(d.RpcdEndpoint, "application/json", bytes.NewBuffer(jsonValue)) + if err != nil { + return nil, err + } + + defer res.Body.Close() + if res.StatusCode != http.StatusOK { + return nil, fmt.Errorf("failed to request proof, id: %d, statusCode: %d", opts.Height, res.StatusCode) + } + + resBytes, err := io.ReadAll(res.Body) + if err != nil { + return nil, err + } + + var output RequestProofBodyResponse + if err := json.Unmarshal(resBytes, &output); err != nil { + return nil, err + } + + return output.Result, nil +} + +// outputToCalldata converts the response data to the proof bytes which will be +// needed for verification contract. +func (d *ZkevmRpcdProducer) outputToCalldata(output *RpcdOutput) []byte { + calldata := []byte{} + data := output.Circuit + bufLen := len(data.Instances)*32 + len(data.Proof) + + for i := 0; i < len(data.Instances); i++ { + uint256Bytes := [32]byte{} + evenHexLen := len(data.Instances[i]) - 2 + (len(data.Instances[i]) % 2) + instanceHex := data.Instances[i][2:] + if len(instanceHex) < evenHexLen { + instanceHex = strings.Repeat("0", evenHexLen-len(instanceHex)) + instanceHex + } + instanceBytes := common.Hex2Bytes(instanceHex) + + for j := 0; j < len(instanceBytes); j++ { + uint256Bytes[31-j] = instanceBytes[len(instanceBytes)-1-j] + } + for k := 0; k < 32; k++ { + calldata = append(calldata, uint256Bytes[k]) + } + } + + evenHexLen := len(data.Proof) - 2 + (len(data.Proof) % 2) + proofBytesHex := data.Proof[2:] + if len(proofBytesHex) < evenHexLen { + proofBytesHex = strings.Repeat("0", evenHexLen-len(proofBytesHex)) + proofBytesHex + } + proofBytes := common.Hex2Bytes(proofBytesHex) + calldata = append(calldata, proofBytes...) + + for i := len(calldata); i < bufLen; i++ { + calldata = append(calldata, byte(0)) + } + + return calldata[:bufLen] +} diff --git a/prover/proof_producer/zkevm_rpcd_producer_test.go b/prover/proof_producer/zkevm_rpcd_producer_test.go index 7e7ae7351..731928086 100644 --- a/prover/proof_producer/zkevm_rpcd_producer_test.go +++ b/prover/proof_producer/zkevm_rpcd_producer_test.go @@ -1,11 +1,14 @@ package producer import ( + "encoding/json" + "os" "testing" "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/require" "github.com/taikoxyz/taiko-client/bindings" ) @@ -14,9 +17,13 @@ func TestNewZkevmRpcdProducer(t *testing.T) { _, err := NewZkevmRpcdProducer("http://localhost:28551", "", "", false) require.EqualError(t, err, errRpcdUnhealthy.Error()) - dummyZKEvmProducer, err := NewZkevmRpcdProducer("http://localhost:18545", "", "", false) + dummpyZkevmRpcdProducer, err := NewZkevmRpcdProducer("http://localhost:18545", "", "", false) require.Nil(t, err) + dummpyZkevmRpcdProducer.CustomProofHook = func() ([]byte, error) { + return []byte{0}, nil + } + resCh := make(chan *ProofWithHeader, 1) blockID := common.Big32 @@ -36,7 +43,7 @@ func TestNewZkevmRpcdProducer(t *testing.T) { MixDigest: randHash(), Nonce: types.BlockNonce{}, } - require.Nil(t, dummyZKEvmProducer.RequestProof( + require.Nil(t, dummpyZkevmRpcdProducer.RequestProof( &ProofRequestOptions{}, blockID, &bindings.TaikoDataBlockMetadata{}, @@ -49,3 +56,17 @@ func TestNewZkevmRpcdProducer(t *testing.T) { require.Equal(t, res.Header, header) require.NotEmpty(t, res.ZkProof) } + +var testCalldataHexHash = "0xf50afda3076f7102e4d7d20fc82856b47d8f357d5007ccd1b541fa4b42ba7cba" + +func TestZkevmRpcdProducerOutputToCalldata(t *testing.T) { + output, err := os.ReadFile("../../testutils/testdata/zkchain_proof.json") + require.Nil(t, err) + + var zkevmRpcdOutput RequestProofBodyResponse + require.Nil(t, json.Unmarshal(output, &zkevmRpcdOutput)) + + calldata := new(ZkevmRpcdProducer).outputToCalldata(zkevmRpcdOutput.Result) + + require.Equal(t, common.HexToHash(testCalldataHexHash), crypto.Keccak256Hash(calldata)) +} diff --git a/prover/proof_submitter/invalid_proof_submitter.go b/prover/proof_submitter/invalid_proof_submitter.go index d38fecb00..8efa7b0ba 100644 --- a/prover/proof_submitter/invalid_proof_submitter.go +++ b/prover/proof_submitter/invalid_proof_submitter.go @@ -91,7 +91,7 @@ func (s *InvalidProofSubmitter) SubmitProof( "blockID", proofWithHeader.BlockID, "beneficiary", proofWithHeader.Meta.Beneficiary, "hash", proofWithHeader.Header.Hash(), - "proof", proofWithHeader.ZkProof, + "proof", common.Bytes2Hex(proofWithHeader.ZkProof), ) var ( blockID = proofWithHeader.BlockID diff --git a/prover/proof_submitter/valid_proof_submitter.go b/prover/proof_submitter/valid_proof_submitter.go index 99825ac46..764cc6ba9 100644 --- a/prover/proof_submitter/valid_proof_submitter.go +++ b/prover/proof_submitter/valid_proof_submitter.go @@ -100,7 +100,7 @@ func (s *ValidProofSubmitter) SubmitProof( "blockID", proofWithHeader.BlockID, "beneficiary", proofWithHeader.Meta.Beneficiary, "hash", proofWithHeader.Header.Hash(), - "proof", proofWithHeader.ZkProof, + "proof", common.Bytes2Hex(proofWithHeader.ZkProof), ) var ( blockID = proofWithHeader.BlockID diff --git a/prover/prover.go b/prover/prover.go index a17defd29..883b7dcfb 100644 --- a/prover/prover.go +++ b/prover/prover.go @@ -95,7 +95,7 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { } p.protocolConfigs = &protocolConfigs - log.Info("Protocol configs", "configs", p.protocolConfigs) + log.Info("Protocol configs", "configs", p.protocolConfigs, "totalProver", p.cfg.Total, "proverIdx", p.cfg.Idx) p.submitProofTxMutex = &sync.Mutex{} p.txListValidator = txListValidator.NewTxListValidator( @@ -268,6 +268,19 @@ func (p *Prover) onBlockProposed( handleBlockProposedEvent := func() error { defer func() { <-p.proposeConcurrencyGuard }() + log.Info( + "Check proposed block", + "totalProver", p.cfg.Total, + "proverIdx", p.cfg.Idx, + ) + + if p.cfg.Total > 0 { + if event.Id.Uint64()%uint64(p.cfg.Total) != uint64(p.cfg.Idx) { + log.Info("Ignore proposed block", "blockID", event.Id, "idx", p.cfg.Idx, "total", p.cfg.Total) + return nil + } + } + // Check whether the block has been verified. isVerified, err := p.isBlockVerified(event.Id) if err != nil { diff --git a/testutils/testdata/block-5_proof.json b/testutils/testdata/block-5_proof.json new file mode 100644 index 000000000..61cd232fd --- /dev/null +++ b/testutils/testdata/block-5_proof.json @@ -0,0 +1 @@ +{"instances":["0x101","0x7d6fea5a2ec7de4f8ad149ee45e7f69f0993d672ed4af3eaf6b288d6ea1cdb3","0xa7","0x8d3152434aeef619d040e5af9f52f53ac448fa790574c2837cca4fab02e3cc","0x68f992ffe139695e56ab109a0e4a8199588eb5e262720f4e8980e44ab2980f6"],"proof":[45,139,232,183,176,204,244,27,25,119,31,104,82,182,26,120,99,162,127,227,219,66,89,204,129,246,79,177,250,135,23,63,27,16,176,166,235,134,215,51,65,239,34,199,46,36,116,176,43,5,25,108,133,124,63,214,70,161,149,48,27,3,116,17,12,168,100,180,191,5,254,8,206,122,33,116,6,131,85,178,60,161,225,65,160,180,39,167,174,28,86,91,69,13,232,209,36,46,134,43,110,228,112,75,217,154,144,117,152,62,12,90,145,6,55,241,206,35,75,214,66,85,84,229,146,240,232,118,10,36,233,91,144,126,80,163,77,179,223,90,202,129,248,155,226,33,71,175,88,199,142,172,39,104,3,220,176,95,88,248,18,25,179,254,109,89,63,230,164,74,230,161,20,44,2,131,181,79,53,224,54,210,198,162,85,79,109,32,154,4,134,187,28,99,71,174,52,51,251,186,84,164,54,207,30,255,89,181,231,9,135,194,212,196,201,237,233,80,1,119,157,71,123,165,9,203,83,123,23,156,174,11,130,124,226,50,176,113,89,81,7,57,228,12,74,15,81,7,28,141,65,217,183,188,157,228,17,24,83,92,189,242,92,33,98,214,15,227,113,195,86,146,246,199,17,239,151,71,231,91,79,145,137,227,80,105,152,190,4,100,242,125,253,63,10,4,2,18,138,90,235,217,23,147,167,165,195,153,57,158,138,203,238,184,232,148,82,88,23,96,29,244,170,105,245,242,76,225,135,179,29,248,9,83,83,111,183,230,48,78,234,4,145,97,80,5,235,145,113,99,226,194,23,178,37,36,163,36,180,197,140,236,153,255,49,86,230,142,155,138,247,60,255,170,5,6,174,206,139,148,68,131,12,103,40,2,167,99,175,186,93,61,22,188,168,4,32,75,245,63,80,73,225,26,73,227,8,100,118,122,17,198,2,200,132,37,16,9,137,127,59,16,201,213,253,156,56,146,26,85,182,246,72,218,92,219,29,55,39,173,176,95,104,252,188,183,148,128,11,194,11,173,138,161,164,76,34,93,94,219,72,188,116,205,142,94,199,175,240,184,248,28,47,154,233,182,57,168,195,18,3,102,153,29,69,62,33,222,234,18,123,4,45,108,105,118,41,37,123,99,93,230,245,58,9,13,158,101,103,122,220,39,0,137,5,252,240,35,123,146,37,227,166,73,66,58,43,88,63,237,240,8,87,33,131,0,115,84,148,56,120,131,245,154,26,251,120,61,88,138,240,22,25,201,212,112,210,98,49,68,199,108,84,235,14,47,135,228,109,194,186,31,255,64,232,10,2,158,36,249,182,183,79,246,69,228,170,101,92,102,248,214,172,3,122,186,66,17,161,11,231,208,117,236,215,35,34,217,22,241,100,15,207,240,68,46,3,90,122,125,41,131,230,248,212,81,56,219,83,123,135,219,67,20,74,210,50,177,227,253,6,33,118,175,5,254,22,166,197,120,190,187,154,240,40,154,61,224,187,43,49,114,218,109,110,132,174,26,14,102,75,182,37,136,25,185,231,165,179,52,117,141,186,247,249,97,138,190,29,57,88,216,100,149,68,76,72,69,189,20,159,58,24,62,16,246,31,75,212,222,222,54,167,117,117,32,243,235,231,171,3,130,230,88,27,20,110,33,127,50,12,147,36,219,89,187,42,165,238,247,129,98,37,225,168,215,81,78,32,13,64,45,34,207,122,39,69,211,121,231,64,127,201,72,234,198,72,104,29,247,206,94,148,77,248,189,153,240,186,76,32,128,241,52,207,170,54,135,226,229,135,51,26,154,172,191,58,248,128,57,39,120,157,208,81,81,223,103,0,99,32,140,214,104,230,41,250,36,209,166,152,87,227,128,132,238,215,122,253,86,230,130,3,79,152,233,227,232,17,70,119,113,39,39,244,228,224,55,252,27,247,230,202,33,6,198,86,145,144,168,126,164,201,176,17,21,13,193,6,5,198,92,4,0,138,126,89,232,20,199,185,100,104,153,201,248,2,199,85,241,29,238,150,1,31,7,44,226,170,225,22,140,107,219,188,108,33,14,59,220,78,151,195,65,40,57,99,169,206,248,137,71,183,121,156,131,158,227,14,249,163,50,187,168,80,113,109,94,10,47,18,154,219,229,206,21,208,186,5,122,54,90,131,219,28,71,130,245,43,13,2,40,98,84,154,150,71,37,146,21,150,139,175,186,249,241,151,139,19,108,255,28,215,236,12,117,21,164,144,202,255,7,29,215,25,103,154,7,213,24,16,66,110,19,23,86,253,128,91,108,223,194,100,163,38,202,227,223,63,2,210,32,119,39,40,95,235,251,253,72,122,57,94,239,233,121,188,70,222,182,68,195,176,91,18,191,49,31,32,94,119,93,81,135,84,134,23,241,162,159,15,61,41,217,52,99,255,4,78,26,201,122,181,6,134,237,174,177,161,41,146,247,103,242,97,39,8,160,16,41,240,151,168,79,82,148,236,142,154,104,180,53,155,82,204,220,35,116,132,33,90,142,79,94,78,120,59,214,4,57,4,93,50,243,90,225,94,62,80,71,214,251,148,193,120,39,16,192,1,66,205,86,8,234,78,13,220,155,124,8,113,102,34,93,34,5,60,123,248,218,223,28,33,209,214,150,145,141,221,36,14,10,42,162,74,89,225,45,90,179,234,137,136,99,8,82,180,121,11,97,125,110,2,94,208,114,154,162,118,93,93,223,32,138,138,69,252,142,183,225,110,119,80,180,49,216,39,31,136,15,171,230,98,87,85,195,254,162,229,172,175,107,49,221,48,83,192,150,29,27,194,85,246,53,31,100,218,2,44,93,243,18,63,128,203,227,253,162,153,78,171,36,216,220,255,195,68,222,215,103,79,165,180,88,19,114,1,210,35,23,34,234,250,7,44,20,71,116,252,96,165,62,50,12,196,170,22,193,178,231,238,120,214,240,23,165,128,107,31,216,130,208,9,216,58,8,244,241,165,64,254,34,129,183,254,185,151,104,168,213,24,169,197,2,236,172,213,231,59,100,252,142,15,161,22,7,158,24,225,38,131,105,38,234,69,156,172,190,126,92,55,162,44,185,165,253,108,39,192,116,198,4,181,132,24,248,45,126,63,224,136,236,95,116,181,208,219,111,242,165,148,62,182,165,31,224,231,90,155,10,226,176,111,168,4,4,243,8,27,13,103,186,151,212,60,227,57,82,93,188,10,0,1,52,5,103,156,213,199,178,97,244,39,186,74,81,98,30,118,71,11,163,168,106,248,216,35,35,196,25,48,188,119,180,58,117,212,173,179,184,241,53,162,164,32,210,215,27,223,206,129,32,16,78,40,20,140,238,237,211,152,227,7,104,240,166,90,173,95,131,105,91,109,60,243,13,226,11,1,229,110,254,158,225,5,129,232,7,43,195,112,49,40,68,234,178,10,213,166,166,200,95,196,83,103,7,199,252,214,222,83,75,94,191,16,214,18,155,7,231,205,53,65,91,91,73,159,165,104,6,28,67,191,127,251,159,215,221,5,187,230,42,136,69,223,24,43,206,41,230,125,95,19,147,21,25,116,206,216,210,129,33,197,51,61,211,142,45,47,105,66,199,202,79,20,23,51,120,192,211,28,149,188,112,89,75,250,199,39,253,123,242,186,37,164,37,212,101,29,208,201,36,52,164,199,188,21,48,97,13,16,149,43,189,89,76,189,246,52,241,69,127,115,34,182,100,16,115,125,246,51,199,158,221,243,177,151,174,150,223,206,243,69,128,28,204,44,22,157,203,99,92,64,80,52,136,211,0,87,143,45,138,242,160,220,161,102,12,179,75,88,96,117,85,111,156,29,39,135,24,186,246,92,52,34,95,220,39,251,183,201,228,79,88,7,212,53,126,118,177,10,39,144,158,175,52,88,84,38,191,12,237,96,231,247,199,190,115,46,223,134,243,100,158,153,2,185,78,123,153,190,21,205,97,127,136,94,225,73,28,32,12,9,185,222,221,91,174,32,170,237,86,54,248,220,112,85,193,150,74,105,176,150,136,192,31,78,254,187,210,39,7,27,176,182,88,36,19,3,186,103,215,245,99,95,158,6,28,161,175,124,177,202,210,242,73,72,82,55,156,79,213,187,231,30,194,31,247,18,0,225,3,224,56,150,69,46,196,243,68,189,29,171,73,119,249,178,94,221,68,24,169,176,45,148,185,41,161,22,241,128,108,26,163,40,76,154,120,80,242,172,206,140,33,164,169,98,214,83,141,168,90,161,170,155,47,51,194,5,204,117,140,185,248,104,100,21,151,19,83,120,240,63,147,10,32,162,7,216,12,7,139,243,98,17,137,78,241,45,1,6,175,45,140,53,155,203,212,91,52,174,195,100,20,60,110,7,27,29,43,52,151,164,78,102,55,50,193,61,84,224,187,23,243,100,210,131,95,126,166,229,25,19,127,146,24,220,91,252,146,83,202,39,250,5,189,92,157,102,200,234,103,27,171,33,17,58,1,112,36,13,111,107,181,17,189,41,49,205,105,60,5,111,215,182,186,86,93,187,150,38,247,27,135,55,102,43,45,197,127,204,246,236,42,185,94,76,46,120,220,53,218,213,141,63,142,50,162,42,201,138,131,7,251,44,127,189,151,28,59,128,51,92,216,168,89,146,95,71,229,88,67,221,111,191,197,229,19,183,171,110,181,192,191,59,167,55,232,252,221,38,193,89,75,63,168,17,169,164,53,146,126,127,112,211,21,25,147,68,153,161,75,104,228,175,181,90,148,166,141,30,17,32,126,134,184,202,106,181,251,154,63,85,118,98,27,102,210,26,149,32,30,138,127,157,182,212,116,111,167,48,96,81,190,44,163,63,87,190,17,254,93,228,164,189,58,88,107,255,33,96,129,77,7,22,48,34,89,14,33,214,56,159,22,94,9,10,80,249,184,8,37,51,157,195,49,222,186,15,245,42,89,197,97,163,131,252,182,165,113,6,193,163,90,119,95,23,101,27,129,252,226,0,28,125,99,66,184,21,56,52,22,122,52,26,127,84,102,37,18,113,12,117,69,115,46,154,14,46,129,11,52,114,35,180,130,39,163,206,65,44,221,226,84,202,143,51,141,109,71,137,202,31,54,243,36,106,127,170,250,15,252,0,150,188,114,4,169,117,45,189,130,236,67,181,98,34,178,155,240,109,44,173,93,56,158,188,80,3,114,8,208,180,148,13,44,15,91,172,138,195,177,28,106,172,91,82,7,142,99,166,141,173,19,15,177,53,208,66,111,27,221,112,171,161,116,25,150,83,50,185,96,101,137,103,131,53,139,78,131,150,190,144,172,19,83,19,49,55,82,88,162,46,233,249,125,197,38,33,56,9,192,45,19,142,30,13,41,133,103,213,76,140,242,79,63,159,215,1,153,81,69,118,180,183,154,11,71,69,89,2,208,189,28,184,76,241,244,189,237,9,95,12,168,236,131,109,143,77,157,140,218,143,108,75,26,221,167,138,90,98,13,9,248,241,146,130,7,222,118,249,94,148,239,42,117,160,19,17,236,112,229,115,88,240,219,111,26,204,59,181,59,182,44,19,98,241,151,58,204,65,74,118,119,89,30,169,61,96,80,224,96,171,153,170,211,94,105,108,236,47,214,117,38,86,213,12,229,98,174,67,168,183,67,190,255,71,48,225,110,109,246,225,204,194,46,43,67,134,181,44,152,54,156,151,87,119,152,41,252,0,158,3,138,105,191,238,231,176,202,245,186,162,71,186,16,213,248,175,254,80,173,230,253,58,64,46,55,154,39,10,48,1,14,61,132,12,7,193,218,216,122,240,155,222,99,44,185,216,168,250,251,237,113,30,120,62,99,139,195,186,124,44,232,22,158,172,78,117,32,190,237,38,249,185,20,245,52,247,192,102,247,162,217,212,114,78,187,213,23,178,213,171,251,17,187,17,226,105,122,241,155,226,191,50,206,161,250,64,175,105,31,225,59,12,104,130,188,69,152,72,114,219,249,205,84,14,242,162,43,169,112,8,114,118,60,4,164,215,115,197,70,124,104,70,70,130,94,88,4,4,94,114,98,214,78,241,233,16,146,251,33,77,182,213,58,180,103,185,166,172,215,111,143,72,1,169,205,121,255,242,217,144,121,169,54,169,146,10,33,32,159,73,16,196,247,193,143,30,187,15,84,216,186,242,30,238,54,105,12,249,143,223,45,70,208,51,135,178,134,91,237,35,2,222,171,138,113,147,152,64,46,59,253,143,235,1,28,83,144,8,110,146,26,39,130,162,85,78,159,106,214,82,14,23,222,67,147,82,68,219,243,97,171,63,180,82,116,33,123,59,193,48,77,192,86,250,40,252,221,189,183,58,112,12,132,27,34,240,41,178,191,214,219,95,163,209,60,96,201,38,194,41,51,75,172,155,230,219,65,108,132,201,95,219,168,253,224,25,132,247,165,229,163,241,18,59,61,93,123,26,246,109,241,111,38,26,85,135,252,11,176,57,210,198,1,111,123,184,13,9,142,83,46,60,181,58,229,133,212,47,215,248,255,251,145,222,236,165,195,12,50,186,103,47,147,229,111,192,138,173,108,7,36,177,108,158,63,50,56,163,65,214,253,47,253,247,80,149,106,179,249,244,95,128,30,227,169,153,134,46,53,238,98,19,68,227,13,220,47,26,173,27,114,212,233,243,109,47,67,161,217,179,128,107,129,108,131,109,88,130,243,20,48,183,51,4,139,116,88,100,120,222,72,248,236,21,144,49,140,67,23,244,10,69,129,251,137,202,121,156,150,193,244,58,26,106,137,17,87,175,218,160,231,184,188,11,213,216,221,238,117,34,98,140,202,143,182,21,128,252,18,34,249,73,186,215,132,101,143,30,200,189,166,224,208,116,4,85,127,34,206,182,156,182,154,47,66,254,241,36,95,32,158,70,38,88,132,54,178,28,52,40,253,230,161,204,197,78,132,197,115,174,71,18,77,224,208,25,189,24,155,18,86,119,226,152,185,195,220,157,179,12,177,37,224,178,105,115,47,90,236,254,162,36,194,163,57,11,0,245,147,174,104,249,135,99,213,169,81,206,53,156,113,42,188,6,118,25,194,238,138,82,78,252,239,16,163,22,230,179,37,224,118,100,199,108,203,106,28,209,247,97,250,216,83,211,255,26,165,127,249,83,200,119,252,51,237,35,2,151,70,149,226,222,128,52,233,103,115,69,1,187,183,103,84,32,33,179,0,48,69,116,114,242,138,169,4,50,163,119,183,80,75,245,21,51,245,10,82,17,218,131,251,70,16,24,224,80,90,196,87,30,198,153,228,198,229,252,161,187,197,1,159,23,126,240,22,253,94,97,114,123,108,106,251,57,209,185,208,85,67,32,3,21,118,112,14,189,250,56,153,19,118,91,64,178,24,185,53,190,231,104,126,94,142,77,75,114,212,211,247,124,173,28,160,13,204,2,13,124,218,70,20,188,170,174,243,207,216,19,233,138,194,218,200,163,198,240,207,104,66,139,242,110,62,51,203,12,0,226,147,212,226,84,83,120,128,230,82,54,145,108,93,241,37,80,46,112,239,96,170,244,186,205,248,138,124,65,151,12,119,113,204,150,83,38,90,61,121,255,25,20,82,13,148,99,150,120,148,62,238,231,84,43,209,249,69,244,225,77,130,7,107,162,217,117,118,142,57,41,40,141,139,121,32,219,237,251,101,59,43,160,7,87,192,163,117,149,2,28,253,238,115,15,49,208,218,95,77,68,163,106,201,91,173,185,147,196,79,79,166,17,118,254,199,214,235,18,238,82,224,14,243,216,2,37,241,199,82,101,240,214,227,238,192,28,221,92,104,199,37,165,203,12,225,78,168,96,62,110,197,85,226,26,23,81,247,44,120,26,81,223,210,173,75,44,98,55,181,119,100,67,57,183,26,138,72,216,1,197,54,9,71,21,55,86,135,182,73,16,77,140,128,92,26,108,51,90,189,138,232,83,26,25,17,55,32,131,223,124,11,201,144,225,111,125,136,163,194,177,10,19,110,194,152,218,165,23,95,115,48,199,17,229,59,222,69,144,155,110,166,16,161,86,14,26,30,76,174,133,150,162,154,24,50,247,238,51,82,159,154,222,2,81,149,116,53,2,91,165,228,67,238,111,29,223,255,184,239,36,241,165,13,93,83,5,4,12,161,128,18,146,248,50,184,78,145,57,168,2,253,88,65,220,130,114,227,86,225,244,206,145,62,6,107,124,58,6,219,90,159,250,202,240,18,116,31,26,132,12,55,67,165,146,59,167,101,25,228,226,236,98,203,11,143,37,239,8,8,19,105,48,173,194,17,172,169,41,94,50,48,28,40,3,180,188,19,63,168,87,48,3,186,129,138,102,221,7,221,90,38,36,219,156,200,207,228,167,175,104,27,128,29,153,69,242,113,115,24,143,225,64,21,26,44,38,30,190,1,16,243,154,216,16,74,225,225,98,238,158,220,180,169,125,80,83,34,159,230,151,53,170,56,23,27,166,158,35,238,117,70,248,187,238,22,45,145,68,17,237,220,194,198,188,87,66,171,179,173,201,62,19,142,78,140,34,129,107,209,236,253,78,241,102,21,173,129]} \ No newline at end of file diff --git a/testutils/testdata/zkchain_proof.json b/testutils/testdata/zkchain_proof.json new file mode 100644 index 000000000..45394532a --- /dev/null +++ b/testutils/testdata/zkchain_proof.json @@ -0,0 +1,40 @@ +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "aggregation": { + "duration": 0, + "instance": [], + "k": 0, + "label": "pi-300000-a", + "proof": "0x", + "randomness": "0x" + }, + "circuit": { + "duration": 276176, + "instance": [ + "0x101", + "0x138441ed4bea3492374e1caa6f1dcc8a947ef58ec290d16cf8092905be8fc0bd", + "0xc3b", + "0x208afa142625879c94271d82cb04b3cde0c93641ad9f92ef6a593b0f8c8443f8", + "0x1b23eb43f1d78910deeead51dee8039294565db225c7cfc708a88ddc4a9f91f3" + ], + "k": 20, + "label": "pi-300000", + "proof": "0x278ded153590c76a42003e1a3e7bbfb0f19211bc2377a0902637dcc83b694d910028e4d5d41058312208d45a7f7ca736bb59171d5eca4bb3aa3180790dd07a99245bf820ba7460dcd2bb942e0e150305b173933c0cdb7219ee6273ea6abb87402c143c17c397feb2e0e8e0714da11965797e1308661f69932cd4451dbfa74085167114e1f18978090ba1077a2172c0e4d3ed5fabd570a8c4a5611a29eb55dfab1c5de7c6efdda8d5fadd48e28d68130051ad2858ae8931df88accf56692cbc2b0022336d94672043021050ecec9d3474745fae186e7536edec1d1e373ecc1c220a1a51374eee268110bac9595857c515352b7df0027fdd85739573edae695b34017f549a762859e1199cd0f6d6acd74653925730b4b9fe8931482e9a5a37eb95227c97bc8855c227fc9f4ae02a8cf9408bdc7b203a1c5bb36280418efa2578782d58b31f1c28940af0e3db232ecaf31f03571d45340205150022902602974c5320c7928eca8fd502177d2c4992ce39a9e3ab492f17beb21a89cadad4ff6b5f0b226fcd236b07f691d0776e8381f1eb38827e5219faaf4864b4c2bfa69aa0e45f18021769bb2a9caea749e047f504f694b6e1ebcfe1a387169edd88b867081c222b0533672c8937bab235f7b65744e043c8f1f090a60ecdee957f5765b566e94f286ceb1f7f2a9aa16c991aa6f2c0a09b051a028eeae2021779fe5da69ecd8b2e058d1fc940c49782b62907c7560e5a09c52709c801ae7b0d6f533c2c75467ebe0b14b34dca9f270cc2a84803c81c3b40bf52c9b33adee667c37e14d9066bb1b3073ee19f77b0c7659d07099116727bca7f6b5efb244be08a0c921fc0356a2baf04430bbc517927c8023e74ba61e9b1bbc2cd7bfc4b7b3f1e3410de000c63af1d1c683e5a60cbf83d5f482549d86bfe1a495ea58d35ed0e762ea4f15139fbe0681d1e7236df3df504d3c747c1506c534ce4f6c3f8a4a7fc63889188535cdafc58205800af17d1f5cabfbaad0dc8fe89081f81fab0653bd92da481fdac6a9e963d19fbf5fc74c7765bd5e18ed97ab32ae4823e29704d475b6b2ec09d2369351b0c17849f4fb1023dd277ab0d0875dd43f3dc79a0072661db1f4c7264ba48e3f367070150ef1dd85005318398fe00abfa39b51588c2ea6b5e7259559d53d4849b4b042e835e8b6037f6e9d15475106486b63e97e2933fa5e6aaf8ab7829b793b7481078be0955176a719cb025a1b97ef1310c7a219160a261268aee53ba33506f3f1e5bfebab60f5c328cd4c729f3d0ea66dea312640d0bf68acd592ae450e348ac257c9e9602950c60bd09ba656f5b638de3dddfcdcde83e8a0f381feb2d5e5b2e00a5dca9c97a0de1ef0dac1da5a62af8feadbfe16a1990c2d48b4d50e0f4b1af2185968f43b794c7c6b468758f3d18199671ba6f317cb6363bf93698b4982e9a2364493a1d5d7c12ff3237e2367f8d91a7aaa801fa29aa90818e920ae782379e02f1f1325f447b2f21522376c79fdf06db3d9b33b56dacb384c5c3ca121c57c01600dbbace1c93d1f1cc5af97502e8150fcae525d0a1d4f0bb32b2f2b4e72f79277b825dcf72cf2054fff0da188d26b93741421d68e9476e3cf12096e8774cde2d2a91994f0d09fa5cf6a117ff1012607407c851a63899acab8b39c083602f7626cb3f300f3022f61a97030c00f6e563982d77ec75ba2030c835e616328ec76b0b70852696a9d27a444ff30a08482a24c932abf7214ec063708352a4f46dc94e0cc7f0b6a4272f1c93bc84899c4e3befe0c0c060f8a1b9d4dad9cf23cc4e1b171d80bcef820ee9351a5e46ceb56b876592b4ddd22ddcbd4454e6d93316fbf36c16a805c6fc4e9df736bb1b13f9a1de9f08d884c582aab98fa4669cce753f7cdc1fb3eb2b7249497436bf6d288affb1f7e5d53c27feff9ec9c1aff091e4fb0e2918f9cc4fb73f21bd9776fc6afa12ae6ce675adec378a7485760a51b1f60158491f81b25ce32daeb66480f72f855e06b316ac319b0c380a5084ce5de521cef8bf1c2b07cb80d013cd6cb32b1461674f465d31faa4d50010d5b514e7340a6d791e113482d3a3e7f3083cad42853872934717e85554464904bc1ed7aaa1f3cc0bd02662865173cc1af2762d64dfe4b48cd5af094a3093c26b3cd629347377598444272ee87f9031909976a11781cec904d95cfc48c091f53bd8c851493cd98c3d8c2e834df54fb36b68043a38b6b6499a7d8320bcb98a62d7c6cc1531ea0ddc731c0d832801d04ef747776ca6ecbe36bfa241a53d092bff0328ca084a9bd1be349117af1c95f8760916478920125d94c4787cffc6cbcaeb2501339d14ea3548707e123d631817e2e0d3e9ff7d1a2da48dcc915bbdeb5c6b0739b09af427f7f4176a1cc18646f25fbf50a57104e61b9cde7c34f27a8cda14e9807505a7731a4d38c215ee08ba00ef0800068e4fe3cbf102c6dd96fa47b835fce4becc6df6457c79c10eb498c8c6235eaa980fac0d16ce8761913512d16f31e0979d7071ad5e67b2401ec698676985846ef07d778de0791f48de4f767b5f16e0cb3ff5ea528e96ff4f2e56c10333eb2b6ad95eafafe12f72357a5ea1c1ee615ec4754714ea424cbf31070daca28aa1dc0cfc6f41af34e1af1dc0b91e89a2c3c2358f3339ef37c3f7fd053f342fe444395376258352b1d3656ce3e7d72ee91c2ac072ac0ebc1c8189941eb569484b928b4d3f3e2c62d041b64453a5db338a6215ef28c899cc05aea5442a20543e92e1a68df04e69d377fb1029946ef8466e5940569e3ad4e3e0ec9b4b0e445b832584d1996dcf2edd7fb78e3eae8939e7d275d1ce9f418f889e6632bd22d4d7e72ab0365fcdaba96bfd3c26337028ad9f2aa2d8031099082ee01038d608e92de4e55351f6e495332bebe7306f57f8ae0373bae78cb4ae36826cbb6cbe0d2b9e68aa282273f985a7777075d99df9779f8f230f369afb0addb7d74e190502e0efbc5b0024357c50d382eef0cb1e8ed54ec1c5195b9dce9289f782f59c5b1f85db20cca34eedf47341fab2588ddfb6ce224aedb0c53159fae62cf5a5c6b9190788b13ba00ad4591f0fc90663f869f3862ce7c4d5cd90a682b4a646de08e3230516ebcaf786dd64f0a75f3f46f3aa808562b96d387f327716b3c34ea1071209a32e7e08121c9667f962e20da7c806a56e7ce840f413e95001abf82380f947132cf32a3c879b22fc4d88342b77656d6359ce3fbc53985a060eea19f9f0b75029e81c08c70ec9f0205e210567aff85725d8009125d2e97ef057531818db522d0f28d239c5db0e341fff78b014bc65d373c28c2b4672b3cbad39f298a823774f0409e206dadfcd7fe5b191d17d2c9638a846c5cae30faa8423dff7e81ec9f3df054c54e9be6bfaacefcc9f108b96cdd00c1f8a0065865eb0b5e876ccfd33d2242fcc7cb753fa9723eb619a3720125398cbbc9fe7ab3fb4d65107459e5c98de6f14fcb043eaa98b927e4703d17cb77ad3c2539e21e38a67751aa0d92fbfe192e5204739d5bad022327904d3512f1da7218be4595db0c22da093ec24ab89a5d334024c58dde366c314d733f965476ddd41da858aceffed8678d1027cea3b2bbf9e0a634529008e5de56e39bc98990814408447bf8ff10f43f19a782cff4a458af5304e06505f19f38d67a92f8522d7ff945ac5600547a2dad89878acf398c9876804d5a554b9237f673ef093a42910633f9e9171bd1f78d4db762906d434d6891f02d3c33eaacb97defb7699b21e3c430bf2d652891c426bb23ed6d70efc3332201200f8633f10d3c66ec5e846a16d03b711e46b101829c03e7172522b33423c1902a25a4b2e30b90b82942b7a6764c7ac4e8f1708d9b2e5da0d5e6648064e85d504bd16eb87691cf7a58d9480377c28c7c6c2f11d567a7c3c0b630bb24028adf1242e5dd8b4040f1e094c7dd77dc9531df82793a63c1d476c5f85e09fd3b95b4830487cea213f9a10cc3ec8b59dfac5e2be257679b8e3d3b41a4e33a04df6088e0644b1514743a3fdda56623ece87d8aa946389285092e1d0a62f5bae3748f7581e184b34a262ef00f5449c2971d598f733102ee98fd737329f6872ce67d4a27627e1458e9822feed2bedc6c239c7e8972e400774279416d0d7ba27896922690010c7cb7c70dc6bd597f369381fae2c9871c906ea2f1e8226c3310fd1e7546dc527313f06175782fe0eb84c427bd7e455cff99f7b3130b44b22202d0f7667ada8305fa180e77cad4e6ea0342959a8af17f046e879b8a85d618e4908965fa248720bbaa7aba93ae5c15092559ad6e9d4f0db441ef02dd18a5b1703b7e618d7274702b1a3fcc5b19b517b711409f04a9aeb2f945fc5ce0ff2b758e54e767f98ecfc1a20a78327f1edd20dfe36719a2f83c0d521de4c754f2b5e417ba662938487e22263639b666c62b53381ed1476bdaf97c1de9eb80b8095d423f8242d8e86369602d27e61f5828e25b5cc6536869d88073d6a91e2e79c35bfe81bb544e771587f147941e6998d20e9d6f59933318dc302389befdbf071736f9493222791f1b0b3142a72133fbdf083ddbf12fba8085cc0df781d566ddbe3f2b3591a5f7bc17cf7251ee83127c2a0bffe0a172af1d82f159ba0492291feb1a858ee96b680b5151325cdc59d78c5ca19d254bf50c8e40a986b0d5ac6d6a06080eb3f5e8d38901a8c11f060e6f1fbc4a164f027291957162f25c8b51cc34dbf91eca332527eef3c900e6e08809729440418dbff5d132ac6bf952156d5b895a3e35093dbe5a074105f2dce06d937fb94c56a5f62aa72fc6fe5f8582abe02adfd821d98b06f24d3e1781128bcbb0f898e70ed5b0a72ac4bfa608667fd2b418b6fad1a6815488acdd9e017125204fc980c7bd2c5fa5323df5b14c1df537161bc6b87013a429e8a4f2beb2fac45bf68c329f5901bf3bd368278a12c35a3b5384b29a22eb8d31b703d0ba31f89cc4cccdf60242a4c882746c5e57c61581a913fa29ef1df335b5012e3ca100a9f583d52062d15f5301286660947b9e8e30c0e1ffc0955a1af79dbbe9e21e61893bad1e7dbf562af8b1678454d12d01713076543152053ab2ed28ea06d6b2608cd08c69163b960407fa58d64a5fb18c051482aef70a5f66a87c45a39afc69a2bdee0e29de28beaa63a36ab4a3f9f1f5f63690ad74459c1bc9c2ff4ed49a8ce0beff55785fb17442226c29d82da9681419d9c624d22d3aa58992e2342de983719ed90454a06313b70e8017425850d495d04c62d7b65de39caf6594000d8232619a33023cf6c44f0b18a6a1e0c38162d7be034b7ae6a787520d1d41a5c39a0b5222de4652fbee0444e03f79c9474155fd945d9675cbedbdcab8c74727480899a", + "randomness": "0x" + }, + "config": { + "block_gas_limit": 300000, + "keccak_padding": 336000, + "max_bytecode": 24634, + "max_calldata": 105000, + "max_rws": 476052, + "max_txs": 40, + "min_k": 20, + "min_k_aggregation": 26, + "pad_to": 476052 + }, + "gas": 21000 + } +}