Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cli): add read voucher command
Browse files Browse the repository at this point in the history
GMKrieger committed Dec 11, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 48d1a28 commit 967c3fd
Showing 6 changed files with 466 additions and 0 deletions.
2 changes: 2 additions & 0 deletions cmd/cartesi-rollups-cli/root/read/read.go
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ import (
"github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/read/inputs"
"github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/read/notice"
"github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/read/notices"
"github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/read/voucher"
"github.com/spf13/cobra"
)

@@ -21,4 +22,5 @@ func init() {
Cmd.AddCommand(inputs.Cmd)
Cmd.AddCommand(notice.Cmd)
Cmd.AddCommand(notices.Cmd)
Cmd.AddCommand(voucher.Cmd)
}
57 changes: 57 additions & 0 deletions cmd/cartesi-rollups-cli/root/read/voucher/voucher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// (c) Cartesi and individual authors (see AUTHORS)
// SPDX-License-Identifier: Apache-2.0 (see LICENSE)

package voucher

import (
"encoding/json"
"fmt"

"github.com/Khan/genqlient/graphql"
"github.com/cartesi/rollups-node/pkg/readerclient"
"github.com/spf13/cobra"
)

var Cmd = &cobra.Command{
Use: "voucher",
Short: "Reads a voucher",
Example: examples,
Run: run,
}

const examples = `# Read voucher 5 from input 6:
cartesi-rollups-cli read voucher --voucher-index 5 --input-index 6`

var (
voucherIndex int
inputIndex int
graphqlEndpoint string
)

func init() {
Cmd.Flags().IntVar(&voucherIndex, "voucher-index", 0,
"index of the voucher")

cobra.CheckErr(Cmd.MarkFlagRequired("voucher-index"))

Cmd.Flags().IntVar(&inputIndex, "input-index", 0,
"index of the input")

cobra.CheckErr(Cmd.MarkFlagRequired("input-index"))

Cmd.Flags().StringVar(&graphqlEndpoint, "graphql-endpoint", "http://0.0.0.0:4000/graphql",
"address used to connect to graphql")
}

func run(cmd *cobra.Command, args []string) {
ctx := cmd.Context()
client := graphql.NewClient(graphqlEndpoint, nil)

resp, err := readerclient.GetVoucher(ctx, client, voucherIndex, inputIndex)
cobra.CheckErr(err)

val, err := json.MarshalIndent(resp, "", " ")
cobra.CheckErr(err)

fmt.Print(string(val))
}
23 changes: 23 additions & 0 deletions pkg/readerclient/generate/voucher.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
query getVoucher($voucherIndex: Int!, $inputIndex: Int!) {
voucher(voucherIndex: $voucherIndex, inputIndex: $inputIndex) {
index
payload
destination
proof {
validity {
inputIndexWithinEpoch
outputIndexWithinInput
outputHashesRootHash
vouchersEpochRootHash
noticesEpochRootHash
machineStateHash
outputHashInOutputHashesSiblings
outputHashesInEpochSiblings
}
context
}
input {
index
}
}
}
202 changes: 202 additions & 0 deletions pkg/readerclient/generated.go

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

1 change: 1 addition & 0 deletions pkg/readerclient/genqlient.yaml
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ operations:
- generate/notice.graphql
- generate/notices.graphql
- generate/input_notices.graphql
- generate/voucher.graphql
generated: generated.go
package: readerclient

181 changes: 181 additions & 0 deletions pkg/readerclient/voucher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// (c) Cartesi and individual authors (see AUTHORS)
// SPDX-License-Identifier: Apache-2.0 (see LICENSE)

package readerclient

import (
"context"
"fmt"

"github.com/Khan/genqlient/graphql"
"github.com/ethereum/go-ethereum/common/hexutil"
)

type Voucher struct {
// Notice index within the context of the input that produced it
Index int `json:"index"`
// Input whose processing produced the notice
InputIndex int `json:"inputIndex"`
// Transaction destination address in Ethereum hex binary format (20 bytes), starting with '0x'
Destination string `json:"destination"`
// Notice data as a payload in Ethereum hex binary format, starting with '0x'
Payload hexutil.Bytes `json:"payload"`
// Proof object that allows this notice to be validated by the base layer blockchain
Proof *Proof `json:"proof"`
}

