Skip to content
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

fix: unmarshalling issue with multisig keys in master (backport #10061) #10113

Merged
merged 10 commits into from
Nov 9, 2021
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,15 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Bug Fixes

* [\#9969](https://github.com/cosmos/cosmos-sdk/pull/9969) fix: use keyring in config for add-genesis-account cmd.
* [\#10061](https://github.com/cosmos/cosmos-sdk/pull/10061) Ensure that `LegacyAminoPubKey` struct correctly unmarshals from JSON

### Client Breaking Changes

* [\#9879](https://github.com/cosmos/cosmos-sdk/pull/9879) Modify ABCI Queries to use `abci.QueryRequest` Height field if it is non-zero, otherwise continue using context height.

### API Breaking Changes

* [\#10077](https://github.com/cosmos/cosmos-sdk/pull/10077) Remove telemetry on `GasKV` and `CacheKV` store Get/Set operations, significantly improving their performance.
+ [\#10077](https://github.com/cosmos/cosmos-sdk/pull/10077) Remove telemetry on `GasKV` and `CacheKV` store Get/Set operations, significantly improving their performance.

## [v0.42.9](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.42.9) - 2021-08-04

Expand Down
23 changes: 21 additions & 2 deletions crypto/keys/multisig/amino.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,28 @@ func (m *LegacyAminoPubKey) UnmarshalAminoJSON(tmPk tmMultisig) error {
// Instead of just doing `*m = *protoPk`, we prefer to modify in-place the
// existing Anys inside `m` (instead of allocating new Anys), as so not to
// break the `.compat` fields in the existing Anys.
if m.PubKeys == nil {
m.PubKeys = make([]*types.Any, len(tmPk.PubKeys))
}
for i := range m.PubKeys {
m.PubKeys[i].TypeUrl = protoPk.PubKeys[i].TypeUrl
m.PubKeys[i].Value = protoPk.PubKeys[i].Value
if m.PubKeys[i] == nil {
// create the compat jsonBz value
bz, err := AminoCdc.MarshalJSON(tmPk.PubKeys[i])
if err != nil {
return err
}

m.PubKeys[i] = protoPk.PubKeys[i]
// UnmarshalJSON():
// just sets the compat.jsonBz value.
// always succeeds: err == nil
if err := m.PubKeys[i].UnmarshalJSON(bz); err != nil {
return err
}
} else {
m.PubKeys[i].TypeUrl = protoPk.PubKeys[i].TypeUrl
m.PubKeys[i].Value = protoPk.PubKeys[i].Value
}
}
m.Threshold = protoPk.Threshold

Expand Down
38 changes: 37 additions & 1 deletion crypto/keys/multisig/multisig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
)

func generatePubKeys(n int) []cryptotypes.PubKey {
pks := make([]cryptotypes.PubKey, n)
for i := 0; i < n; i++ {
pks[i] = secp256k1.GenPrivKey().PubKey()
}

return pks
}

func TestAddress(t *testing.T) {
msg := []byte{1, 2, 3, 4}
pubKeys, _ := generatePubKeysAndSignatures(5, msg)
Expand Down Expand Up @@ -379,5 +388,32 @@ func TestAminoUnmarshalJSON(t *testing.T) {
var pk cryptotypes.PubKey
err := cdc.UnmarshalJSON([]byte(pkJSON), &pk)
require.NoError(t, err)
require.Equal(t, uint32(3), pk.(*kmultisig.LegacyAminoPubKey).Threshold)
lpk := pk.(*kmultisig.LegacyAminoPubKey)
require.Equal(t, uint32(3), lpk.Threshold)
require.Equal(t, 5, len(pk.(*kmultisig.LegacyAminoPubKey).PubKeys))

for _, key := range pk.(*kmultisig.LegacyAminoPubKey).PubKeys {
require.NotNil(t, key)
pk := secp256k1.PubKey{}
err := pk.Unmarshal(key.Value)
require.NoError(t, err)
}
}

func TestProtoMarshalJSON(t *testing.T) {
require := require.New(t)
pubkeys := generatePubKeys(3)
msig := kmultisig.NewLegacyAminoPubKey(2, pubkeys)

registry := types.NewInterfaceRegistry()
cryptocodec.RegisterInterfaces(registry)
cdc := codec.NewProtoCodec(registry)

bz, err := cdc.MarshalInterfaceJSON(msig)
require.NoError(err)

var pk2 cryptotypes.PubKey
err = cdc.UnmarshalInterfaceJSON(bz, &pk2)
require.NoError(err)
require.True(pk2.Equals(msig))
}