Merge PR #3347: Ensure Canonical Message Signature Bytes

This commit is contained in:
Alexander Bezobchuk 2019-01-23 03:46:41 -05:00 committed by Christopher Goes
parent b2ae4ed573
commit a27ef7f7d1
7 changed files with 76 additions and 138 deletions

View File

@ -144,6 +144,8 @@ BUG FIXES
* \#3223 Fix unset governance proposal queues when importing state from old chain
* [#3187](https://github.com/cosmos/cosmos-sdk/issues/3187) Fix `gaiad export`
by resetting each validator's slashing period.
* [##3336](https://github.com/cosmos/cosmos-sdk/issues/3336) Ensure all SDK
messages have their signature bytes contain canonical fields `value` and `type`.
* SDK

View File

@ -1,8 +1,6 @@
package bank
import (
"encoding/json"
sdk "github.com/cosmos/cosmos-sdk/types"
)
@ -43,24 +41,8 @@ func (msg MsgSend) ValidateBasic() sdk.Error {
// Implements Msg.
func (msg MsgSend) GetSignBytes() []byte {
var inputs, outputs []json.RawMessage
for _, input := range msg.Inputs {
inputs = append(inputs, input.GetSignBytes())
}
for _, output := range msg.Outputs {
outputs = append(outputs, output.GetSignBytes())
}
b, err := msgCdc.MarshalJSON(struct {
Inputs []json.RawMessage `json:"inputs"`
Outputs []json.RawMessage `json:"outputs"`
}{
Inputs: inputs,
Outputs: outputs,
})
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
bz := msgCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// Implements Msg.
@ -81,15 +63,6 @@ type Input struct {
Coins sdk.Coins `json:"coins"`
}
// Return bytes to sign for Input
func (in Input) GetSignBytes() []byte {
bin, err := msgCdc.MarshalJSON(in)
if err != nil {
panic(err)
}
return sdk.MustSortJSON(bin)
}
// ValidateBasic - validate transaction input
func (in Input) ValidateBasic() sdk.Error {
if len(in.Address) == 0 {
@ -106,11 +79,10 @@ func (in Input) ValidateBasic() sdk.Error {
// NewInput - create a transaction input, used with MsgSend
func NewInput(addr sdk.AccAddress, coins sdk.Coins) Input {
input := Input{
return Input{
Address: addr,
Coins: coins,
}
return input
}
//----------------------------------------
@ -122,15 +94,6 @@ type Output struct {
Coins sdk.Coins `json:"coins"`
}
// Return bytes to sign for Output
func (out Output) GetSignBytes() []byte {
bin, err := msgCdc.MarshalJSON(out)
if err != nil {
panic(err)
}
return sdk.MustSortJSON(bin)
}
// ValidateBasic - validate transaction output
func (out Output) ValidateBasic() sdk.Error {
if len(out.Address) == 0 {
@ -147,11 +110,10 @@ func (out Output) ValidateBasic() sdk.Error {
// NewOutput - create a transaction output, used with MsgSend
func NewOutput(addr sdk.AccAddress, coins sdk.Coins) Output {
output := Output{
return Output{
Address: addr,
Coins: coins,
}
return output
}
// ----------------------------------------------------------------------------

View File

@ -179,7 +179,7 @@ func TestMsgSendGetSignBytes(t *testing.T) {
}
res := msg.GetSignBytes()
expected := `{"inputs":[{"address":"cosmos1d9h8qat57ljhcm","coins":[{"amount":"10","denom":"atom"}]}],"outputs":[{"address":"cosmos1da6hgur4wsmpnjyg","coins":[{"amount":"10","denom":"atom"}]}]}`
expected := `{"type":"cosmos-sdk/Send","value":{"inputs":[{"address":"cosmos1d9h8qat57ljhcm","coins":[{"amount":"10","denom":"atom"}]}],"outputs":[{"address":"cosmos1da6hgur4wsmpnjyg","coins":[{"amount":"10","denom":"atom"}]}]}}`
require.Equal(t, expected, string(res))
}

View File

@ -34,11 +34,8 @@ func (msg MsgSetWithdrawAddress) GetSigners() []sdk.AccAddress {
// get the bytes for the message signer to sign on
func (msg MsgSetWithdrawAddress) GetSignBytes() []byte {
b, err := MsgCdc.MarshalJSON(msg)
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
bz := MsgCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// quick validity check
@ -75,11 +72,8 @@ func (msg MsgWithdrawDelegatorReward) GetSigners() []sdk.AccAddress {
// get the bytes for the message signer to sign on
func (msg MsgWithdrawDelegatorReward) GetSignBytes() []byte {
b, err := MsgCdc.MarshalJSON(msg)
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
bz := MsgCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// quick validity check
@ -114,11 +108,8 @@ func (msg MsgWithdrawValidatorCommission) GetSigners() []sdk.AccAddress {
// get the bytes for the message signer to sign on
func (msg MsgWithdrawValidatorCommission) GetSignBytes() []byte {
b, err := MsgCdc.MarshalJSON(msg)
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
bz := MsgCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// quick validity check

View File

@ -73,11 +73,8 @@ func (msg MsgSubmitProposal) Get(key interface{}) (value interface{}) {
// Implements Msg.
func (msg MsgSubmitProposal) GetSignBytes() []byte {
b, err := msgCdc.MarshalJSON(msg)
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
bz := msgCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// Implements Msg.
@ -134,11 +131,8 @@ func (msg MsgDeposit) Get(key interface{}) (value interface{}) {
// Implements Msg.
func (msg MsgDeposit) GetSignBytes() []byte {
b, err := msgCdc.MarshalJSON(msg)
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
bz := msgCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// Implements Msg.
@ -192,11 +186,8 @@ func (msg MsgVote) Get(key interface{}) (value interface{}) {
// Implements Msg.
func (msg MsgVote) GetSignBytes() []byte {
b, err := msgCdc.MarshalJSON(msg)
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
bz := msgCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// Implements Msg.

View File

@ -30,11 +30,8 @@ func (msg MsgUnjail) GetSigners() []sdk.AccAddress {
// get the bytes for the message signer to sign on
func (msg MsgUnjail) GetSignBytes() []byte {
b, err := cdc.MarshalJSON(msg)
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
bz := cdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// quick validity check

View File

@ -2,14 +2,21 @@ package types
import (
"bytes"
"encoding/json"
"github.com/tendermint/tendermint/crypto"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// Verify interface at compile time
var _, _, _ sdk.Msg = &MsgCreateValidator{}, &MsgEditValidator{}, &MsgDelegate{}
// ensure Msg interface compliance at compile time
var (
_ sdk.Msg = &MsgCreateValidator{}
_ sdk.Msg = &MsgEditValidator{}
_ sdk.Msg = &MsgDelegate{}
_ sdk.Msg = &MsgUndelegate{}
_ sdk.Msg = &MsgBeginRedelegate{}
)
//______________________________________________________________________
@ -23,6 +30,15 @@ type MsgCreateValidator struct {
Value sdk.Coin `json:"value"`
}
type msgCreateValidatorJSON struct {
Description Description `json:"description"`
Commission CommissionMsg `json:"commission"`
DelegatorAddr sdk.AccAddress `json:"delegator_address"`
ValidatorAddr sdk.ValAddress `json:"validator_address"`
PubKey string `json:"pubkey"`
Value sdk.Coin `json:"value"`
}
// Default way to create validator. Delegator address and validator address are the same
func NewMsgCreateValidator(valAddr sdk.ValAddress, pubkey crypto.PubKey,
selfDelegation sdk.Coin, description Description, commission CommissionMsg) MsgCreateValidator {
@ -62,26 +78,41 @@ func (msg MsgCreateValidator) GetSigners() []sdk.AccAddress {
return addrs
}
// TODO Remove use of custom struct (no longer necessary)
// get the bytes for the message signer to sign on
func (msg MsgCreateValidator) GetSignBytes() []byte {
b, err := MsgCdc.MarshalJSON(struct {
Description Description `json:"description"`
Commission CommissionMsg `json:"commission"`
DelegatorAddr sdk.AccAddress `json:"delegator_address"`
ValidatorAddr sdk.ValAddress `json:"validator_address"`
PubKey string `json:"pubkey"`
Value sdk.Coin `json:"value"`
}{
// MarshalJSON implements the json.Marshaler interface to provide custom JSON
// serialization of the MsgCreateValidator type.
func (msg MsgCreateValidator) MarshalJSON() ([]byte, error) {
return json.Marshal(msgCreateValidatorJSON{
Description: msg.Description,
Commission: msg.Commission,
DelegatorAddr: msg.DelegatorAddr,
ValidatorAddr: msg.ValidatorAddr,
PubKey: sdk.MustBech32ifyConsPub(msg.PubKey),
Value: msg.Value,
})
if err != nil {
panic(err)
}
// UnmarshalJSON implements the json.Unmarshaler interface to provide custom
// JSON deserialization of the MsgCreateValidator type.
func (msg *MsgCreateValidator) UnmarshalJSON(bz []byte) error {
var msgCreateValJSON msgCreateValidatorJSON
if err := json.Unmarshal(bz, &msgCreateValJSON); err != nil {
return err
}
return sdk.MustSortJSON(b)
msg.Description = msgCreateValJSON.Description
msg.Commission = msgCreateValJSON.Commission
msg.DelegatorAddr = msgCreateValJSON.DelegatorAddr
msg.ValidatorAddr = msgCreateValJSON.ValidatorAddr
msg.PubKey = sdk.MustGetConsPubKeyBech32(msgCreateValJSON.PubKey)
msg.Value = msgCreateValJSON.Value
return nil
}
// GetSignBytes returns the message bytes to sign over.
func (msg MsgCreateValidator) GetSignBytes() []byte {
bz := MsgCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// quick validity check
@ -137,17 +168,8 @@ func (msg MsgEditValidator) GetSigners() []sdk.AccAddress {
// get the bytes for the message signer to sign on
func (msg MsgEditValidator) GetSignBytes() []byte {
b, err := MsgCdc.MarshalJSON(struct {
Description
ValidatorAddr sdk.ValAddress `json:"address"`
}{
Description: msg.Description,
ValidatorAddr: msg.ValidatorAddr,
})
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
bz := MsgCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// quick validity check
@ -189,11 +211,8 @@ func (msg MsgDelegate) GetSigners() []sdk.AccAddress {
// get the bytes for the message signer to sign on
func (msg MsgDelegate) GetSignBytes() []byte {
b, err := MsgCdc.MarshalJSON(msg)
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
bz := MsgCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// quick validity check
@ -240,21 +259,8 @@ func (msg MsgBeginRedelegate) GetSigners() []sdk.AccAddress {
// get the bytes for the message signer to sign on
func (msg MsgBeginRedelegate) GetSignBytes() []byte {
b, err := MsgCdc.MarshalJSON(struct {
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
ValidatorSrcAddr sdk.ValAddress `json:"validator_src_addr"`
ValidatorDstAddr sdk.ValAddress `json:"validator_dst_addr"`
SharesAmount string `json:"shares"`
}{
DelegatorAddr: msg.DelegatorAddr,
ValidatorSrcAddr: msg.ValidatorSrcAddr,
ValidatorDstAddr: msg.ValidatorDstAddr,
SharesAmount: msg.SharesAmount.String(),
})
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
bz := MsgCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// quick validity check
@ -298,19 +304,8 @@ func (msg MsgUndelegate) GetSigners() []sdk.AccAddress { return []sdk.AccAddress
// get the bytes for the message signer to sign on
func (msg MsgUndelegate) GetSignBytes() []byte {
b, err := MsgCdc.MarshalJSON(struct {
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
ValidatorAddr sdk.ValAddress `json:"validator_addr"`
SharesAmount string `json:"shares_amount"`
}{
DelegatorAddr: msg.DelegatorAddr,
ValidatorAddr: msg.ValidatorAddr,
SharesAmount: msg.SharesAmount.String(),
})
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
bz := MsgCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// quick validity check