From b8a9b719d046bd360a10479106c24dac659a10f2 Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Wed, 25 Dec 2019 15:03:21 -0800 Subject: [PATCH 1/8] optional verbose flag --- cmd/plasmacli/flags/flags.go | 3 ++- cmd/plasmacli/subcmd/query/info.go | 11 +---------- cmd/plasmacli/subcmd/root.go | 1 + cmd/plasmacli/subcmd/tx/include.go | 2 ++ cmd/plasmacli/subcmd/tx/sign.go | 1 + cmd/plasmacli/subcmd/tx/spend.go | 1 + 6 files changed, 8 insertions(+), 11 deletions(-) diff --git a/cmd/plasmacli/flags/flags.go b/cmd/plasmacli/flags/flags.go index e71df62..3d93561 100644 --- a/cmd/plasmacli/flags/flags.go +++ b/cmd/plasmacli/flags/flags.go @@ -6,5 +6,6 @@ import ( // Flags const ( - Home = tmcli.HomeFlag + Home = tmcli.HomeFlag + Verbose = "verbose" ) diff --git a/cmd/plasmacli/subcmd/query/info.go b/cmd/plasmacli/subcmd/query/info.go index fedbe79..92a00ff 100644 --- a/cmd/plasmacli/subcmd/query/info.go +++ b/cmd/plasmacli/subcmd/query/info.go @@ -43,20 +43,11 @@ var infoCmd = &cobra.Command{ fmt.Printf("UTXO %d\n", i) fmt.Printf("Position: %s, Amount: %s, Spent: %t\nSpender Hash: %s\n", utxo.Position, utxo.Output.Amount.String(), utxo.Spent, utxo.SpenderTx) fmt.Printf("Transaction Hash: 0x%x\nConfirmationHash: 0x%x\n", utxo.TxHash, utxo.ConfirmationHash) - /* - // TODO: Add --verbose flag that if set will query TxInput and print InputAddresses and InputPositions as well - // print inputs if applicable - positions := utxo.InputPositions - for i, p := range positions { - fmt.Printf("Input %d Position: %s\n", i, p) - } - */ - fmt.Printf("End UTXO %d info\n\n", i) } if len(utxos) == 0 { - fmt.Println("no information available for this address") + fmt.Println("No information available for this address") } return nil diff --git a/cmd/plasmacli/subcmd/root.go b/cmd/plasmacli/subcmd/root.go index 20e9c4e..937d905 100644 --- a/cmd/plasmacli/subcmd/root.go +++ b/cmd/plasmacli/subcmd/root.go @@ -23,6 +23,7 @@ var homeDir = os.ExpandEnv("$HOME/.plasmacli/") func RootCmd() *cobra.Command { cobra.EnableCommandSorting = false rootCmd.PersistentFlags().String(flags.Home, homeDir, "home directory for plasmacli") + rootCmd.PersistentFlags().Bool(flags.Verbose, false, "additional output (if applicable)") if err := viper.BindPFlags(rootCmd.PersistentFlags()); err != nil { fmt.Println(err) os.Exit(1) diff --git a/cmd/plasmacli/subcmd/tx/include.go b/cmd/plasmacli/subcmd/tx/include.go index 00b8737..941048d 100644 --- a/cmd/plasmacli/subcmd/tx/include.go +++ b/cmd/plasmacli/subcmd/tx/include.go @@ -14,6 +14,7 @@ import ( "strings" ) +// IncludeCmd - func IncludeCmd() *cobra.Command { includeCmd.Flags().Int64P(replayF, "r", 0, "Replay Nonce that can be incremented to allow for resubmissions of include deposit messages") includeCmd.Flags().String(addressF, "", "address represented as hex string") @@ -82,6 +83,7 @@ var includeCmd = &cobra.Command{ if _, err := ctx.BroadcastTxAsync(txBytes); err != nil { return err } + fmt.Println("Transaction submitted") } else { res, err := ctx.BroadcastTxAndAwaitCommit(txBytes) if err != nil { diff --git a/cmd/plasmacli/subcmd/tx/sign.go b/cmd/plasmacli/subcmd/tx/sign.go index c44842b..c4dc631 100644 --- a/cmd/plasmacli/subcmd/tx/sign.go +++ b/cmd/plasmacli/subcmd/tx/sign.go @@ -18,6 +18,7 @@ const ( signPrompt = "Would you like to finalize this transaction? [Y/n]" ) +// SignCmd - func SignCmd() *cobra.Command { signCmd.Flags().String(ownerF, "", "Owner of the output (required with position flag)") signCmd.Flags().String(positionF, "", "Position of transaction to finalize (required with owner flag)") diff --git a/cmd/plasmacli/subcmd/tx/spend.go b/cmd/plasmacli/subcmd/tx/spend.go index 71e86b3..a311bfd 100644 --- a/cmd/plasmacli/subcmd/tx/spend.go +++ b/cmd/plasmacli/subcmd/tx/spend.go @@ -19,6 +19,7 @@ import ( "strings" ) +// SpendCmd - func SpendCmd() *cobra.Command { spendCmd.Flags().String(positionF, "", "UTXO Positions to be spent, format: (blknum0.txindex0.oindex0.depositnonce0)::(blknum1.txindex1.oindex1.depositnonce1)") spendCmd.Flags().StringP(confirmSigs0F, "0", "", "Input Confirmation Signatures for first input to be spent (separated by commas)") From d8c2bbb239e8c4fd9af32f4398bcaf6f19600fd3 Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Thu, 2 Jan 2020 10:15:10 -0800 Subject: [PATCH 2/8] start of adding verbose features. skeleton for tx query command --- cmd/plasmacli/subcmd/query/info.go | 22 ++++++++++++++++++--- cmd/plasmacli/subcmd/query/tx.go | 31 ++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 cmd/plasmacli/subcmd/query/tx.go diff --git a/cmd/plasmacli/subcmd/query/info.go b/cmd/plasmacli/subcmd/query/info.go index 92a00ff..4683eea 100644 --- a/cmd/plasmacli/subcmd/query/info.go +++ b/cmd/plasmacli/subcmd/query/info.go @@ -3,6 +3,7 @@ package query import ( "fmt" "github.com/FourthState/plasma-mvp-sidechain/client" + "github.com/FourthState/plasma-mvp-sidechain/cmd/plasmacli/flags" ks "github.com/FourthState/plasma-mvp-sidechain/cmd/plasmacli/store" "github.com/cosmos/cosmos-sdk/client/context" ethcmn "github.com/ethereum/go-ethereum/common" @@ -15,9 +16,11 @@ func InfoCmd() *cobra.Command { } var infoCmd = &cobra.Command{ - Use: "info ", - Short: "Information on owned utxos valid and invalid", - Args: cobra.ExactArgs(1), + Use: "info ", + Short: "Information on owned utxos valid and invalid", + Long: `Information on owned utxos valid and invalid. +If --verbose is set, the input positions that created each output will also be displayed`, + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.NewCLIContext() cmd.SilenceUsage = true @@ -43,6 +46,19 @@ var infoCmd = &cobra.Command{ fmt.Printf("UTXO %d\n", i) fmt.Printf("Position: %s, Amount: %s, Spent: %t\nSpender Hash: %s\n", utxo.Position, utxo.Output.Amount.String(), utxo.Spent, utxo.SpenderTx) fmt.Printf("Transaction Hash: 0x%x\nConfirmationHash: 0x%x\n", utxo.TxHash, utxo.ConfirmationHash) + + // query for the inputs that created this out + if flags.Verbose { + txInput, err := client.TxInput(ctx, utxo.Position) + if err != nil { + // print the error + } else { + for i, input := range txInput.InputPositions { + fmt.Printf("Input %d: Position: %s\n", i, input) + } + } + } + fmt.Printf("End UTXO %d info\n\n", i) } diff --git a/cmd/plasmacli/subcmd/query/tx.go b/cmd/plasmacli/subcmd/query/tx.go new file mode 100644 index 0000000..75c7e7e --- /dev/null +++ b/cmd/plasmacli/subcmd/query/tx.go @@ -0,0 +1,31 @@ +package query + +import ( + "fmt" + "github.com/FourthState/plasma-mvp-sidechain/client" + "github.com/FourthState/plasma-mvp-sidechain/cmd/plasmacli/flags" + "github.com/FourthState/plasma-mvp-sidechain/utils" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +// TxCommand - +func TxCommand() *cobra.Command { + return txCmd +} + +var txCmd *cobra.Command = &cobra.Command{ + Use: "tx ", + Short: "Query for information about a single transaction", + Long: `Query for information about a single transaction. +If --verbose is set, additional information about the transaction will also be displayed`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *Cobra.Command, args []string) error { + ctx := context.NewCLIContext() + + // argument validation + txHashStr := utils.RemoveHexPrefix(args[0]) + + }, +} From 8a16317a0655f4130de3edd319673b8c184411fd Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Sat, 22 Feb 2020 21:01:42 -0800 Subject: [PATCH 3/8] actually check the verbose flag --- cmd/plasmacli/subcmd/query/info.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/plasmacli/subcmd/query/info.go b/cmd/plasmacli/subcmd/query/info.go index 4683eea..aa359db 100644 --- a/cmd/plasmacli/subcmd/query/info.go +++ b/cmd/plasmacli/subcmd/query/info.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" ethcmn "github.com/ethereum/go-ethereum/common" "github.com/spf13/cobra" + "github.com/spf13/viper" ) // InfoCmd returns the query information command @@ -48,10 +49,10 @@ If --verbose is set, the input positions that created each output will also be d fmt.Printf("Transaction Hash: 0x%x\nConfirmationHash: 0x%x\n", utxo.TxHash, utxo.ConfirmationHash) // query for the inputs that created this out - if flags.Verbose { + if viper.GetBool(flags.Verbose) { txInput, err := client.TxInput(ctx, utxo.Position) if err != nil { - // print the error + fmt.Printf("Error retrieving further information about the inputs of this UTXO: %s", err) } else { for i, input := range txInput.InputPositions { fmt.Printf("Input %d: Position: %s\n", i, input) From 16be066605fa64f2b48353a61218a0ca6ab10097 Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Sun, 23 Feb 2020 20:33:03 -0800 Subject: [PATCH 4/8] godoc and more scafolding --- cmd/plasmacli/subcmd/query/tx.go | 10 ++++++++-- plasma/position.go | 22 +++++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/cmd/plasmacli/subcmd/query/tx.go b/cmd/plasmacli/subcmd/query/tx.go index 75c7e7e..d47f387 100644 --- a/cmd/plasmacli/subcmd/query/tx.go +++ b/cmd/plasmacli/subcmd/query/tx.go @@ -4,10 +4,12 @@ import ( "fmt" "github.com/FourthState/plasma-mvp-sidechain/client" "github.com/FourthState/plasma-mvp-sidechain/cmd/plasmacli/flags" + "github.com/FourthState/plasma-mvp-sidechain/plasma" "github.com/FourthState/plasma-mvp-sidechain/utils" "github.com/cosmos/cosmos-sdk/client/context" "github.com/spf13/cobra" "github.com/spf13/viper" + "strings" ) // TxCommand - @@ -25,7 +27,11 @@ If --verbose is set, additional information about the transaction will also be d ctx := context.NewCLIContext() // argument validation - txHashStr := utils.RemoveHexPrefix(args[0]) - + arg := utils.RemoveHexPrefix(strings.TrimSpace(args[0])) + if pos, err := plasma.FromPositionString(arg); err != nil { + // position + } else { + // transaction hash + } }, } diff --git a/plasma/position.go b/plasma/position.go index d20c66e..4c8b759 100644 --- a/plasma/position.go +++ b/plasma/position.go @@ -8,6 +8,7 @@ import ( "strings" ) +// Position - type Position struct { BlockNum *big.Int TxIndex uint16 @@ -20,6 +21,7 @@ const ( txIndexFactor = 10 ) +// NewPosition func NewPosition(blkNum *big.Int, txIndex uint16, oIndex uint8, depositNonce *big.Int) Position { if depositNonce == nil { depositNonce = big.NewInt(0) @@ -36,6 +38,7 @@ func NewPosition(blkNum *big.Int, txIndex uint16, oIndex uint8, depositNonce *bi } } +// Bytes serializes `p` func (p Position) Bytes() []byte { bytes, _ := rlp.EncodeToBytes(&p) return bytes @@ -65,18 +68,22 @@ func (p Position) ValidateBasic() error { return nil } +// IsDeposit - func (p Position) IsDeposit() bool { return p.DepositNonce.Sign() != 0 } +// IsFee - func (p Position) IsFee() bool { return p.TxIndex == 1<<16-1 } +// IsNilPosition - func (p Position) IsNilPosition() bool { return p.BlockNum.Sign() == 0 && p.DepositNonce.Sign() == 0 } +// Priority func (p Position) Priority() *big.Int { if p.IsDeposit() { return p.DepositNonce @@ -92,6 +99,7 @@ func (p Position) Priority() *big.Int { return temp.Add(temp, big.NewInt(int64(p.OutputIndex))) } +// ToBigIntArray - func (p Position) ToBigIntArray() [4]*big.Int { return [4]*big.Int{p.BlockNum, big.NewInt(int64(p.TxIndex)), big.NewInt(int64(p.OutputIndex)), p.DepositNonce} } @@ -107,6 +115,9 @@ func (p Position) String() string { p.BlockNum, p.TxIndex, p.OutputIndex, p.DepositNonce) } +// FromPositionString constructs a `Position` from the string representation +// "(blockNumber, txIndex, outputIndex, depositNonce)". The returned error will +// also reflect an invalid position object in addition to any deserialization errors func FromPositionString(posStr string) (Position, error) { posStr = strings.TrimSpace(posStr) if string(posStr[0]) != "(" || string(posStr[len(posStr)-1]) != ")" { @@ -160,11 +171,16 @@ func FromPositionString(posStr string) (Position, error) { return pos, pos.ValidateBasic() } -// Return the position of a utxo given the exit key +// FromExitKey creates the position of a utxo given the exit key func FromExitKey(key *big.Int, deposit bool) Position { if deposit { return NewPosition(big.NewInt(0), 0, 0, key) - } else { - return NewPosition(new(big.Int).Div(key, big.NewInt(blockIndexFactor)), uint16(key.Int64()%blockIndexFactor/txIndexFactor), uint8(key.Int64()%2), big.NewInt(0)) } + + return NewPosition( + new(big.Int).Div(key, big.NewInt(blockIndexFactor)), + uint16(key.Int64()%blockIndexFactor/txIndexFactor), + uint8(key.Int64()%2), + big.NewInt(0), + ) } From 4f58e1f58022cc2f1e5b5cfc02f7ea4ace303285 Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Fri, 28 Feb 2020 00:26:35 -0800 Subject: [PATCH 5/8] progress --- cmd/plasmacli/subcmd/query/tx.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/cmd/plasmacli/subcmd/query/tx.go b/cmd/plasmacli/subcmd/query/tx.go index d47f387..bcbe10d 100644 --- a/cmd/plasmacli/subcmd/query/tx.go +++ b/cmd/plasmacli/subcmd/query/tx.go @@ -19,19 +19,27 @@ func TxCommand() *cobra.Command { var txCmd *cobra.Command = &cobra.Command{ Use: "tx ", - Short: "Query for information about a single transaction", - Long: `Query for information about a single transaction. + Short: "Query for information about a single transaction or transaction output", + Long: `Query for information about a single transaction or transaction output. If --verbose is set, additional information about the transaction will also be displayed`, Args: cobra.ExactArgs(1), RunE: func(cmd *Cobra.Command, args []string) error { ctx := context.NewCLIContext() + cmd.SilenceUsage = true // argument validation arg := utils.RemoveHexPrefix(strings.TrimSpace(args[0])) if pos, err := plasma.FromPositionString(arg); err != nil { - // position + // utxo position + txOutput, err := client.TxOutput(ctx, pos) + if err != nil { + fmt.Printf("Error quering transaction output %s: %s\n", pos, err) + return err + } } else { // transaction hash } + + return nil }, } From c0441e4a9bb1f7eed9cac48e87df9ab1d53349c0 Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Wed, 11 Mar 2020 14:10:43 -0700 Subject: [PATCH 6/8] finish of the tx cmd --- cmd/plasmacli/subcmd/query/tx.go | 46 +++++++++++++++++++++++++++----- utils/utils.go | 2 ++ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/cmd/plasmacli/subcmd/query/tx.go b/cmd/plasmacli/subcmd/query/tx.go index bcbe10d..979d5cf 100644 --- a/cmd/plasmacli/subcmd/query/tx.go +++ b/cmd/plasmacli/subcmd/query/tx.go @@ -1,14 +1,13 @@ package query import ( + "encoding/hex" "fmt" "github.com/FourthState/plasma-mvp-sidechain/client" - "github.com/FourthState/plasma-mvp-sidechain/cmd/plasmacli/flags" "github.com/FourthState/plasma-mvp-sidechain/plasma" "github.com/FourthState/plasma-mvp-sidechain/utils" "github.com/cosmos/cosmos-sdk/client/context" "github.com/spf13/cobra" - "github.com/spf13/viper" "strings" ) @@ -20,15 +19,13 @@ func TxCommand() *cobra.Command { var txCmd *cobra.Command = &cobra.Command{ Use: "tx ", Short: "Query for information about a single transaction or transaction output", - Long: `Query for information about a single transaction or transaction output. -If --verbose is set, additional information about the transaction will also be displayed`, - Args: cobra.ExactArgs(1), - RunE: func(cmd *Cobra.Command, args []string) error { + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { ctx := context.NewCLIContext() cmd.SilenceUsage = true + arg := strings.TrimSpace(args[0]) // argument validation - arg := utils.RemoveHexPrefix(strings.TrimSpace(args[0])) if pos, err := plasma.FromPositionString(arg); err != nil { // utxo position txOutput, err := client.TxOutput(ctx, pos) @@ -36,8 +33,43 @@ If --verbose is set, additional information about the transaction will also be d fmt.Printf("Error quering transaction output %s: %s\n", pos, err) return err } + + // display output information + fmt.Printf("TxOutput: %s\n", pos) + fmt.Printf("Confirmation Hash: 0x%x\n", txOutput.ConfirmationHash) + fmt.Printf("Transaction Hash: 0x%x\n", txOutput.TxHash) + fmt.Printf("Spent: %v\n", txOutput.Spent) + if txOutput.Spent { + fmt.Printf("Spending Tx Hash: 0x%x\n", txOutput.SpenderTx) + } + } else { // transaction hash + txHash, err := hex.DecodeString(utils.RemoveHexPrefix(arg)) + if err != nil { + fmt.Printf("Error decoding tx hash hex-encoded string: %s\n", err) + return err + } + + tx, err := client.Tx(ctx, txHash) + if err != nil { + fmt.Printf("Error queyring trasnsaction hash: 0x%x\n", txHash) + return err + } + + // display transaction information + fmt.Printf("Block %d, Tx Index: %d\n", tx.Position.BlockNum, tx.Position.TxIndex) + fmt.Printf("TxHash: 0x%x\n", txHash) + fmt.Printf("Confirmation Hash: 0x%x\n", tx.ConfirmationHash) + // we expect the length of `SpenderTx` and `Spent` to be the same + for i, spender := range tx.SpenderTxs { + spent := tx.Spent[i] + fmt.Println("Ouput %d:\n\tSpent: %v\n", i, spent) + if spent { + // keep the indentendation + fmt.Printf("\tSpender Tx: 0x%x\n", spender) + } + } } return nil diff --git a/utils/utils.go b/utils/utils.go index 02f3e26..4a6857a 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -18,6 +18,8 @@ func IsZeroAddress(addr common.Address) bool { return bytes.Equal(addr[:], ZeroAddress[:]) } +// RemoveHexPrefix will remove the "0x" prefix to a hex string and also fix the byte string +// to an even length func RemoveHexPrefix(hexStr string) string { if len(hexStr) >= 2 && (hexStr[:2] == "0x" || hexStr[:2] == "0X") { hexStr = hexStr[2:] From 6dda90b9655fae5473f56bd3fe81a8c2db163c3a Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Wed, 11 Mar 2020 17:42:35 -0700 Subject: [PATCH 7/8] correct to Printf. remove the extra print statement in the tests --- cmd/plasmacli/subcmd/query/tx.go | 2 +- handlers/anteHandler_test.go | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/cmd/plasmacli/subcmd/query/tx.go b/cmd/plasmacli/subcmd/query/tx.go index 979d5cf..fb4be8f 100644 --- a/cmd/plasmacli/subcmd/query/tx.go +++ b/cmd/plasmacli/subcmd/query/tx.go @@ -64,7 +64,7 @@ var txCmd *cobra.Command = &cobra.Command{ // we expect the length of `SpenderTx` and `Spent` to be the same for i, spender := range tx.SpenderTxs { spent := tx.Spent[i] - fmt.Println("Ouput %d:\n\tSpent: %v\n", i, spent) + fmt.Printf("Ouput %d:\n\tSpent: %v\n", i, spent) if spent { // keep the indentendation fmt.Printf("\tSpender Tx: 0x%x\n", spender) diff --git a/handlers/anteHandler_test.go b/handlers/anteHandler_test.go index a9dcc78..3b7a9d3 100644 --- a/handlers/anteHandler_test.go +++ b/handlers/anteHandler_test.go @@ -353,10 +353,7 @@ func TestAnteValidTx(t *testing.T) { ds.SpendDeposit(ctx, big.NewInt(2), tx.Transaction.TxHash()) output, check := ds.GetOutput(ctx, getPosition("(1.0.0.0)")) - if !check { - fmt.Println("WHy?") - } - fmt.Printf("Output: %v\n", output) + require.True(t, check) // sanity // store confirm sig into correct format var confirmSig [65]byte From b28bee7d4c06380e9b3ea4784f30414b5c1e75bc Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Wed, 11 Mar 2020 18:15:43 -0700 Subject: [PATCH 8/8] fix test --- handlers/anteHandler_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handlers/anteHandler_test.go b/handlers/anteHandler_test.go index 3b7a9d3..bf452bd 100644 --- a/handlers/anteHandler_test.go +++ b/handlers/anteHandler_test.go @@ -352,7 +352,7 @@ func TestAnteValidTx(t *testing.T) { ds.StoreOutputs(ctx, tx) ds.SpendDeposit(ctx, big.NewInt(2), tx.Transaction.TxHash()) - output, check := ds.GetOutput(ctx, getPosition("(1.0.0.0)")) + _, check := ds.GetOutput(ctx, getPosition("(1.0.0.0)")) require.True(t, check) // sanity // store confirm sig into correct format