diff --git a/client/query.go b/client/query.go index 2a27419..71490f5 100644 --- a/client/query.go +++ b/client/query.go @@ -7,6 +7,7 @@ import ( "github.com/FourthState/plasma-mvp-sidechain/store" "github.com/cosmos/cosmos-sdk/client/context" ethcmn "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rlp" "math/big" ) @@ -154,3 +155,49 @@ func Blocks(ctx context.CLIContext, startingHeight *big.Int) ([]store.Block, err return blocks, nil } + +// Returns confirm sig results for given position +// Trusts connected full node +func ConfirmSignatures(ctx context.CLIContext, position plasma.Position) ([]byte, error) { + key := store.GetOutputKey(position) + hash, err := ctx.QueryStore(key, store.DataStoreName) + if err != nil { + return nil, err + } + + txKey := store.GetTxKey(hash) + txBytes, err := ctx.QueryStore(txKey, store.DataStoreName) + + var tx store.Transaction + if err := rlp.DecodeBytes(txBytes, &tx); err != nil { + return nil, fmt.Errorf("transaction decoding failed: %s", err.Error()) + } + + // Look for confirmation signatures + // Ignore error if no confirm sig currently exists in store + var sigs []byte + if len(tx.SpenderTxs[position.OutputIndex]) > 0 { + queryPath := fmt.Sprintf("custom/%s/%s/%s", + store.QuerierRouteName, store.QueryTx, tx.SpenderTxs[position.OutputIndex]) + data, err := ctx.Query(queryPath, nil) + if err != nil { + return nil, err + } + + var spenderTx store.Transaction + if err := json.Unmarshal(data, &spenderTx); err != nil { + return nil, fmt.Errorf("unmarshaling json query response: %s", err) + } + + for _, input := range spenderTx.Transaction.Inputs { + if input.Position.String() == position.String() { + for _, sig := range input.ConfirmSignatures { + sigs = append(sigs, sig[:]...) + } + } + } + } + + return sigs, nil +} + diff --git a/cmd/plasmacli/subcmd/eth/query/confirmsig.go b/cmd/plasmacli/subcmd/eth/query/confirmsig.go new file mode 100644 index 0000000..945ddb7 --- /dev/null +++ b/cmd/plasmacli/subcmd/eth/query/confirmsig.go @@ -0,0 +1,49 @@ +package query + +import ( + "fmt" + "github.com/FourthState/plasma-mvp-sidechain/client" + "github.com/FourthState/plasma-mvp-sidechain/cmd/plasmacli/config" + "github.com/FourthState/plasma-mvp-sidechain/plasma" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/spf13/cobra" +) + +// SigCmd returns the query confirm sig command +func SigCmd() *cobra.Command { + config.AddPersistentTMFlags(sigCmd) + return sigCmd +} + +var sigCmd = &cobra.Command{ + Use: "sig ", + Short: "Query confirm signature information for a given position", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + // parse position + pos, err := plasma.FromPositionString(args[0]) + if err != nil { + return fmt.Errorf("error parsing position: %s", err) + } + + var sigs []byte + ctx := context.NewCLIContext() + sigs, err = client.ConfirmSignatures(ctx, pos) + if err != nil { + return fmt.Errorf("failed to retrieve confirm signature information: %s", err) + } + + cmd.SilenceUsage = true + + switch len(sigs) { + case 0: + fmt.Printf("No Confirm Signatures Found") + case 65: + fmt.Printf("Confirmation Signatures: 0x%x\n", sigs[:]) + case 130: + fmt.Printf("Confirmation Signatures: 0x%x, 0x%x\n", sigs[:65], sigs[65:]) + } + + return nil + }, +} \ No newline at end of file diff --git a/cmd/plasmacli/subcmd/eth/query/root.go b/cmd/plasmacli/subcmd/eth/query/root.go index 280e772..c358845 100644 --- a/cmd/plasmacli/subcmd/eth/query/root.go +++ b/cmd/plasmacli/subcmd/eth/query/root.go @@ -25,6 +25,7 @@ func RootCmd() *cobra.Command { BlockCmd(), DepositCmd(), ExitsCmd(), + SigCmd(), RootchainCmd(), ) diff --git a/cmd/plasmacli/subcmd/eth/root.go b/cmd/plasmacli/subcmd/eth/root.go index b53ef44..47a4a76 100644 --- a/cmd/plasmacli/subcmd/eth/root.go +++ b/cmd/plasmacli/subcmd/eth/root.go @@ -53,7 +53,7 @@ var ethCmd = &cobra.Command{ Short: "Interact with the plasma smart contract", Long: `Configurations for interacting with the rootchain contract can be specified in /plasma.toml. An eth node instance needs to be running for this command to work.`, - PreRunE: func(cmd *cobra.Command, args []string) error { + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { fmt.Println("setting up eth connection") plasma, err := config.GetContractConn() plasmaContract = plasma