Some checks are pending
Build SimApp / build (amd64) (push) Waiting to run
Build SimApp / build (arm64) (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
Build & Push / build (push) Waiting to run
Run Gosec / Gosec (push) Waiting to run
Lint / golangci-lint (push) Waiting to run
Checks dependencies and mocks generation / Check go mod tidy (push) Waiting to run
Checks dependencies and mocks generation / Check up to date mocks (push) Waiting to run
System Tests / setup (push) Waiting to run
System Tests / test-system (push) Blocked by required conditions
System Tests / test-system-legacy (push) Blocked by required conditions
Tests / Code Coverage / split-test-files (push) Waiting to run
Tests / Code Coverage / tests (00) (push) Blocked by required conditions
Tests / Code Coverage / tests (01) (push) Blocked by required conditions
Tests / Code Coverage / tests (02) (push) Blocked by required conditions
Tests / Code Coverage / tests (03) (push) Blocked by required conditions
Tests / Code Coverage / test-integration (push) Waiting to run
Tests / Code Coverage / test-e2e (push) Waiting to run
Tests / Code Coverage / repo-analysis (push) Blocked by required conditions
Tests / Code Coverage / test-sim-nondeterminism (push) Waiting to run
Tests / Code Coverage / test-clientv2 (push) Waiting to run
Tests / Code Coverage / test-core (push) Waiting to run
Tests / Code Coverage / test-depinject (push) Waiting to run
Tests / Code Coverage / test-errors (push) Waiting to run
Tests / Code Coverage / test-math (push) Waiting to run
Tests / Code Coverage / test-schema (push) Waiting to run
Tests / Code Coverage / test-collections (push) Waiting to run
Tests / Code Coverage / test-cosmovisor (push) Waiting to run
Tests / Code Coverage / test-confix (push) Waiting to run
Tests / Code Coverage / test-store (push) Waiting to run
Tests / Code Coverage / test-log (push) Waiting to run
Tests / Code Coverage / test-x-tx (push) Waiting to run
Tests / Code Coverage / test-x-nft (push) Waiting to run
Tests / Code Coverage / test-x-circuit (push) Waiting to run
Tests / Code Coverage / test-x-feegrant (push) Waiting to run
Tests / Code Coverage / test-x-evidence (push) Waiting to run
Tests / Code Coverage / test-x-upgrade (push) Waiting to run
Tests / Code Coverage / test-tools-benchmark (push) Waiting to run
109 lines
3.4 KiB
Go
109 lines
3.4 KiB
Go
package multisig
|
|
|
|
import (
|
|
errorsmod "cosmossdk.io/errors"
|
|
|
|
types "git.cw.tr/mukan-network/mukan-sdk/codec/types"
|
|
cryptotypes "git.cw.tr/mukan-network/mukan-sdk/crypto/types"
|
|
sdkerrors "git.cw.tr/mukan-network/mukan-sdk/types/errors"
|
|
)
|
|
|
|
// tmMultisig implements a K of N threshold multisig. It is used for
|
|
// Amino JSON marshaling of LegacyAminoPubKey (see below for details).
|
|
//
|
|
// This struct is copy-pasted from:
|
|
// https://github.com/tendermint/tendermint/blob/v0.33.9/crypto/multisig/threshold_pubkey.go
|
|
//
|
|
// This struct was used in the SDK <=0.39. In 0.40 and the switch to protobuf,
|
|
// it has been converted to LegacyAminoPubKey. However, there's one difference:
|
|
// the threshold field was an `uint` before, and an `uint32` after. This caused
|
|
// amino marshaling to be breaking: amino marshals `uint32` as a JSON number,
|
|
// and `uint` as a JSON string.
|
|
//
|
|
// In this file, we're overriding LegacyAminoPubKey's default JSON Amino
|
|
// marshaling by using this struct. Please note that we are NOT overriding the
|
|
// Amino binary marshaling, as that _might_ introduce breaking changes in the
|
|
// keyring, where multisigs are amino-binary-encoded.
|
|
//
|
|
// ref: https://git.cw.tr/mukan-network/mukan-sdk/issues/8776
|
|
type tmMultisig struct {
|
|
K uint `json:"threshold"`
|
|
PubKeys []cryptotypes.PubKey `json:"pubkeys"`
|
|
}
|
|
|
|
// protoToTm converts a LegacyAminoPubKey into a tmMultisig.
|
|
func protoToTm(protoPk *LegacyAminoPubKey) (tmMultisig, error) {
|
|
var ok bool
|
|
pks := make([]cryptotypes.PubKey, len(protoPk.PubKeys))
|
|
for i, pk := range protoPk.PubKeys {
|
|
pks[i], ok = pk.GetCachedValue().(cryptotypes.PubKey)
|
|
if !ok {
|
|
return tmMultisig{}, errorsmod.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", (cryptotypes.PubKey)(nil), pk.GetCachedValue())
|
|
}
|
|
}
|
|
|
|
return tmMultisig{
|
|
K: uint(protoPk.Threshold),
|
|
PubKeys: pks,
|
|
}, nil
|
|
}
|
|
|
|
// tmToProto converts a tmMultisig into a LegacyAminoPubKey.
|
|
func tmToProto(tmPk tmMultisig) (*LegacyAminoPubKey, error) {
|
|
var err error
|
|
pks := make([]*types.Any, len(tmPk.PubKeys))
|
|
for i, pk := range tmPk.PubKeys {
|
|
pks[i], err = types.NewAnyWithValue(pk)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return &LegacyAminoPubKey{
|
|
Threshold: uint32(tmPk.K),
|
|
PubKeys: pks,
|
|
}, nil
|
|
}
|
|
|
|
// MarshalAminoJSON overrides amino JSON unmarshaling.
|
|
func (m LegacyAminoPubKey) MarshalAminoJSON() (tmMultisig, error) {
|
|
return protoToTm(&m)
|
|
}
|
|
|
|
// UnmarshalAminoJSON overrides amino JSON unmarshaling.
|
|
func (m *LegacyAminoPubKey) UnmarshalAminoJSON(tmPk tmMultisig) error {
|
|
protoPk, err := tmToProto(tmPk)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 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 {
|
|
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
|
|
|
|
return nil
|
|
}
|