diff --git a/client/keys/output_test.go b/client/keys/output_test.go index 9bc77841c51a..88361e74e8cd 100644 --- a/client/keys/output_test.go +++ b/client/keys/output_test.go @@ -45,6 +45,30 @@ func TestBech32KeysOutput(t *testing.T) { require.Equal(t, "{Name:multisig Type:multi Address:cosmos1nf8lf6n4wa43rzmdzwe6hkrnw5guekhqt595cw PubKey:{\"@type\":\"/cosmos.crypto.multisig.LegacyAminoPubKey\",\"threshold\":1,\"public_keys\":[{\"@type\":\"/cosmos.crypto.secp256k1.PubKey\",\"key\":\"AurroA7jvfPd1AadmmOvWM2rJSwipXfRf8yD6pLbA2DJ\"}]} Mnemonic:}", fmt.Sprintf("%+v", out)) } +// TestBech32KeysOutputNestedMsig tests that the output of a nested multisig key is correct +func TestBech32KeysOutputNestedMsig(t *testing.T) { + sk := secp256k1.PrivKey{Key: []byte{154, 49, 3, 117, 55, 232, 249, 20, 205, 216, 102, 7, 136, 72, 177, 2, 131, 202, 234, 81, 31, 208, 46, 244, 179, 192, 167, 163, 142, 117, 246, 13}} + tmpKey := sk.PubKey() + nestedMultiSig := kmultisig.NewLegacyAminoPubKey(1, []types.PubKey{tmpKey}) + multisigPk := kmultisig.NewLegacyAminoPubKey(2, []types.PubKey{tmpKey, nestedMultiSig}) + k, err := keyring.NewMultiRecord("multisig", multisigPk) + require.NotNil(t, k) + require.NoError(t, err) + + pubKey, err := k.GetPubKey() + require.NoError(t, err) + + accAddr := sdk.AccAddress(pubKey.Address()) + expectedOutput, err := NewKeyOutput(k.Name, k.GetType(), accAddr, multisigPk, addresscodec.NewBech32Codec("cosmos")) + require.NoError(t, err) + + out, err := MkAccKeyOutput(k, addresscodec.NewBech32Codec("cosmos")) + require.NoError(t, err) + + require.Equal(t, expectedOutput, out) + require.Equal(t, "{Name:multisig Type:multi Address:cosmos13ytvp7lwj947gpa5gz0zmlr9drvkdcykk4lmcj PubKey:{\"@type\":\"/cosmos.crypto.multisig.LegacyAminoPubKey\",\"threshold\":2,\"public_keys\":[{\"@type\":\"/cosmos.crypto.secp256k1.PubKey\",\"key\":\"AurroA7jvfPd1AadmmOvWM2rJSwipXfRf8yD6pLbA2DJ\"},{\"@type\":\"/cosmos.crypto.multisig.LegacyAminoPubKey\",\"threshold\":1,\"public_keys\":[{\"@type\":\"/cosmos.crypto.secp256k1.PubKey\",\"key\":\"AurroA7jvfPd1AadmmOvWM2rJSwipXfRf8yD6pLbA2DJ\"}]}]} Mnemonic:}", fmt.Sprintf("%+v", out)) +} + func TestProtoMarshalJSON(t *testing.T) { require := require.New(t) pubkeys := generatePubKeys(3) diff --git a/crypto/keys/multisig/amino.go b/crypto/keys/multisig/amino.go index 6ac90d0bdd11..17d3ba46a0d7 100644 --- a/crypto/keys/multisig/amino.go +++ b/crypto/keys/multisig/amino.go @@ -65,6 +65,16 @@ func tmToProto(tmPk tmMultisig) (*LegacyAminoPubKey, error) { }, nil } +// MarshalAmino overrides amino binary marshaling. +func (m LegacyAminoPubKey) MarshalAmino() ([]byte, error) { + return m.Marshal() +} + +// UnmarshalAmino overrides amino binary marshaling. +func (m *LegacyAminoPubKey) UnmarshalAmino(bz []byte) error { + return m.Unmarshal(bz) +} + // MarshalAminoJSON overrides amino JSON unmarshaling. func (m LegacyAminoPubKey) MarshalAminoJSON() (tmMultisig, error) { //nolint:golint // we need to override the default amino JSON marshaling return protoToTm(&m) diff --git a/crypto/keys/multisig/multisig_test.go b/crypto/keys/multisig/multisig_test.go index e8e75a61ab02..4f0b94745997 100644 --- a/crypto/keys/multisig/multisig_test.go +++ b/crypto/keys/multisig/multisig_test.go @@ -389,6 +389,21 @@ func TestAminoBinary(t *testing.T) { require.Equal(t, msig.Threshold, newMsig.(*kmultisig.LegacyAminoPubKey).Threshold) } +func TestAminoBinaryNested(t *testing.T) { + pubkeys := generatePubKeys(4) + nestedMsig := kmultisig.NewLegacyAminoPubKey(2, pubkeys[:2]) + msig := kmultisig.NewLegacyAminoPubKey(2, []cryptotypes.PubKey{pubkeys[2], pubkeys[3], nestedMsig}) + + // Do a round-trip key->bytes->key. + bz, err := legacy.Cdc.Marshal(msig) + require.NoError(t, err) + var newMsig cryptotypes.PubKey + err = legacy.Cdc.Unmarshal(bz, &newMsig) + require.NoError(t, err) + require.Equal(t, msig.Threshold, newMsig.(*kmultisig.LegacyAminoPubKey).Threshold) + require.Equal(t, len(msig.PubKeys), len(newMsig.(*kmultisig.LegacyAminoPubKey).PubKeys)) +} + func TestAminoMarshalJSON(t *testing.T) { pubkeys := generatePubKeys(2) multisigKey := kmultisig.NewLegacyAminoPubKey(2, pubkeys)