func newVoucher(
index int,
inputIndex int,
destination string,
payload string,
proof *Proof,
) (*Voucher, error) {
convPayload, err := hexutil.Decode(payload)
if err != nil {
return nil, fmt.Errorf("failed to decode payload to bytes: %v", err)
}

voucher := Voucher{
index,
inputIndex,
destination,
convPayload,
proof,
}

return &voucher, err
}

// Get multiple vouchers from graphql.
func GetVouchers(
ctx context.Context,
client graphql.Client,
) ([]Voucher, error) {

var vouchers []Voucher

resp, err := getVouchers(ctx, client)
if err != nil {
return nil, err
}

for _, edge := range resp.Vouchers.Edges {

proof, err := newProof(
edge.Node.Proof.Validity.InputIndexWithinEpoch,
edge.Node.Proof.Validity.OutputIndexWithinInput,
edge.Node.Proof.Validity.OutputHashesRootHash,
edge.Node.Proof.Validity.VouchersEpochRootHash,
edge.Node.Proof.Validity.NoticesEpochRootHash,
edge.Node.Proof.Validity.MachineStateHash,
edge.Node.Proof.Validity.OutputHashInOutputHashesSiblings,
edge.Node.Proof.Validity.OutputHashesInEpochSiblings,
edge.Node.Proof.Context,
)
if err != nil {
return nil, err
}

voucher, err := newVoucher(
edge.Node.Index,
edge.Node.Input.Index,
edge.Node.Destination,
edge.Node.Payload,
proof,
)
if err != nil {
return nil, err
}

vouchers = append(vouchers, *voucher)
}

return vouchers, err
}

// Get multiple vouchers from GraphQL for the given input index.
func GetInputVouchers(
ctx context.Context,
client graphql.Client,
inputIndex int,
) ([]Voucher, error) {

var vouchers []Voucher

resp, err := getInputVouchers(ctx, client, inputIndex)
if err != nil {
return nil, err
}

for _, edge := range resp.Input.Vouchers.Edges {

proof, err := newProof(
edge.Node.Proof.Validity.InputIndexWithinEpoch,
edge.Node.Proof.Validity.OutputIndexWithinInput,
edge.Node.Proof.Validity.OutputHashesRootHash,
edge.Node.Proof.Validity.VouchersEpochRootHash,
edge.Node.Proof.Validity.NoticesEpochRootHash,
edge.Node.Proof.Validity.MachineStateHash,
edge.Node.Proof.Validity.OutputHashInOutputHashesSiblings,
edge.Node.Proof.Validity.OutputHashesInEpochSiblings,
edge.Node.Proof.Context,
)
if err != nil {
return nil, err
}

voucher, err := newVoucher(
edge.Node.Index,
resp.Input.Index,
edge.Node.Destination,
edge.Node.Payload,
proof,
)
if err != nil {
return nil, err
}

vouchers = append(vouchers, *voucher)
}

return vouchers, err
}

// Get voucher from GraphQL given the input and voucher indices.
func GetVoucher(
ctx context.Context,
client graphql.Client,
voucherIndex int,
inputIndex int,
) (*Voucher, error) {
resp, err := getVoucher(ctx, client, voucherIndex, inputIndex)
if err != nil {
return nil, err
}

proof, err := newProof(
resp.Voucher.Proof.Validity.InputIndexWithinEpoch,
resp.Voucher.Proof.Validity.OutputIndexWithinInput,
resp.Voucher.Proof.Validity.OutputHashesRootHash,
resp.Voucher.Proof.Validity.VouchersEpochRootHash,
resp.Voucher.Proof.Validity.NoticesEpochRootHash,
resp.Voucher.Proof.Validity.MachineStateHash,
resp.Voucher.Proof.Validity.OutputHashInOutputHashesSiblings,
resp.Voucher.Proof.Validity.OutputHashesInEpochSiblings,
resp.Voucher.Proof.Context,
)
if err != nil {
return nil, err
}

voucher, err := newVoucher(
resp.Voucher.Index,
resp.Voucher.Input.Index,
resp.Voucher.Destination,
resp.Voucher.Payload,
proof,
)

return voucher, err
}

0 comments on commit 967c3fd

Please sign in to comment.