Skip to content

Commit

Permalink
feat(nodebuilder/blob/cmd): Allow submit multiple blobs through file …
Browse files Browse the repository at this point in the history
…input (#3008)
  • Loading branch information
sontrinh16 authored Feb 14, 2024
1 parent 87544d7 commit 5e1895c
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 14 deletions.
104 changes: 90 additions & 14 deletions nodebuilder/blob/cmd/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package cmd

import (
"encoding/base64"
"errors"
"fmt"
"path/filepath"
"reflect"
"strconv"

Expand All @@ -17,6 +19,10 @@ var (
base64Flag bool

gasPrice float64

// flagFileInput allows the user to provide file path to the json file
// for submitting multiple blobs.
flagFileInput = "input-file"
)

func init() {
Expand All @@ -43,6 +49,8 @@ func init() {
"specifies gas price (in utia) for blob submission.\n"+
"Gas price will be set to default (0.002) if no value is passed",
)

submitCmd.PersistentFlags().String(flagFileInput, "", "Specify the file input")
}

var Cmd = &cobra.Command{
Expand Down Expand Up @@ -119,11 +127,46 @@ var getAllCmd = &cobra.Command{
}

var submitCmd = &cobra.Command{
Use: "submit [namespace] [blobData]",
Args: cobra.ExactArgs(2),
Short: "Submit the blob at the given namespace.\n" +
Use: "submit [namespace] [blobData]",
Args: func(cmd *cobra.Command, args []string) error {
path, err := cmd.Flags().GetString(flagFileInput)
if err != nil {
return err
}

// If there is a file path input we'll check for the file extension
if path != "" {
if filepath.Ext(path) != ".json" {
return fmt.Errorf("invalid file extension, require json got %s", filepath.Ext(path))
}

return nil
}

if len(args) < 2 {
return errors.New("submit requires two arguments: namespace and blobData")
}

return nil
},
Short: "Submit the blob(s) at the given namespace(s).\n" +
"User can use namespace and blobData as argument for single blob submission \n" +
"or use --input-file flag with the path to a json file for multiple blobs submission, \n" +
`where the json file contains:
{
"Blobs": [
{
"namespace": "0x00010203040506070809",
"blobData": "0x676d"
},
{
"namespace": "0x42690c204d39600fddd3",
"blobData": "0x676d"
}
]
}` +
"Note:\n" +
"* only one blob is allowed to submit through the RPC.\n" +
"* fee and gas limit params will be calculated automatically.\n",
RunE: func(cmd *cobra.Command, args []string) error {
client, err := cmdnode.ParseClientFromCtx(cmd.Context())
Expand All @@ -132,33 +175,66 @@ var submitCmd = &cobra.Command{
}
defer client.Close()

namespace, err := cmdnode.ParseV0Namespace(args[0])
path, err := cmd.Flags().GetString(flagFileInput)
if err != nil {
return fmt.Errorf("error parsing a namespace:%v", err)
return err
}

parsedBlob, err := blob.NewBlobV0(namespace, []byte(args[1]))
if err != nil {
return fmt.Errorf("error creating a blob:%v", err)
jsonBlobs := make([]blobJSON, 0)
// In case of there is a file input, get the namespace and blob from the arguments
if path != "" {
paresdBlobs, err := parseSubmitBlobs(path)
if err != nil {
return err
}

jsonBlobs = append(jsonBlobs, paresdBlobs...)
} else {
jsonBlobs = append(jsonBlobs, blobJSON{Namespace: args[0], BlobData: args[1]})
}

var blobs []*blob.Blob
var commitments []blob.Commitment
for _, jsonBlob := range jsonBlobs {
blob, err := getBlobFromArguments(jsonBlob.Namespace, jsonBlob.BlobData)
if err != nil {
return err
}
blobs = append(blobs, blob)
commitments = append(commitments, blob.Commitment)
}

height, err := client.Blob.Submit(
cmd.Context(),
[]*blob.Blob{parsedBlob},
blobs,
blob.GasPrice(gasPrice),
)

response := struct {
Height uint64 `json:"height"`
Commitment blob.Commitment `json:"commitment"`
Height uint64 `json:"height"`
Commitments []blob.Commitment `json:"commitments"`
}{
Height: height,
Commitment: parsedBlob.Commitment,
Height: height,
Commitments: commitments,
}
return cmdnode.PrintOutput(response, err, nil)
},
}

func getBlobFromArguments(namespaceArg, blobArg string) (*blob.Blob, error) {
namespace, err := cmdnode.ParseV0Namespace(namespaceArg)
if err != nil {
return nil, fmt.Errorf("error parsing a namespace:%v", err)
}

parsedBlob, err := blob.NewBlobV0(namespace, []byte(blobArg))
if err != nil {
return nil, fmt.Errorf("error creating a blob:%v", err)
}

return parsedBlob, nil
}

var getProofCmd = &cobra.Command{
Use: "get-proof [height] [namespace] [commitment]",
Args: cobra.ExactArgs(3),
Expand Down
32 changes: 32 additions & 0 deletions nodebuilder/blob/cmd/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package cmd

import (
"encoding/json"
"os"
)

// Define the raw content from the file input.
type blobs struct {
Blobs []blobJSON
}

type blobJSON struct {
Namespace string
BlobData string
}

func parseSubmitBlobs(path string) ([]blobJSON, error) {
var rawBlobs blobs

content, err := os.ReadFile(path)
if err != nil {
return []blobJSON{}, err
}

err = json.Unmarshal(content, &rawBlobs)
if err != nil {
return []blobJSON{}, err
}

return rawBlobs.Blobs, err
}

0 comments on commit 5e1895c

Please sign in to comment.