-
Notifications
You must be signed in to change notification settings - Fork 828
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add other confidential tx methods to seid #1933
Changes from 2 commits
2c73e2d
3ea53a6
a60d01c
53cfac7
5562fce
64ff084
4a411f0
3a80df5
be00e41
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
"crypto/ecdsa" | ||
"encoding/hex" | ||
"errors" | ||
"strconv" | ||
|
||
"github.com/cosmos/cosmos-sdk/client" | ||
"github.com/cosmos/cosmos-sdk/client/flags" | ||
|
@@ -33,6 +34,10 @@ | |
|
||
txCmd.AddCommand(NewInitializeAccountTxCmd()) | ||
txCmd.AddCommand(NewCloseAccountTxCmd()) | ||
txCmd.AddCommand(NewTransferTxCmd()) | ||
txCmd.AddCommand(NewWithdrawTxCmd()) | ||
txCmd.AddCommand(NewDepositTxCmd()) | ||
txCmd.AddCommand(NewApplyPendingBalanceTxCmd()) | ||
|
||
return txCmd | ||
} | ||
|
@@ -138,17 +143,7 @@ | |
return err | ||
} | ||
|
||
req := &types.GetCtAccountRequest{ | ||
Address: clientCtx.GetFromAddress().String(), | ||
Denom: args[0], | ||
} | ||
|
||
ctAccount, err := queryClient.GetCtAccount(context.Background(), req) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
account, err := ctAccount.GetAccount().FromProto() | ||
account, err := getAccount(queryClient, clientCtx.GetFromAddress().String(), args[0]) | ||
if err != nil { | ||
return err | ||
} | ||
|
@@ -173,3 +168,285 @@ | |
|
||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) | ||
} | ||
|
||
// NewTransferTxCmd returns a CLI command handler for creating a MsgTransfer transaction. | ||
func NewTransferTxCmd() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "transfer [denom] [to_address] [amount] [flags]", | ||
Short: "Make a confidential transfer to another address", | ||
Long: `Transfer command create a confidential transfer of the specified amount of the specified denomination to the specified address. | ||
passed in .`, | ||
Args: cobra.ExactArgs(3), | ||
RunE: makeTransferCmd, | ||
} | ||
|
||
flags.AddTxFlagsToCmd(cmd) | ||
cmd.Flags().StringSlice("auditors", []string{}, "List of auditors") | ||
|
||
return cmd | ||
} | ||
|
||
func makeTransferCmd(cmd *cobra.Command, args []string) error { | ||
clientCtx, err := client.GetClientTxContext(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
queryClientCtx, err := client.GetClientQueryContext(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
queryClient := types.NewQueryClient(queryClientCtx) | ||
|
||
privKey, err := getPrivateKey(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fromAddress := clientCtx.GetFromAddress().String() | ||
denom := args[0] | ||
toAddress := args[1] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we may want to validate inputs. I think I skipped those checks in commands I implemented, and we may need to revisit here and other places There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated the commands with denom and address validation |
||
amount, err := strconv.ParseUint(args[2], 10, 64) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
senderAccount, err := getAccount(queryClient, fromAddress, denom) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
recipientAccount, err := getAccount(queryClient, toAddress, denom) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
auditorAddrs, err := cmd.Flags().GetStringSlice("auditors") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
auditors := make([]types.AuditorInput, len(auditorAddrs)) | ||
for i, auditorAddr := range auditorAddrs { | ||
auditorAccount, err := getAccount(queryClient, auditorAddr, denom) | ||
if err != nil { | ||
return err | ||
} | ||
auditors[i] = types.AuditorInput{ | ||
auditorAddr, | ||
&auditorAccount.PublicKey, | ||
} | ||
} | ||
|
||
transfer, err := types.NewTransfer( | ||
privKey, | ||
fromAddress, | ||
toAddress, | ||
args[0], | ||
senderAccount.DecryptableAvailableBalance, | ||
senderAccount.AvailableBalance, | ||
amount, | ||
&recipientAccount.PublicKey, | ||
auditors) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
msg := types.NewMsgTransferProto(transfer) | ||
|
||
if err = msg.ValidateBasic(); err != nil { | ||
return err | ||
} | ||
|
||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) | ||
} | ||
|
||
// NewWithdrawTxCmd returns a CLI command handler for creating a MsgWithdraw transaction. | ||
func NewWithdrawTxCmd() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "withdraw [denom] [amount] [flags]", | ||
Short: "Withdraw from confidential transfers account", | ||
Long: `Withdraws the specified amount from the confidential transfers account for the specified denomination and address | ||
passed in --from flag.`, | ||
Args: cobra.ExactArgs(2), | ||
RunE: makeWithdrawCmd, | ||
} | ||
|
||
flags.AddTxFlagsToCmd(cmd) | ||
|
||
return cmd | ||
} | ||
|
||
func makeWithdrawCmd(cmd *cobra.Command, args []string) error { | ||
clientCtx, err := client.GetClientTxContext(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
queryClientCtx, err := client.GetClientQueryContext(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
queryClient := types.NewQueryClient(queryClientCtx) | ||
|
||
privKey, err := getPrivateKey(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
address := clientCtx.GetFromAddress().String() | ||
denom := args[0] | ||
amount, err := strconv.ParseUint(args[1], 10, 64) | ||
if err != nil { | ||
return err | ||
} | ||
account, err := getAccount(queryClient, address, denom) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
withdraw, err := types.NewWithdraw( | ||
*privKey, | ||
account.AvailableBalance, | ||
denom, | ||
address, | ||
account.DecryptableAvailableBalance, | ||
amount) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
msg := types.NewMsgWithdrawProto(withdraw) | ||
|
||
if err = msg.ValidateBasic(); err != nil { | ||
return err | ||
} | ||
|
||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) | ||
} | ||
|
||
// NewDepositTxCmd returns a CLI command handler for creating a MsgDeposit transaction. | ||
func NewDepositTxCmd() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "deposit [denom] [amount] [flags]", | ||
Short: "Deposit funds into confidential transfers account", | ||
Long: `Deposit the specified amount into the confidential transfers account for the specified denomination and address | ||
passed in --from flag.`, | ||
Args: cobra.ExactArgs(2), | ||
RunE: makeDepositCmd, | ||
} | ||
|
||
flags.AddTxFlagsToCmd(cmd) | ||
|
||
return cmd | ||
} | ||
|
||
func makeDepositCmd(cmd *cobra.Command, args []string) error { | ||
clientCtx, err := client.GetClientTxContext(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
address := clientCtx.GetFromAddress().String() | ||
denom := args[0] | ||
amount, err := strconv.ParseUint(args[1], 10, 64) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
msg := &types.MsgDeposit{ | ||
FromAddress: address, | ||
Denom: denom, | ||
Amount: amount, | ||
} | ||
|
||
if err = msg.ValidateBasic(); err != nil { | ||
return err | ||
} | ||
|
||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) | ||
} | ||
|
||
// NewApplyPendingBalanceCmd returns a CLI command handler for creating a MsgDeposit transaction. | ||
func NewApplyPendingBalanceTxCmd() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "apply-pending-balance [denom] [flags]", | ||
Short: "Applies the pending balances to the available balances", | ||
Long: `Makes the pending balances of the confidential token account for the specified denomination and address | ||
passed in --from flag spendable by moving them to the available balance.`, | ||
Args: cobra.ExactArgs(1), | ||
RunE: makeApplyPendingBalanceCmd, | ||
} | ||
|
||
flags.AddTxFlagsToCmd(cmd) | ||
|
||
return cmd | ||
} | ||
|
||
func makeApplyPendingBalanceCmd(cmd *cobra.Command, args []string) error { | ||
clientCtx, err := client.GetClientTxContext(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
queryClientCtx, err := client.GetClientQueryContext(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
queryClient := types.NewQueryClient(queryClientCtx) | ||
privKey, err := getPrivateKey(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
address := clientCtx.GetFromAddress().String() | ||
denom := args[0] | ||
if err != nil { | ||
return err | ||
} | ||
|
||
account, err := getAccount(queryClient, clientCtx.GetFromAddress().String(), args[0]) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
msg, err := types.NewMsgApplyPendingBalance( | ||
*privKey, | ||
address, | ||
denom, | ||
account.DecryptableAvailableBalance, | ||
account.PendingBalanceLo, | ||
account.PendingBalanceHi) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
if err = msg.ValidateBasic(); err != nil { | ||
return err | ||
} | ||
|
||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) | ||
} | ||
|
||
// Uses the query client to get the account data for the given address and denomination. | ||
func getAccount(queryClient types.QueryClient, address, denom string) (*types.Account, error) { | ||
ctAccount, err := queryClient.GetCtAccount(context.Background(), &types.GetCtAccountRequest{ | ||
Address: address, | ||
Denom: denom, | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
account, err := ctAccount.GetAccount().FromProto() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return account, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -358,6 +358,10 @@ func (m msgServer) Transfer(goCtx context.Context, req *types.MsgTransfer) (*typ | |
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid msg") | ||
} | ||
|
||
if instruction.FromAddress == instruction.ToAddress { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess I agree, but In bank module though, I think it's a valid case There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Disabled this because the way we write this is senderState.Balance += Amount keeper.Store(senderState, sender) If sender and recipient are same address, the updated 'recipientState' overrides the updated 'senderState' for the key 'sender' and funds are not deducted. If we want to enable this we need to write a special case. |
||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "sender and recipient addresses must be different") | ||
} | ||
|
||
// Check that sender and recipient accounts exist. | ||
senderAccount, exists := m.Keeper.GetAccount(ctx, req.FromAddress, req.Denom) | ||
if !exists { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: We could also add some example commands in long description. I think i rushed my piece in without it though