github.com/celestiaorg/celestia-node@v0.15.0-beta.1/nodebuilder/share/cmd/share.go (about)

     1  package cmd
     2  
     3  import (
     4  	"context"
     5  	"encoding/hex"
     6  	"fmt"
     7  	"strconv"
     8  
     9  	"github.com/spf13/cobra"
    10  
    11  	rpc "github.com/celestiaorg/celestia-node/api/rpc/client"
    12  	cmdnode "github.com/celestiaorg/celestia-node/cmd"
    13  	"github.com/celestiaorg/celestia-node/header"
    14  	"github.com/celestiaorg/celestia-node/share"
    15  )
    16  
    17  func init() {
    18  	Cmd.AddCommand(
    19  		sharesAvailableCmd,
    20  		getSharesByNamespaceCmd,
    21  		getShare,
    22  		getEDS,
    23  	)
    24  }
    25  
    26  var Cmd = &cobra.Command{
    27  	Use:               "share [command]",
    28  	Short:             "Allows interaction with the Share Module via JSON-RPC",
    29  	Args:              cobra.NoArgs,
    30  	PersistentPreRunE: cmdnode.InitClient,
    31  }
    32  
    33  var sharesAvailableCmd = &cobra.Command{
    34  	Use:   "available",
    35  	Short: "Subjectively validates if Shares committed to the given Root are available on the Network.",
    36  	Args:  cobra.ExactArgs(1),
    37  	RunE: func(cmd *cobra.Command, args []string) error {
    38  		client, err := cmdnode.ParseClientFromCtx(cmd.Context())
    39  		if err != nil {
    40  			return err
    41  		}
    42  		defer client.Close()
    43  
    44  		eh, err := getExtendedHeaderFromCmdArg(cmd.Context(), client, args[0])
    45  
    46  		if err != nil {
    47  			return err
    48  		}
    49  
    50  		err = client.Share.SharesAvailable(cmd.Context(), eh)
    51  		formatter := func(data interface{}) interface{} {
    52  			err, ok := data.(error)
    53  			available := false
    54  			if !ok {
    55  				available = true
    56  			}
    57  			return struct {
    58  				Available bool   `json:"available"`
    59  				Hash      []byte `json:"dah_hash"`
    60  				Reason    error  `json:"reason,omitempty"`
    61  			}{
    62  				Available: available,
    63  				Hash:      []byte(args[0]),
    64  				Reason:    err,
    65  			}
    66  		}
    67  		return cmdnode.PrintOutput(err, nil, formatter)
    68  	},
    69  }
    70  
    71  var getSharesByNamespaceCmd = &cobra.Command{
    72  	Use:   "get-by-namespace (height | hash) namespace",
    73  	Short: "Gets all shares from an EDS within the given namespace.",
    74  	Args:  cobra.ExactArgs(2),
    75  	RunE: func(cmd *cobra.Command, args []string) error {
    76  		client, err := cmdnode.ParseClientFromCtx(cmd.Context())
    77  		if err != nil {
    78  			return err
    79  		}
    80  		defer client.Close()
    81  
    82  		eh, err := getExtendedHeaderFromCmdArg(cmd.Context(), client, args[0])
    83  
    84  		if err != nil {
    85  			return err
    86  		}
    87  
    88  		ns, err := cmdnode.ParseV0Namespace(args[1])
    89  		if err != nil {
    90  			return err
    91  		}
    92  
    93  		shares, err := client.Share.GetSharesByNamespace(cmd.Context(), eh, ns)
    94  		return cmdnode.PrintOutput(shares, err, nil)
    95  	},
    96  }
    97  
    98  var getShare = &cobra.Command{
    99  	Use:   "get-share (height | hash) row col",
   100  	Short: "Gets a Share by coordinates in EDS.",
   101  	Args:  cobra.ExactArgs(3),
   102  	RunE: func(cmd *cobra.Command, args []string) error {
   103  		client, err := cmdnode.ParseClientFromCtx(cmd.Context())
   104  		if err != nil {
   105  			return err
   106  		}
   107  		defer client.Close()
   108  
   109  		eh, err := getExtendedHeaderFromCmdArg(cmd.Context(), client, args[0])
   110  
   111  		if err != nil {
   112  			return err
   113  		}
   114  
   115  		row, err := strconv.ParseInt(args[1], 10, 64)
   116  		if err != nil {
   117  			return err
   118  		}
   119  
   120  		col, err := strconv.ParseInt(args[2], 10, 64)
   121  		if err != nil {
   122  			return err
   123  		}
   124  
   125  		s, err := client.Share.GetShare(cmd.Context(), eh, int(row), int(col))
   126  
   127  		formatter := func(data interface{}) interface{} {
   128  			sh, ok := data.(share.Share)
   129  			if !ok {
   130  				return data
   131  			}
   132  
   133  			ns := hex.EncodeToString(share.GetNamespace(sh))
   134  
   135  			return struct {
   136  				Namespace string `json:"namespace"`
   137  				Data      []byte `json:"data"`
   138  			}{
   139  				Namespace: ns,
   140  				Data:      share.GetData(sh),
   141  			}
   142  		}
   143  		return cmdnode.PrintOutput(s, err, formatter)
   144  	},
   145  }
   146  
   147  var getEDS = &cobra.Command{
   148  	Use:   "get-eds (height | hash)",
   149  	Short: "Gets the full EDS identified by the given block height",
   150  	Args:  cobra.ExactArgs(1),
   151  	RunE: func(cmd *cobra.Command, args []string) error {
   152  		client, err := cmdnode.ParseClientFromCtx(cmd.Context())
   153  		if err != nil {
   154  			return err
   155  		}
   156  		defer client.Close()
   157  
   158  		eh, err := getExtendedHeaderFromCmdArg(cmd.Context(), client, args[0])
   159  
   160  		if err != nil {
   161  			return err
   162  		}
   163  
   164  		shares, err := client.Share.GetEDS(cmd.Context(), eh)
   165  		return cmdnode.PrintOutput(shares, err, nil)
   166  	},
   167  }
   168  
   169  func getExtendedHeaderFromCmdArg(ctx context.Context, client *rpc.Client, arg string) (*header.ExtendedHeader, error) {
   170  	hash, err := hex.DecodeString(arg)
   171  	if err == nil {
   172  		return client.Header.GetByHash(ctx, hash)
   173  	}
   174  	height, err := strconv.ParseUint(arg, 10, 64)
   175  	if err != nil {
   176  		return nil, fmt.Errorf("can't parse the height/hash argument: %w", err)
   177  	}
   178  	return client.Header.GetByHeight(ctx, height)
   179  }