multisig: add type and bitarray (#6241)
* add multisig and bitarray * remove random message * add changelog entry * bring back the concrete type * move changelog entry * move bitarray to crypto/types * fix build * remove commented code Co-authored-by: Aaron Craelius <aaron@regen.network>
This commit is contained in:
parent
bf8809ef98
commit
a201967fd1
@ -105,6 +105,7 @@ be used to retrieve the actual proposal `Content`. Also the `NewMsgSubmitProposa
|
||||
|
||||
### Features
|
||||
|
||||
* (crypto/multisig) [\#6241](https://github.com/cosmos/cosmos-sdk/pull/6241) Add Multisig type directly to the repo. Previously this was in tendermint.
|
||||
* (rest) [\#6167](https://github.com/cosmos/cosmos-sdk/pull/6167) Support `max-body-bytes` CLI flag for the REST service.
|
||||
* (x/ibc) [\#5588](https://github.com/cosmos/cosmos-sdk/pull/5588) Add [ICS 024 - Host State Machine Requirements](https://github.com/cosmos/ics/tree/master/spec/ics-024-host-requirements) subpackage to `x/ibc` module.
|
||||
* (x/ibc) [\#5277](https://github.com/cosmos/cosmos-sdk/pull/5277) `x/ibc` changes from IBC alpha. For more details check the the [`x/ibc/spec`](https://github.com/cosmos/tree/master/x/ibc/spec) directory:
|
||||
|
||||
248
crypto/types/compact_bit_array.go
Normal file
248
crypto/types/compact_bit_array.go
Normal file
@ -0,0 +1,248 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CompactBitArray is an implementation of a space efficient bit array.
|
||||
// This is used to ensure that the encoded data takes up a minimal amount of
|
||||
// space after amino encoding.
|
||||
// This is not thread safe, and is not intended for concurrent usage.
|
||||
|
||||
// NewCompactBitArray returns a new compact bit array.
|
||||
// It returns nil if the number of bits is zero.
|
||||
func NewCompactBitArray(bits int) *CompactBitArray {
|
||||
if bits <= 0 {
|
||||
return nil
|
||||
}
|
||||
return &CompactBitArray{
|
||||
ExtraBitsStored: uint32(bits % 8),
|
||||
Elems: make([]byte, (bits+7)/8),
|
||||
}
|
||||
}
|
||||
|
||||
// Size returns the number of bits in the bitarray
|
||||
func (bA *CompactBitArray) Size() int {
|
||||
if bA == nil {
|
||||
return 0
|
||||
} else if bA.ExtraBitsStored == uint32(0) {
|
||||
return len(bA.Elems) * 8
|
||||
}
|
||||
|
||||
return (len(bA.Elems)-1)*8 + int(bA.ExtraBitsStored)
|
||||
}
|
||||
|
||||
// GetIndex returns the bit at index i within the bit array.
|
||||
// The behavior is undefined if i >= bA.Size()
|
||||
func (bA *CompactBitArray) GetIndex(i int) bool {
|
||||
if bA == nil {
|
||||
return false
|
||||
}
|
||||
if i >= bA.Size() {
|
||||
return false
|
||||
}
|
||||
|
||||
return bA.Elems[i>>3]&(uint8(1)<<uint8(7-(i%8))) > 0
|
||||
}
|
||||
|
||||
// SetIndex sets the bit at index i within the bit array.
|
||||
// The behavior is undefined if i >= bA.Size()
|
||||
func (bA *CompactBitArray) SetIndex(i int, v bool) bool {
|
||||
if bA == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if i >= bA.Size() {
|
||||
return false
|
||||
}
|
||||
|
||||
if v {
|
||||
bA.Elems[i>>3] |= (uint8(1) << uint8(7-(i%8)))
|
||||
} else {
|
||||
bA.Elems[i>>3] &= ^(uint8(1) << uint8(7-(i%8)))
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// NumTrueBitsBefore returns the number of bits set to true before the
|
||||
// given index. e.g. if bA = _XX__XX, NumOfTrueBitsBefore(4) = 2, since
|
||||
// there are two bits set to true before index 4.
|
||||
func (bA *CompactBitArray) NumTrueBitsBefore(index int) int {
|
||||
numTrueValues := 0
|
||||
for i := 0; i < index; i++ {
|
||||
if bA.GetIndex(i) {
|
||||
numTrueValues++
|
||||
}
|
||||
}
|
||||
|
||||
return numTrueValues
|
||||
}
|
||||
|
||||
// Copy returns a copy of the provided bit array.
|
||||
func (bA *CompactBitArray) Copy() *CompactBitArray {
|
||||
if bA == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
c := make([]byte, len(bA.Elems))
|
||||
copy(c, bA.Elems)
|
||||
|
||||
return &CompactBitArray{
|
||||
ExtraBitsStored: bA.ExtraBitsStored,
|
||||
Elems: c,
|
||||
}
|
||||
}
|
||||
|
||||
// String returns a string representation of CompactBitArray: BA{<bit-string>},
|
||||
// where <bit-string> is a sequence of 'x' (1) and '_' (0).
|
||||
// The <bit-string> includes spaces and newlines to help people.
|
||||
// For a simple sequence of 'x' and '_' characters with no spaces or newlines,
|
||||
// see the MarshalJSON() method.
|
||||
// Example: "BA{_x_}" or "nil-BitArray" for nil.
|
||||
func (bA *CompactBitArray) String() string { return bA.StringIndented("") }
|
||||
|
||||
// StringIndented returns the same thing as String(), but applies the indent
|
||||
// at every 10th bit, and twice at every 50th bit.
|
||||
func (bA *CompactBitArray) StringIndented(indent string) string {
|
||||
if bA == nil {
|
||||
return "nil-BitArray"
|
||||
}
|
||||
lines := []string{}
|
||||
bits := ""
|
||||
size := bA.Size()
|
||||
for i := 0; i < size; i++ {
|
||||
if bA.GetIndex(i) {
|
||||
bits += "x"
|
||||
} else {
|
||||
bits += "_"
|
||||
}
|
||||
|
||||
if i%100 == 99 {
|
||||
lines = append(lines, bits)
|
||||
bits = ""
|
||||
}
|
||||
|
||||
if i%10 == 9 {
|
||||
bits += indent
|
||||
}
|
||||
|
||||
if i%50 == 49 {
|
||||
bits += indent
|
||||
}
|
||||
}
|
||||
|
||||
if len(bits) > 0 {
|
||||
lines = append(lines, bits)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("BA{%v:%v}", size, strings.Join(lines, indent))
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler interface by marshaling bit array
|
||||
// using a custom format: a string of '-' or 'x' where 'x' denotes the 1 bit.
|
||||
func (bA *CompactBitArray) MarshalJSON() ([]byte, error) {
|
||||
if bA == nil {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
|
||||
bits := `"`
|
||||
size := bA.Size()
|
||||
for i := 0; i < size; i++ {
|
||||
if bA.GetIndex(i) {
|
||||
bits += `x`
|
||||
} else {
|
||||
bits += `_`
|
||||
}
|
||||
}
|
||||
|
||||
bits += `"`
|
||||
|
||||
return []byte(bits), nil
|
||||
}
|
||||
|
||||
var bitArrayJSONRegexp = regexp.MustCompile(`\A"([_x]*)"\z`)
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler interface by unmarshaling a custom
|
||||
// JSON description.
|
||||
func (bA *CompactBitArray) UnmarshalJSON(bz []byte) error {
|
||||
b := string(bz)
|
||||
if b == "null" {
|
||||
// This is required e.g. for encoding/json when decoding
|
||||
// into a pointer with pre-allocated BitArray.
|
||||
bA.ExtraBitsStored = 0
|
||||
bA.Elems = nil
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
match := bitArrayJSONRegexp.FindStringSubmatch(b)
|
||||
if match == nil {
|
||||
return fmt.Errorf("bitArray in JSON should be a string of format %q but got %s", bitArrayJSONRegexp.String(), b)
|
||||
}
|
||||
|
||||
bits := match[1]
|
||||
|
||||
// Construct new CompactBitArray and copy over.
|
||||
numBits := len(bits)
|
||||
bA2 := NewCompactBitArray(numBits)
|
||||
for i := 0; i < numBits; i++ {
|
||||
if bits[i] == 'x' {
|
||||
bA2.SetIndex(i, true)
|
||||
}
|
||||
}
|
||||
*bA = *bA2
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CompactMarshal is a space efficient encoding for CompactBitArray.
|
||||
// It is not amino compatible.
|
||||
func (bA *CompactBitArray) CompactMarshal() []byte {
|
||||
size := bA.Size()
|
||||
if size <= 0 {
|
||||
return []byte("null")
|
||||
}
|
||||
|
||||
bz := make([]byte, 0, size/8)
|
||||
// length prefix number of bits, not number of bytes. This difference
|
||||
// takes 3-4 bits in encoding, as opposed to instead encoding the number of
|
||||
// bytes (saving 3-4 bits) and including the offset as a full byte.
|
||||
bz = appendUvarint(bz, uint64(size))
|
||||
bz = append(bz, bA.Elems...)
|
||||
|
||||
return bz
|
||||
}
|
||||
|
||||
// CompactUnmarshal is a space efficient decoding for CompactBitArray.
|
||||
// It is not amino compatible.
|
||||
func CompactUnmarshal(bz []byte) (*CompactBitArray, error) {
|
||||
if len(bz) < 2 {
|
||||
return nil, errors.New("compact bit array: invalid compact unmarshal size")
|
||||
} else if bytes.Equal(bz, []byte("null")) {
|
||||
return NewCompactBitArray(0), nil
|
||||
}
|
||||
|
||||
size, n := binary.Uvarint(bz)
|
||||
bz = bz[n:]
|
||||
|
||||
if len(bz) != int(size+7)/8 {
|
||||
return nil, errors.New("compact bit array: invalid compact unmarshal size")
|
||||
}
|
||||
|
||||
bA := &CompactBitArray{uint32(size % 8), bz}
|
||||
|
||||
return bA, nil
|
||||
}
|
||||
|
||||
func appendUvarint(b []byte, x uint64) []byte {
|
||||
var a [binary.MaxVarintLen64]byte
|
||||
n := binary.PutUvarint(a[:], x)
|
||||
|
||||
return append(b, a[:n]...)
|
||||
}
|
||||
202
crypto/types/compact_bit_array_test.go
Normal file
202
crypto/types/compact_bit_array_test.go
Normal file
@ -0,0 +1,202 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
tmrand "github.com/tendermint/tendermint/libs/rand"
|
||||
)
|
||||
|
||||
func randCompactBitArray(bits int) (*CompactBitArray, []byte) {
|
||||
numBytes := (bits + 7) / 8
|
||||
src := tmrand.Bytes((bits + 7) / 8)
|
||||
bA := NewCompactBitArray(bits)
|
||||
|
||||
for i := 0; i < numBytes-1; i++ {
|
||||
for j := uint8(0); j < 8; j++ {
|
||||
bA.SetIndex(i*8+int(j), src[i]&(uint8(1)<<(8-j)) > 0)
|
||||
}
|
||||
}
|
||||
// Set remaining bits
|
||||
for i := uint32(0); i < 8-bA.ExtraBitsStored; i++ {
|
||||
bA.SetIndex(numBytes*8+int(i), src[numBytes-1]&(uint8(1)<<(8-i)) > 0)
|
||||
}
|
||||
return bA, src
|
||||
}
|
||||
|
||||
func TestNewBitArrayNeverCrashesOnNegatives(t *testing.T) {
|
||||
bitList := []int{-127, -128, -1 << 31}
|
||||
for _, bits := range bitList {
|
||||
bA := NewCompactBitArray(bits)
|
||||
require.Nil(t, bA)
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONMarshalUnmarshal(t *testing.T) {
|
||||
|
||||
bA1 := NewCompactBitArray(0)
|
||||
bA2 := NewCompactBitArray(1)
|
||||
|
||||
bA3 := NewCompactBitArray(1)
|
||||
bA3.SetIndex(0, true)
|
||||
|
||||
bA4 := NewCompactBitArray(5)
|
||||
bA4.SetIndex(0, true)
|
||||
bA4.SetIndex(1, true)
|
||||
|
||||
bA5 := NewCompactBitArray(9)
|
||||
bA5.SetIndex(0, true)
|
||||
bA5.SetIndex(1, true)
|
||||
bA5.SetIndex(8, true)
|
||||
|
||||
bA6 := NewCompactBitArray(16)
|
||||
bA6.SetIndex(0, true)
|
||||
bA6.SetIndex(1, true)
|
||||
bA6.SetIndex(8, false)
|
||||
bA6.SetIndex(15, true)
|
||||
|
||||
testCases := []struct {
|
||||
bA *CompactBitArray
|
||||
marshalledBA string
|
||||
}{
|
||||
{nil, `null`},
|
||||
{bA1, `null`},
|
||||
{bA2, `"_"`},
|
||||
{bA3, `"x"`},
|
||||
{bA4, `"xx___"`},
|
||||
{bA5, `"xx______x"`},
|
||||
{bA6, `"xx_____________x"`},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.bA.String(), func(t *testing.T) {
|
||||
bz, err := json.Marshal(tc.bA)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, tc.marshalledBA, string(bz))
|
||||
|
||||
var unmarshalledBA *CompactBitArray
|
||||
err = json.Unmarshal(bz, &unmarshalledBA)
|
||||
require.NoError(t, err)
|
||||
|
||||
if tc.bA == nil {
|
||||
require.Nil(t, unmarshalledBA)
|
||||
} else {
|
||||
require.NotNil(t, unmarshalledBA)
|
||||
assert.EqualValues(t, tc.bA.Elems, unmarshalledBA.Elems)
|
||||
if assert.EqualValues(t, tc.bA.String(), unmarshalledBA.String()) {
|
||||
assert.EqualValues(t, tc.bA.Elems, unmarshalledBA.Elems)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompactMarshalUnmarshal(t *testing.T) {
|
||||
bA1 := NewCompactBitArray(0)
|
||||
bA2 := NewCompactBitArray(1)
|
||||
|
||||
bA3 := NewCompactBitArray(1)
|
||||
bA3.SetIndex(0, true)
|
||||
|
||||
bA4 := NewCompactBitArray(5)
|
||||
bA4.SetIndex(0, true)
|
||||
bA4.SetIndex(1, true)
|
||||
|
||||
bA5 := NewCompactBitArray(9)
|
||||
bA5.SetIndex(0, true)
|
||||
bA5.SetIndex(1, true)
|
||||
bA5.SetIndex(8, true)
|
||||
|
||||
bA6 := NewCompactBitArray(16)
|
||||
bA6.SetIndex(0, true)
|
||||
bA6.SetIndex(1, true)
|
||||
bA6.SetIndex(8, false)
|
||||
bA6.SetIndex(15, true)
|
||||
|
||||
testCases := []struct {
|
||||
bA *CompactBitArray
|
||||
marshalledBA []byte
|
||||
}{
|
||||
{nil, []byte("null")},
|
||||
{bA1, []byte("null")},
|
||||
{bA2, []byte{byte(1), byte(0)}},
|
||||
{bA3, []byte{byte(1), byte(128)}},
|
||||
{bA4, []byte{byte(5), byte(192)}},
|
||||
{bA5, []byte{byte(9), byte(192), byte(128)}},
|
||||
{bA6, []byte{byte(16), byte(192), byte(1)}},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.bA.String(), func(t *testing.T) {
|
||||
bz := tc.bA.CompactMarshal()
|
||||
|
||||
assert.Equal(t, tc.marshalledBA, bz)
|
||||
|
||||
unmarshalledBA, err := CompactUnmarshal(bz)
|
||||
require.NoError(t, err)
|
||||
if tc.bA == nil {
|
||||
require.Nil(t, unmarshalledBA)
|
||||
} else {
|
||||
require.NotNil(t, unmarshalledBA)
|
||||
assert.EqualValues(t, tc.bA.Elems, unmarshalledBA.Elems)
|
||||
if assert.EqualValues(t, tc.bA.String(), unmarshalledBA.String()) {
|
||||
assert.EqualValues(t, tc.bA.Elems, unmarshalledBA.Elems)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompactBitArrayNumOfTrueBitsBefore(t *testing.T) {
|
||||
testCases := []struct {
|
||||
marshalledBA string
|
||||
bAIndex []int
|
||||
trueValueIndex []int
|
||||
}{
|
||||
{`"_____"`, []int{0, 1, 2, 3, 4}, []int{0, 0, 0, 0, 0}},
|
||||
{`"x"`, []int{0}, []int{0}},
|
||||
{`"_x"`, []int{1}, []int{0}},
|
||||
{`"x___xxxx"`, []int{0, 4, 5, 6, 7}, []int{0, 1, 2, 3, 4}},
|
||||
{`"__x_xx_x__x_x___"`, []int{2, 4, 5, 7, 10, 12}, []int{0, 1, 2, 3, 4, 5}},
|
||||
{`"______________xx"`, []int{14, 15}, []int{0, 1}},
|
||||
}
|
||||
for tcIndex, tc := range testCases {
|
||||
tc := tc
|
||||
tcIndex := tcIndex
|
||||
t.Run(tc.marshalledBA, func(t *testing.T) {
|
||||
var bA *CompactBitArray
|
||||
err := json.Unmarshal([]byte(tc.marshalledBA), &bA)
|
||||
require.NoError(t, err)
|
||||
|
||||
for i := 0; i < len(tc.bAIndex); i++ {
|
||||
|
||||
require.Equal(t, tc.trueValueIndex[i], bA.NumTrueBitsBefore(tc.bAIndex[i]), "tc %d, i %d", tcIndex, i)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompactBitArrayGetSetIndex(t *testing.T) {
|
||||
r := rand.New(rand.NewSource(100))
|
||||
numTests := 10
|
||||
numBitsPerArr := 100
|
||||
for i := 0; i < numTests; i++ {
|
||||
bits := r.Intn(1000)
|
||||
bA, _ := randCompactBitArray(bits)
|
||||
|
||||
for j := 0; j < numBitsPerArr; j++ {
|
||||
copy := bA.Copy()
|
||||
index := r.Intn(bits)
|
||||
val := (r.Int63() % 2) == 0
|
||||
bA.SetIndex(index, val)
|
||||
require.Equal(t, val, bA.GetIndex(index), "bA.SetIndex(%d, %v) failed on bit array: %s", index, val, copy)
|
||||
}
|
||||
}
|
||||
}
|
||||
30
crypto/types/multisig/codec.go
Normal file
30
crypto/types/multisig/codec.go
Normal file
@ -0,0 +1,30 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
amino "github.com/tendermint/go-amino"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
"github.com/tendermint/tendermint/crypto/sr25519"
|
||||
)
|
||||
|
||||
// TODO: Figure out API for others to either add their own pubkey types, or
|
||||
// to make verify / marshal accept a cdc.
|
||||
const (
|
||||
PubKeyAminoRoute = "tendermint/PubKeyMultisigThreshold"
|
||||
)
|
||||
|
||||
var cdc = amino.NewCodec()
|
||||
|
||||
func init() {
|
||||
cdc.RegisterInterface((*crypto.PubKey)(nil), nil)
|
||||
cdc.RegisterConcrete(PubKey{},
|
||||
PubKeyAminoRoute, nil)
|
||||
cdc.RegisterConcrete(ed25519.PubKeyEd25519{},
|
||||
ed25519.PubKeyAminoName, nil)
|
||||
cdc.RegisterConcrete(sr25519.PubKeySr25519{},
|
||||
sr25519.PubKeyAminoName, nil)
|
||||
cdc.RegisterConcrete(secp256k1.PubKeySecp256k1{},
|
||||
secp256k1.PubKeyAminoName, nil)
|
||||
}
|
||||
77
crypto/types/multisig/multisignature.go
Normal file
77
crypto/types/multisig/multisignature.go
Normal file
@ -0,0 +1,77 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
)
|
||||
|
||||
// Multisignature is used to represent the signature object used in the multisigs.
|
||||
// Sigs is a list of signatures, sorted by corresponding index.
|
||||
type Multisignature struct {
|
||||
BitArray *types.CompactBitArray
|
||||
Sigs [][]byte
|
||||
}
|
||||
|
||||
// NewMultisig returns a new Multisignature of size n.
|
||||
func NewMultisig(n int) *Multisignature {
|
||||
// Default the signature list to have a capacity of two, since we can
|
||||
// expect that most multisigs will require multiple signers.
|
||||
return &Multisignature{types.NewCompactBitArray(n), make([][]byte, 0, 2)}
|
||||
}
|
||||
|
||||
// GetIndex returns the index of pk in keys. Returns -1 if not found
|
||||
func getIndex(pk crypto.PubKey, keys []crypto.PubKey) int {
|
||||
for i := 0; i < len(keys); i++ {
|
||||
if pk.Equals(keys[i]) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// AddSignature adds a signature to the multisig, at the corresponding index.
|
||||
// If the signature already exists, replace it.
|
||||
func (mSig *Multisignature) AddSignature(sig []byte, index int) {
|
||||
newSigIndex := mSig.BitArray.NumTrueBitsBefore(index)
|
||||
// Signature already exists, just replace the value there
|
||||
if mSig.BitArray.GetIndex(index) {
|
||||
mSig.Sigs[newSigIndex] = sig
|
||||
return
|
||||
}
|
||||
mSig.BitArray.SetIndex(index, true)
|
||||
// Optimization if the index is the greatest index
|
||||
if newSigIndex == len(mSig.Sigs) {
|
||||
mSig.Sigs = append(mSig.Sigs, sig)
|
||||
return
|
||||
}
|
||||
// Expand slice by one with a dummy element, move all elements after i
|
||||
// over by one, then place the new signature in that gap.
|
||||
mSig.Sigs = append(mSig.Sigs, make([]byte, 0))
|
||||
copy(mSig.Sigs[newSigIndex+1:], mSig.Sigs[newSigIndex:])
|
||||
mSig.Sigs[newSigIndex] = sig
|
||||
}
|
||||
|
||||
// AddSignatureFromPubKey adds a signature to the multisig, at the index in
|
||||
// keys corresponding to the provided pubkey.
|
||||
func (mSig *Multisignature) AddSignatureFromPubKey(sig []byte, pubkey crypto.PubKey, keys []crypto.PubKey) error {
|
||||
index := getIndex(pubkey, keys)
|
||||
if index == -1 {
|
||||
keysStr := make([]string, len(keys))
|
||||
for i, k := range keys {
|
||||
keysStr[i] = fmt.Sprintf("%X", k.Bytes())
|
||||
}
|
||||
|
||||
return fmt.Errorf("provided key %X doesn't exist in pubkeys: \n%s", pubkey.Bytes(), strings.Join(keysStr, "\n"))
|
||||
}
|
||||
|
||||
mSig.AddSignature(sig, index)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Marshal the multisignature with amino
|
||||
func (mSig *Multisignature) Marshal() []byte {
|
||||
return cdc.MustMarshalBinaryBare(mSig)
|
||||
}
|
||||
96
crypto/types/multisig/threshold_pubkey.go
Normal file
96
crypto/types/multisig/threshold_pubkey.go
Normal file
@ -0,0 +1,96 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
)
|
||||
|
||||
// PubKey implements a K of N threshold multisig.
|
||||
type PubKey struct {
|
||||
K uint `json:"threshold"`
|
||||
PubKeys []crypto.PubKey `json:"pubkeys"`
|
||||
}
|
||||
|
||||
var _ crypto.PubKey = PubKey{}
|
||||
|
||||
// NewPubKeyMultisigThreshold returns a new PubKeyMultisigThreshold.
|
||||
// Panics if len(pubkeys) < k or 0 >= k.
|
||||
func NewPubKeyMultisigThreshold(k int, pubkeys []crypto.PubKey) crypto.PubKey {
|
||||
if k <= 0 {
|
||||
panic("threshold k of n multisignature: k <= 0")
|
||||
}
|
||||
if len(pubkeys) < k {
|
||||
panic("threshold k of n multisignature: len(pubkeys) < k")
|
||||
}
|
||||
for _, pubkey := range pubkeys {
|
||||
if pubkey == nil {
|
||||
panic("nil pubkey")
|
||||
}
|
||||
}
|
||||
return PubKey{uint(k), pubkeys}
|
||||
}
|
||||
|
||||
// VerifyBytes expects sig to be an amino encoded version of a MultiSignature.
|
||||
// Returns true iff the multisignature contains k or more signatures
|
||||
// for the correct corresponding keys,
|
||||
// and all signatures are valid. (Not just k of the signatures)
|
||||
// The multisig uses a bitarray, so multiple signatures for the same key is not
|
||||
// a concern.
|
||||
func (pk PubKey) VerifyBytes(msg []byte, marshalledSig []byte) bool {
|
||||
var sig Multisignature
|
||||
err := cdc.UnmarshalBinaryBare(marshalledSig, &sig)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
size := sig.BitArray.Size()
|
||||
// ensure bit array is the correct size
|
||||
if len(pk.PubKeys) != size {
|
||||
return false
|
||||
}
|
||||
// ensure size of signature list
|
||||
if len(sig.Sigs) < int(pk.K) || len(sig.Sigs) > size {
|
||||
return false
|
||||
}
|
||||
// ensure at least k signatures are set
|
||||
if sig.BitArray.NumTrueBitsBefore(size) < int(pk.K) {
|
||||
return false
|
||||
}
|
||||
// index in the list of signatures which we are concerned with.
|
||||
sigIndex := 0
|
||||
for i := 0; i < size; i++ {
|
||||
if sig.BitArray.GetIndex(i) {
|
||||
if !pk.PubKeys[i].VerifyBytes(msg, sig.Sigs[sigIndex]) {
|
||||
return false
|
||||
}
|
||||
sigIndex++
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Bytes returns the amino encoded version of the PubKey
|
||||
func (pk PubKey) Bytes() []byte {
|
||||
return cdc.MustMarshalBinaryBare(pk)
|
||||
}
|
||||
|
||||
// Address returns tmhash(PubKey.Bytes())
|
||||
func (pk PubKey) Address() crypto.Address {
|
||||
return crypto.AddressHash(pk.Bytes())
|
||||
}
|
||||
|
||||
// Equals returns true iff pk and other both have the same number of keys, and
|
||||
// all constituent keys are the same, and in the same order.
|
||||
func (pk PubKey) Equals(other crypto.PubKey) bool {
|
||||
otherKey, sameType := other.(PubKey)
|
||||
if !sameType {
|
||||
return false
|
||||
}
|
||||
if pk.K != otherKey.K || len(pk.PubKeys) != len(otherKey.PubKeys) {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(pk.PubKeys); i++ {
|
||||
if !pk.PubKeys[i].Equals(otherKey.PubKeys[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
186
crypto/types/multisig/threshold_pubkey_test.go
Normal file
186
crypto/types/multisig/threshold_pubkey_test.go
Normal file
@ -0,0 +1,186 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
"github.com/tendermint/tendermint/crypto/sr25519"
|
||||
)
|
||||
|
||||
// This tests multisig functionality, but it expects the first k signatures to be valid
|
||||
// TODO: Adapt it to give more flexibility about first k signatures being valid
|
||||
func TestThresholdMultisigValidCases(t *testing.T) {
|
||||
pkSet1, sigSet1 := generatePubKeysAndSignatures(5, []byte{1, 2, 3, 4})
|
||||
cases := []struct {
|
||||
msg []byte
|
||||
k int
|
||||
pubkeys []crypto.PubKey
|
||||
signingIndices []int
|
||||
// signatures should be the same size as signingIndices.
|
||||
signatures [][]byte
|
||||
passAfterKSignatures []bool
|
||||
}{
|
||||
{
|
||||
msg: []byte{1, 2, 3, 4},
|
||||
k: 2,
|
||||
pubkeys: pkSet1,
|
||||
signingIndices: []int{0, 3, 1},
|
||||
signatures: sigSet1,
|
||||
passAfterKSignatures: []bool{false},
|
||||
},
|
||||
}
|
||||
for tcIndex, tc := range cases {
|
||||
multisigKey := NewPubKeyMultisigThreshold(tc.k, tc.pubkeys)
|
||||
multisignature := NewMultisig(len(tc.pubkeys))
|
||||
|
||||
for i := 0; i < tc.k-1; i++ {
|
||||
signingIndex := tc.signingIndices[i]
|
||||
require.NoError(
|
||||
t,
|
||||
multisignature.AddSignatureFromPubKey(tc.signatures[signingIndex], tc.pubkeys[signingIndex], tc.pubkeys),
|
||||
)
|
||||
bz := multisignature.Marshal()
|
||||
require.False(
|
||||
t,
|
||||
multisigKey.VerifyBytes(tc.msg, bz),
|
||||
"multisig passed when i < k, tc %d, i %d", tcIndex, i,
|
||||
)
|
||||
require.NoError(
|
||||
t,
|
||||
multisignature.AddSignatureFromPubKey(tc.signatures[signingIndex], tc.pubkeys[signingIndex], tc.pubkeys),
|
||||
)
|
||||
require.Equal(
|
||||
t,
|
||||
i+1,
|
||||
len(multisignature.Sigs),
|
||||
"adding a signature for the same pubkey twice increased signature count by 2, tc %d", tcIndex,
|
||||
)
|
||||
}
|
||||
bz := multisignature.Marshal()
|
||||
require.False(
|
||||
t,
|
||||
multisigKey.VerifyBytes(tc.msg, bz),
|
||||
"multisig passed with k - 1 sigs, tc %d", tcIndex,
|
||||
)
|
||||
require.NoError(
|
||||
t,
|
||||
multisignature.AddSignatureFromPubKey(
|
||||
tc.signatures[tc.signingIndices[tc.k]],
|
||||
tc.pubkeys[tc.signingIndices[tc.k]],
|
||||
tc.pubkeys,
|
||||
),
|
||||
)
|
||||
bz = multisignature.Marshal()
|
||||
require.True(
|
||||
t,
|
||||
multisigKey.VerifyBytes(tc.msg, bz),
|
||||
"multisig failed after k good signatures, tc %d", tcIndex,
|
||||
)
|
||||
|
||||
for i := tc.k + 1; i < len(tc.signingIndices); i++ {
|
||||
signingIndex := tc.signingIndices[i]
|
||||
|
||||
require.NoError(
|
||||
t,
|
||||
multisignature.AddSignatureFromPubKey(tc.signatures[signingIndex], tc.pubkeys[signingIndex], tc.pubkeys),
|
||||
)
|
||||
bz := multisignature.Marshal()
|
||||
require.Equal(
|
||||
t,
|
||||
tc.passAfterKSignatures[i-tc.k-1],
|
||||
multisigKey.VerifyBytes(tc.msg, bz),
|
||||
"multisig didn't verify as expected after k sigs, tc %d, i %d", tcIndex, i,
|
||||
)
|
||||
require.NoError(
|
||||
t,
|
||||
multisignature.AddSignatureFromPubKey(tc.signatures[signingIndex], tc.pubkeys[signingIndex], tc.pubkeys),
|
||||
)
|
||||
require.Equal(
|
||||
t,
|
||||
i+1,
|
||||
len(multisignature.Sigs),
|
||||
"adding a signature for the same pubkey twice increased signature count by 2, tc %d", tcIndex,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Fully replace this test with table driven tests
|
||||
func TestThresholdMultisigDuplicateSignatures(t *testing.T) {
|
||||
msg := []byte{1, 2, 3, 4, 5}
|
||||
pubkeys, sigs := generatePubKeysAndSignatures(5, msg)
|
||||
multisigKey := NewPubKeyMultisigThreshold(2, pubkeys)
|
||||
multisignature := NewMultisig(5)
|
||||
bz := multisignature.Marshal()
|
||||
|
||||
require.False(t, multisigKey.VerifyBytes(msg, bz))
|
||||
multisignature.AddSignatureFromPubKey(sigs[0], pubkeys[0], pubkeys)
|
||||
// Add second signature manually
|
||||
multisignature.Sigs = append(multisignature.Sigs, sigs[0])
|
||||
require.False(t, multisigKey.VerifyBytes(msg, bz))
|
||||
}
|
||||
|
||||
// TODO: Fully replace this test with table driven tests
|
||||
func TestMultiSigPubKeyEquality(t *testing.T) {
|
||||
msg := []byte{1, 2, 3, 4}
|
||||
pubkeys, _ := generatePubKeysAndSignatures(5, msg)
|
||||
multisigKey := NewPubKeyMultisigThreshold(2, pubkeys)
|
||||
var unmarshalledMultisig PubKey
|
||||
cdc.MustUnmarshalBinaryBare(multisigKey.Bytes(), &unmarshalledMultisig)
|
||||
require.True(t, multisigKey.Equals(unmarshalledMultisig))
|
||||
|
||||
// Ensure that reordering pubkeys is treated as a different pubkey
|
||||
pubkeysCpy := make([]crypto.PubKey, 5)
|
||||
copy(pubkeysCpy, pubkeys)
|
||||
pubkeysCpy[4] = pubkeys[3]
|
||||
pubkeysCpy[3] = pubkeys[4]
|
||||
multisigKey2 := NewPubKeyMultisigThreshold(2, pubkeysCpy)
|
||||
require.False(t, multisigKey.Equals(multisigKey2))
|
||||
}
|
||||
|
||||
func TestAddress(t *testing.T) {
|
||||
msg := []byte{1, 2, 3, 4}
|
||||
pubkeys, _ := generatePubKeysAndSignatures(5, msg)
|
||||
multisigKey := NewPubKeyMultisigThreshold(2, pubkeys)
|
||||
require.Len(t, multisigKey.Address().Bytes(), 20)
|
||||
}
|
||||
|
||||
func TestPubKeyMultisigThresholdAminoToIface(t *testing.T) {
|
||||
msg := []byte{1, 2, 3, 4}
|
||||
pubkeys, _ := generatePubKeysAndSignatures(5, msg)
|
||||
multisigKey := NewPubKeyMultisigThreshold(2, pubkeys)
|
||||
|
||||
ab, err := cdc.MarshalBinaryLengthPrefixed(multisigKey)
|
||||
require.NoError(t, err)
|
||||
// like other crypto.Pubkey implementations (e.g. ed25519.PubKey),
|
||||
// PubKey should be deserializable into a crypto.PubKey:
|
||||
var pubKey crypto.PubKey
|
||||
err = cdc.UnmarshalBinaryLengthPrefixed(ab, &pubKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, multisigKey, pubKey)
|
||||
}
|
||||
|
||||
func generatePubKeysAndSignatures(n int, msg []byte) (pubkeys []crypto.PubKey, signatures [][]byte) {
|
||||
pubkeys = make([]crypto.PubKey, n)
|
||||
signatures = make([][]byte, n)
|
||||
for i := 0; i < n; i++ {
|
||||
var privkey crypto.PrivKey
|
||||
switch rand.Int63() % 3 {
|
||||
case 0:
|
||||
privkey = ed25519.GenPrivKey()
|
||||
case 1:
|
||||
privkey = secp256k1.GenPrivKey()
|
||||
case 2:
|
||||
privkey = sr25519.GenPrivKey()
|
||||
}
|
||||
pubkeys[i] = privkey.PubKey()
|
||||
signatures[i], _ = privkey.Sign(msg)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -274,9 +274,8 @@ type CompactBitArray struct {
|
||||
Elems []byte `protobuf:"bytes,2,opt,name=elems,proto3" json:"elems,omitempty"`
|
||||
}
|
||||
|
||||
func (m *CompactBitArray) Reset() { *m = CompactBitArray{} }
|
||||
func (m *CompactBitArray) String() string { return proto.CompactTextString(m) }
|
||||
func (*CompactBitArray) ProtoMessage() {}
|
||||
func (m *CompactBitArray) Reset() { *m = CompactBitArray{} }
|
||||
func (*CompactBitArray) ProtoMessage() {}
|
||||
func (*CompactBitArray) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2165b2a1badb1b0c, []int{3}
|
||||
}
|
||||
@ -299,7 +298,7 @@ func (m *CompactBitArray) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CompactBitArray.Merge(m, src)
|
||||
}
|
||||
func (m *CompactBitArray) XXX_Size() int {
|
||||
return m.Size()
|
||||
return xxx_messageInfo_CompactBitArray.Size(m)
|
||||
}
|
||||
func (m *CompactBitArray) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CompactBitArray.DiscardUnknown(m)
|
||||
@ -331,38 +330,39 @@ func init() {
|
||||
func init() { proto.RegisterFile("crypto/types/types.proto", fileDescriptor_2165b2a1badb1b0c) }
|
||||
|
||||
var fileDescriptor_2165b2a1badb1b0c = []byte{
|
||||
// 488 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x52, 0xdd, 0x8a, 0xd3, 0x40,
|
||||
0x18, 0x4d, 0xda, 0xad, 0xb5, 0xb3, 0xeb, 0x56, 0x87, 0x82, 0xd9, 0x82, 0x49, 0x09, 0x22, 0x55,
|
||||
0xd8, 0x84, 0x54, 0xaa, 0xe8, 0xdd, 0x66, 0x6f, 0x16, 0x8a, 0x50, 0x52, 0x2f, 0xc4, 0x9b, 0x90,
|
||||
0x9f, 0x31, 0x1d, 0x9a, 0x64, 0xc2, 0xcc, 0x44, 0x9c, 0x97, 0x10, 0x1f, 0xc4, 0x07, 0xf1, 0x72,
|
||||
0x2f, 0xbd, 0x2a, 0x92, 0xbe, 0xc1, 0x3e, 0x81, 0x6c, 0x26, 0xd9, 0x2e, 0x62, 0x6f, 0x92, 0x99,
|
||||
0xef, 0x9c, 0xef, 0xe4, 0x9c, 0xef, 0x0b, 0xd0, 0x22, 0x2a, 0x0a, 0x4e, 0x6c, 0x2e, 0x0a, 0xc4,
|
||||
0xe4, 0xd3, 0x2a, 0x28, 0xe1, 0x04, 0x8e, 0x22, 0xc2, 0x32, 0xc2, 0x7c, 0x16, 0x6f, 0x2c, 0x49,
|
||||
0xb2, 0xbe, 0x3a, 0xe3, 0x17, 0x7c, 0x8d, 0x69, 0xec, 0x17, 0x01, 0xe5, 0xc2, 0xae, 0x89, 0x76,
|
||||
0x42, 0x12, 0xb2, 0x3f, 0xc9, 0xee, 0xf1, 0x59, 0x42, 0x48, 0x92, 0x22, 0x49, 0x09, 0xcb, 0x2f,
|
||||
0x76, 0x90, 0x0b, 0x09, 0x99, 0xdf, 0x3b, 0x60, 0xb0, 0x2c, 0xc3, 0x14, 0x47, 0x0b, 0x24, 0xa0,
|
||||
0x0e, 0x06, 0x0c, 0x45, 0xc5, 0x6c, 0xfe, 0x66, 0xe3, 0x68, 0xea, 0x44, 0x9d, 0x9e, 0x5c, 0x29,
|
||||
0xde, 0xbe, 0x04, 0xc7, 0xa0, 0x8f, 0xe2, 0xd9, 0x7c, 0xee, 0xbc, 0xd3, 0x3a, 0x0d, 0xda, 0x16,
|
||||
0x6e, 0x31, 0x46, 0x25, 0xd6, 0x6d, 0xb1, 0xa6, 0x00, 0x17, 0xe0, 0x61, 0x56, 0xa6, 0x1c, 0x33,
|
||||
0x9c, 0x68, 0x47, 0x13, 0x75, 0x7a, 0x3c, 0x3b, 0xb7, 0xfe, 0x97, 0xc8, 0x5a, 0x96, 0xe1, 0x02,
|
||||
0x89, 0x0f, 0x0d, 0xf7, 0xe3, 0x9a, 0x22, 0xb6, 0x26, 0x69, 0x7c, 0xa5, 0x78, 0x77, 0x02, 0xf7,
|
||||
0x4c, 0x52, 0x47, 0xeb, 0xfd, 0x63, 0x92, 0x3a, 0x70, 0x0e, 0x40, 0x90, 0x0b, 0xbf, 0x28, 0xc3,
|
||||
0x0d, 0x12, 0xda, 0xb0, 0xfe, 0xdc, 0xc8, 0x92, 0x23, 0xb0, 0xda, 0x11, 0x58, 0x17, 0xb9, 0xb8,
|
||||
0x6d, 0x0b, 0x72, 0xb1, 0xac, 0x89, 0x6e, 0x0f, 0x74, 0x59, 0x99, 0x99, 0x3f, 0x55, 0xf0, 0xf4,
|
||||
0x80, 0x0b, 0xf8, 0x16, 0x0c, 0x78, 0x7b, 0xa9, 0xc7, 0xf3, 0xc8, 0x3d, 0xab, 0xb6, 0x86, 0xba,
|
||||
0xb8, 0xd9, 0x1a, 0x8f, 0x45, 0x90, 0xa5, 0xef, 0xcd, 0x3b, 0xdc, 0xf4, 0xf6, 0x5c, 0xf8, 0x09,
|
||||
0xf4, 0xa5, 0x1d, 0xa6, 0x75, 0x26, 0xdd, 0xe9, 0xf1, 0xcc, 0x38, 0x18, 0x5f, 0x6e, 0xc2, 0x7d,
|
||||
0x56, 0x6d, 0x8d, 0xbe, 0xf4, 0xc1, 0x6e, 0xb6, 0xc6, 0xa9, 0x54, 0x6f, 0x44, 0x4c, 0xaf, 0x95,
|
||||
0x33, 0x9f, 0x83, 0xd3, 0xda, 0xe7, 0x0a, 0x27, 0x79, 0xc0, 0x4b, 0x8a, 0x20, 0x04, 0x47, 0x0c,
|
||||
0x27, 0x4c, 0x53, 0x27, 0xdd, 0xe9, 0x89, 0x57, 0x9f, 0xcd, 0x15, 0x18, 0x5e, 0x92, 0xac, 0x08,
|
||||
0x22, 0xee, 0x62, 0x7e, 0x41, 0x69, 0x20, 0xe0, 0x2b, 0xf0, 0x04, 0x7d, 0xe3, 0x34, 0xf0, 0x43,
|
||||
0xcc, 0x99, 0xcf, 0x38, 0xa1, 0xa8, 0xc9, 0xe4, 0x0d, 0x6b, 0xc0, 0xc5, 0x9c, 0xad, 0xea, 0x32,
|
||||
0x1c, 0x81, 0x1e, 0x4a, 0x51, 0xc6, 0xe4, 0xd2, 0x3d, 0x79, 0x71, 0x2f, 0x7f, 0x55, 0xba, 0x7a,
|
||||
0x5d, 0xe9, 0xea, 0x9f, 0x4a, 0x57, 0x7f, 0xec, 0x74, 0xe5, 0x7a, 0xa7, 0x2b, 0xbf, 0x77, 0xba,
|
||||
0xf2, 0xf9, 0x65, 0x82, 0xf9, 0xba, 0x0c, 0xad, 0x88, 0x64, 0xb6, 0xcc, 0xd9, 0xbc, 0xce, 0x59,
|
||||
0xbc, 0xb1, 0xef, 0xff, 0xe4, 0xe1, 0x83, 0x7a, 0x21, 0xaf, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff,
|
||||
0x82, 0xd0, 0x7b, 0xf3, 0xfb, 0x02, 0x00, 0x00,
|
||||
// 501 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x52, 0xcd, 0x6a, 0xdb, 0x40,
|
||||
0x18, 0x94, 0xec, 0xb8, 0x8e, 0x37, 0x69, 0xdc, 0x2e, 0x86, 0x2a, 0x86, 0x4a, 0x46, 0x94, 0xe2,
|
||||
0x16, 0x22, 0x61, 0x17, 0xb7, 0x34, 0xb7, 0x28, 0x97, 0x80, 0x29, 0x18, 0xa5, 0x87, 0x52, 0x28,
|
||||
0x42, 0x3f, 0x5b, 0x79, 0xb1, 0xa4, 0x15, 0xbb, 0xab, 0xd2, 0x7d, 0x89, 0xd2, 0x63, 0x8f, 0xe9,
|
||||
0xbd, 0x0f, 0xd2, 0x63, 0x8e, 0x3d, 0x99, 0x22, 0xbf, 0x41, 0x9e, 0xa0, 0x44, 0x2b, 0xc5, 0xa1,
|
||||
0x24, 0x17, 0x69, 0xf7, 0x9b, 0xf9, 0x46, 0x33, 0xdf, 0x27, 0xa0, 0x85, 0x54, 0xe4, 0x9c, 0xd8,
|
||||
0x5c, 0xe4, 0x88, 0xc9, 0xa7, 0x95, 0x53, 0xc2, 0x09, 0x1c, 0x84, 0x84, 0xa5, 0x84, 0x79, 0x2c,
|
||||
0x5a, 0x59, 0x92, 0x64, 0x7d, 0x99, 0x0c, 0x9f, 0xf3, 0x25, 0xa6, 0x91, 0x97, 0xfb, 0x94, 0x0b,
|
||||
0xbb, 0x22, 0xda, 0x31, 0x89, 0xc9, 0xf6, 0x24, 0xbb, 0x87, 0x87, 0x31, 0x21, 0x71, 0x82, 0x24,
|
||||
0x25, 0x28, 0x3e, 0xdb, 0x7e, 0x26, 0x24, 0x64, 0x7e, 0x6b, 0x81, 0xde, 0xa2, 0x08, 0x12, 0x1c,
|
||||
0xce, 0x91, 0x80, 0x3a, 0xe8, 0x31, 0x14, 0xe6, 0xd3, 0xd9, 0xeb, 0xd5, 0x44, 0x53, 0x47, 0xea,
|
||||
0x78, 0xff, 0x4c, 0x71, 0xb7, 0x25, 0x38, 0x04, 0x5d, 0x14, 0x4d, 0x67, 0xb3, 0xc9, 0x5b, 0xad,
|
||||
0x55, 0xa3, 0x4d, 0xe1, 0x1a, 0x63, 0x54, 0x62, 0xed, 0x06, 0xab, 0x0b, 0x70, 0x0e, 0x76, 0xd3,
|
||||
0x22, 0xe1, 0x98, 0xe1, 0x58, 0xdb, 0x19, 0xa9, 0xe3, 0xbd, 0xe9, 0x91, 0x75, 0x57, 0x22, 0x6b,
|
||||
0x51, 0x04, 0x73, 0x24, 0xde, 0xd5, 0xdc, 0xf7, 0x4b, 0x8a, 0xd8, 0x92, 0x24, 0xd1, 0x99, 0xe2,
|
||||
0xde, 0x08, 0xdc, 0x32, 0x49, 0x27, 0x5a, 0xe7, 0x3f, 0x93, 0x74, 0x02, 0x67, 0x00, 0xf8, 0x99,
|
||||
0xf0, 0xf2, 0x22, 0x58, 0x21, 0xa1, 0xf5, 0xab, 0xcf, 0x0d, 0x2c, 0x39, 0x02, 0xab, 0x19, 0x81,
|
||||
0x75, 0x92, 0x89, 0xeb, 0x36, 0x3f, 0x13, 0x8b, 0x8a, 0xe8, 0x74, 0x40, 0x9b, 0x15, 0xa9, 0xf9,
|
||||
0x4b, 0x05, 0x4f, 0xee, 0x71, 0x01, 0xdf, 0x80, 0x1e, 0x6f, 0x2e, 0xd5, 0x78, 0x1e, 0x3a, 0x87,
|
||||
0xe5, 0xda, 0x50, 0xe7, 0x57, 0x6b, 0xe3, 0x91, 0xf0, 0xd3, 0xe4, 0xd8, 0xbc, 0xc1, 0x4d, 0x77,
|
||||
0xcb, 0x85, 0x1f, 0x40, 0x57, 0xda, 0x61, 0x5a, 0x6b, 0xd4, 0x1e, 0xef, 0x4d, 0x8d, 0x7b, 0xe3,
|
||||
0xcb, 0x4d, 0x38, 0x4f, 0xcb, 0xb5, 0xd1, 0x95, 0x3e, 0xd8, 0xd5, 0xda, 0x38, 0x90, 0xea, 0xb5,
|
||||
0x88, 0xe9, 0x36, 0x72, 0xe6, 0x33, 0x70, 0x50, 0xf9, 0x3c, 0xc7, 0x71, 0xe6, 0xf3, 0x82, 0x22,
|
||||
0x08, 0xc1, 0x0e, 0xc3, 0x31, 0xd3, 0xd4, 0x51, 0x7b, 0xbc, 0xef, 0x56, 0x67, 0xf3, 0x13, 0xe8,
|
||||
0x9f, 0x92, 0x34, 0xf7, 0x43, 0xee, 0x60, 0x7e, 0x42, 0xa9, 0x2f, 0xe0, 0x4b, 0xf0, 0x18, 0x7d,
|
||||
0xe5, 0xd4, 0xf7, 0x02, 0xcc, 0x99, 0xc7, 0x38, 0xa1, 0xa8, 0xce, 0xe4, 0xf6, 0x2b, 0xc0, 0xc1,
|
||||
0x9c, 0x9d, 0x57, 0x65, 0x38, 0x00, 0x1d, 0x94, 0xa0, 0x94, 0xc9, 0xa5, 0xbb, 0xf2, 0x72, 0xbc,
|
||||
0xfb, 0xe3, 0xc2, 0x50, 0x2e, 0x7e, 0x1a, 0x8a, 0x73, 0xfa, 0xbb, 0xd4, 0xd5, 0xcb, 0x52, 0x57,
|
||||
0xff, 0x96, 0xba, 0xfa, 0x7d, 0xa3, 0x2b, 0x97, 0x1b, 0x5d, 0xf9, 0xb3, 0xd1, 0x95, 0x8f, 0x2f,
|
||||
0x62, 0xcc, 0x97, 0x45, 0x60, 0x85, 0x24, 0xb5, 0x65, 0xe2, 0xfa, 0x75, 0xc4, 0xa2, 0x95, 0x7d,
|
||||
0xfb, 0x77, 0x0f, 0x1e, 0x54, 0xab, 0x79, 0xf5, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x1e, 0xd7, 0x43,
|
||||
0xb2, 0x05, 0x03, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *PublicKey) Marshal() (dAtA []byte, err error) {
|
||||
@ -740,22 +740,6 @@ func (m *MultiSignature) Size() (n int) {
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *CompactBitArray) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.ExtraBitsStored != 0 {
|
||||
n += 1 + sovTypes(uint64(m.ExtraBitsStored))
|
||||
}
|
||||
l = len(m.Elems)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovTypes(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovTypes(x uint64) (n int) {
|
||||
return (math_bits.Len64(x|1) + 6) / 7
|
||||
}
|
||||
|
||||
@ -8,33 +8,32 @@ option go_package = "github.com/cosmos/cosmos-sdk/crypto/types";
|
||||
|
||||
// PublicKey specifies a public key
|
||||
message PublicKey {
|
||||
// sum specifies which type of public key is wrapped
|
||||
oneof sum {
|
||||
bytes secp256k1 = 1;
|
||||
bytes ed25519 = 2;
|
||||
bytes sr25519 = 3;
|
||||
PubKeyMultisigThreshold multisig = 4;
|
||||
bytes secp256r1 = 5;
|
||||
// sum specifies which type of public key is wrapped
|
||||
oneof sum {
|
||||
bytes secp256k1 = 1;
|
||||
bytes ed25519 = 2;
|
||||
bytes sr25519 = 3;
|
||||
PubKeyMultisigThreshold multisig = 4;
|
||||
bytes secp256r1 = 5;
|
||||
|
||||
// any_pubkey can be used for any pubkey that an app may use which is
|
||||
// not explicitly defined in the oneof
|
||||
google.protobuf.Any any_pubkey = 15; // 15 is largest field that occupies one byte
|
||||
}
|
||||
// any_pubkey can be used for any pubkey that an app may use which is
|
||||
// not explicitly defined in the oneof
|
||||
google.protobuf.Any any_pubkey = 15; // 15 is largest field that occupies one byte
|
||||
}
|
||||
}
|
||||
|
||||
// PubKeyMultisigThreshold specifies a public key type which nests multiple public
|
||||
// keys and a threshold
|
||||
message PubKeyMultisigThreshold {
|
||||
uint32 threshold = 1 [(gogoproto.customname) = "K", (gogoproto.moretags) = "yaml:\"threshold\""];
|
||||
repeated PublicKey pubkeys = 2 [(gogoproto.customname) = "PubKeys", (gogoproto.moretags) = "yaml:\"pubkeys\""];
|
||||
uint32 threshold = 1 [(gogoproto.customname) = "K", (gogoproto.moretags) = "yaml:\"threshold\""];
|
||||
repeated PublicKey pubkeys = 2 [(gogoproto.customname) = "PubKeys", (gogoproto.moretags) = "yaml:\"pubkeys\""];
|
||||
}
|
||||
|
||||
|
||||
// MultiSignature wraps the signatures from a PubKeyMultisigThreshold.
|
||||
// See cosmos_sdk.tx.v1.ModeInfo.Multi for how to specify which signers signed
|
||||
// and with which modes
|
||||
message MultiSignature {
|
||||
repeated bytes sigs = 1;
|
||||
repeated bytes sigs = 1;
|
||||
}
|
||||
|
||||
// CompactBitArray is an implementation of a space efficient bit array.
|
||||
@ -42,10 +41,9 @@ message MultiSignature {
|
||||
// space after proto encoding.
|
||||
// This is not thread safe, and is not intended for concurrent usage.
|
||||
message CompactBitArray {
|
||||
// TODO: re-enable these when the actual implementation is added
|
||||
// option (gogoproto.sizer) = false;
|
||||
// option (gogoproto.goproto_stringer) = false;
|
||||
option (gogoproto.sizer) = false;
|
||||
option (gogoproto.goproto_stringer) = false;
|
||||
|
||||
uint32 extra_bits_stored = 1;
|
||||
bytes elems = 2;
|
||||
uint32 extra_bits_stored = 1;
|
||||
bytes elems = 2;
|
||||
}
|
||||
|
||||
@ -690,54 +690,54 @@ var fileDescriptor_1c6ac8fa65877134 = []byte{
|
||||
0x04, 0x04, 0xce, 0xb2, 0x7b, 0x60, 0x11, 0x87, 0x55, 0x92, 0xa6, 0xdb, 0x40, 0x9b, 0xa2, 0x49,
|
||||
0x56, 0x82, 0x95, 0x90, 0xe5, 0xd8, 0x53, 0x67, 0xd4, 0x78, 0x26, 0x78, 0xc6, 0x28, 0xe1, 0x82,
|
||||
0x38, 0x70, 0xe2, 0xc2, 0x85, 0x3f, 0xc1, 0x2f, 0x59, 0x71, 0xda, 0x23, 0x17, 0x3e, 0xd4, 0xfe,
|
||||
0x10, 0x90, 0xc7, 0xe3, 0xa4, 0x6a, 0x4a, 0xb8, 0x71, 0xca, 0xeb, 0x67, 0x9e, 0xe7, 0x99, 0xf7,
|
||||
0x2b, 0x36, 0xec, 0xc8, 0xf9, 0x94, 0x88, 0xa6, 0x9c, 0x35, 0x55, 0x60, 0x4d, 0x43, 0x2e, 0x39,
|
||||
0x10, 0x90, 0xc7, 0xe3, 0xa4, 0x6a, 0x4a, 0xb8, 0x71, 0xca, 0xeb, 0xc7, 0xcf, 0xf3, 0xcc, 0xfb,
|
||||
0x95, 0x31, 0xec, 0xc8, 0xf9, 0x94, 0x88, 0xa6, 0x9c, 0x35, 0x55, 0x60, 0x4d, 0x43, 0x2e, 0x39,
|
||||
0x2a, 0xbb, 0x5c, 0x04, 0x5c, 0xd8, 0xc2, 0xbb, 0xb4, 0xe4, 0xcc, 0xfa, 0xe6, 0xc3, 0xca, 0xdb,
|
||||
0x72, 0x4c, 0x43, 0xcf, 0x9e, 0x3a, 0xa1, 0x9c, 0x37, 0x15, 0xa9, 0xe9, 0x73, 0x9f, 0x2f, 0xa3,
|
||||
0x44, 0x59, 0xd9, 0xd6, 0x7e, 0x4b, 0xb3, 0x8a, 0xe9, 0x86, 0xf3, 0xa9, 0xe4, 0xcd, 0xd5, 0x93,
|
||||
0x3d, 0x9f, 0x73, 0x7f, 0x42, 0x12, 0xbf, 0x51, 0x74, 0xd1, 0x74, 0xd8, 0x3c, 0x39, 0xaa, 0xff,
|
||||
0x68, 0x40, 0x76, 0x38, 0x43, 0xef, 0x43, 0x7e, 0xc4, 0xbd, 0xb9, 0x69, 0xd4, 0x8c, 0xc6, 0xd6,
|
||||
0x63, 0xd3, 0xba, 0x9d, 0x97, 0x35, 0x9c, 0xb5, 0xb9, 0x37, 0xc7, 0x8a, 0x85, 0x3e, 0x82, 0x92,
|
||||
0x13, 0xc9, 0xb1, 0x4d, 0xd9, 0x05, 0x37, 0xb3, 0x4a, 0x52, 0x59, 0x95, 0xb4, 0x22, 0x39, 0xee,
|
||||
0xb1, 0x0b, 0x8e, 0x8b, 0x8e, 0x8e, 0x50, 0x15, 0x40, 0x50, 0x9f, 0x39, 0x32, 0x0a, 0x89, 0x30,
|
||||
0x73, 0xb5, 0x5c, 0xe3, 0x1e, 0xbe, 0x81, 0xd4, 0x7f, 0x37, 0x60, 0x73, 0x40, 0x7d, 0x76, 0xc4,
|
||||
0xdd, 0xff, 0x2b, 0xa5, 0x3d, 0x28, 0xba, 0x63, 0x87, 0x32, 0x9b, 0x7a, 0x66, 0xae, 0x66, 0x34,
|
||||
0x4a, 0x78, 0x53, 0x3d, 0xf7, 0x3c, 0x74, 0x08, 0x0f, 0x1c, 0xd7, 0xe5, 0x11, 0x93, 0x36, 0x8b,
|
||||
0x82, 0x11, 0x09, 0xcd, 0x7c, 0xcd, 0x68, 0xe4, 0xf1, 0x7d, 0x8d, 0xf6, 0x15, 0x88, 0xde, 0x85,
|
||||
0x72, 0x4a, 0x13, 0xe4, 0xeb, 0x88, 0x30, 0x97, 0x98, 0x1b, 0x8a, 0xf8, 0x50, 0xe3, 0x03, 0x0d,
|
||||
0xd7, 0x7f, 0xce, 0x42, 0x21, 0x49, 0x1b, 0x3d, 0x82, 0x62, 0x40, 0x84, 0x70, 0x7c, 0x22, 0x4c,
|
||||
0xa3, 0x96, 0x6b, 0x6c, 0x3d, 0xde, 0xb1, 0x92, 0x31, 0x59, 0xe9, 0x98, 0xac, 0x16, 0x9b, 0xe3,
|
||||
0x05, 0x0b, 0x21, 0xc8, 0x07, 0x24, 0x48, 0xaa, 0x2b, 0x61, 0x15, 0xc7, 0x29, 0x4a, 0x1a, 0x10,
|
||||
0x1e, 0x49, 0x7b, 0x4c, 0xa8, 0x3f, 0x96, 0xaa, 0x86, 0x1c, 0xbe, 0xaf, 0xd1, 0x13, 0x05, 0xa2,
|
||||
0x36, 0x6c, 0x93, 0x99, 0x24, 0x4c, 0x50, 0xce, 0x6c, 0x3e, 0x95, 0x94, 0x33, 0x61, 0xfe, 0xbd,
|
||||
0xb9, 0xe6, 0xda, 0xf2, 0x82, 0x7f, 0x9e, 0xd0, 0xd1, 0x4b, 0xa8, 0x32, 0xce, 0x6c, 0x37, 0xa4,
|
||||
0x92, 0xba, 0xce, 0xc4, 0xbe, 0xc3, 0xf0, 0xe1, 0x1a, 0xc3, 0x7d, 0xc6, 0x59, 0x47, 0x6b, 0xbb,
|
||||
0xb7, 0xbc, 0xeb, 0x12, 0x8a, 0xe9, 0x68, 0xd0, 0x33, 0xb8, 0x17, 0x6f, 0x04, 0x09, 0xd5, 0x2c,
|
||||
0xd3, 0xe6, 0xbc, 0xb9, 0x3a, 0xcc, 0x81, 0x62, 0xa9, 0x71, 0x6e, 0x89, 0x45, 0x2c, 0xd0, 0x3b,
|
||||
0x90, 0xbb, 0x20, 0x44, 0x2f, 0xc1, 0xee, 0xaa, 0xee, 0x98, 0x10, 0x1c, 0x33, 0xea, 0xdf, 0x02,
|
||||
0x2c, 0x3d, 0xd0, 0x13, 0x80, 0x69, 0x34, 0x9a, 0x50, 0xd7, 0xbe, 0x24, 0xe9, 0xd6, 0xdd, 0x5d,
|
||||
0x4a, 0x29, 0xe1, 0x7d, 0x46, 0xd4, 0xda, 0x05, 0xdc, 0x23, 0xff, 0xb1, 0x76, 0x67, 0xdc, 0x23,
|
||||
0xc9, 0xda, 0x05, 0x3a, 0xaa, 0xff, 0x9a, 0x85, 0x62, 0x0a, 0xa3, 0x4f, 0xa0, 0x20, 0x28, 0xf3,
|
||||
0x27, 0x44, 0x5f, 0xfb, 0xd6, 0xbf, 0x5b, 0x58, 0x03, 0x45, 0x3c, 0xc9, 0x60, 0x2d, 0x41, 0x4f,
|
||||
0x61, 0x23, 0x88, 0x26, 0x92, 0xea, 0xeb, 0x6b, 0x6b, 0xb4, 0x67, 0x31, 0xef, 0x24, 0x83, 0x13,
|
||||
0x41, 0xe5, 0x29, 0x14, 0x12, 0x37, 0x64, 0x41, 0x3e, 0xce, 0x4c, 0x5d, 0xff, 0xe0, 0xae, 0x0a,
|
||||
0xe2, 0x3e, 0xc5, 0x36, 0x58, 0xf1, 0x2a, 0x3f, 0x18, 0xb0, 0xa1, 0xcc, 0x50, 0x0b, 0x8a, 0x23,
|
||||
0x2a, 0x9d, 0x30, 0x74, 0xd2, 0x9e, 0x1d, 0xde, 0x54, 0x27, 0xaf, 0xa4, 0xd8, 0xa1, 0xc3, 0x83,
|
||||
0xa9, 0xe3, 0xca, 0x36, 0x95, 0xad, 0x98, 0x8c, 0x17, 0x32, 0xf4, 0x31, 0xc0, 0xa2, 0x87, 0xc2,
|
||||
0xcc, 0xaa, 0x71, 0xaf, 0x6b, 0x62, 0x29, 0x6d, 0xa2, 0x68, 0x6f, 0x40, 0x4e, 0x44, 0x41, 0xfd,
|
||||
0x7b, 0x03, 0x72, 0xc7, 0x84, 0xa0, 0xaf, 0xa0, 0xe0, 0x04, 0xf1, 0x1f, 0x4e, 0x2f, 0xcd, 0x1b,
|
||||
0x37, 0x5d, 0x54, 0x0e, 0x94, 0xb5, 0x1f, 0xbd, 0xfa, 0xe3, 0x20, 0xf3, 0xcb, 0x9f, 0x07, 0x0d,
|
||||
0x9f, 0xca, 0x71, 0x34, 0xb2, 0x5c, 0x1e, 0x34, 0x13, 0x9a, 0xfe, 0xf9, 0x40, 0x78, 0x97, 0xfa,
|
||||
0xf5, 0x19, 0x0b, 0x04, 0xd6, 0xa6, 0x68, 0x1f, 0x4a, 0xbe, 0x23, 0xec, 0x09, 0x0d, 0xa8, 0x54,
|
||||
0xdd, 0xce, 0xe3, 0xa2, 0xef, 0x88, 0xd3, 0xf8, 0xf9, 0x3d, 0x01, 0xc5, 0xb4, 0x49, 0x68, 0x0f,
|
||||
0x76, 0x07, 0xbd, 0xe7, 0x7d, 0xfb, 0xec, 0xfc, 0xa8, 0x6b, 0xbf, 0xe8, 0x0f, 0x3e, 0xef, 0x76,
|
||||
0x7a, 0xc7, 0xbd, 0xee, 0x51, 0x39, 0x83, 0x76, 0xa0, 0xbc, 0x3c, 0x3a, 0xea, 0xe1, 0x6e, 0x67,
|
||||
0x58, 0x36, 0xd0, 0x2e, 0x6c, 0x2f, 0xd1, 0x61, 0xf7, 0x8b, 0xe1, 0x8b, 0xd6, 0x69, 0x39, 0x8b,
|
||||
0x0e, 0x60, 0x7f, 0x09, 0x9f, 0x76, 0x9f, 0xb7, 0x3a, 0x5f, 0xda, 0xad, 0xb3, 0x5e, 0xff, 0xdc,
|
||||
0xfe, 0x74, 0x70, 0xde, 0x2f, 0x7f, 0xd7, 0x7e, 0xf6, 0xea, 0xaa, 0x6a, 0xbc, 0xbe, 0xaa, 0x1a,
|
||||
0x7f, 0x5d, 0x55, 0x8d, 0x9f, 0xae, 0xab, 0x99, 0xd7, 0xd7, 0xd5, 0xcc, 0x6f, 0xd7, 0xd5, 0xcc,
|
||||
0xcb, 0xc3, 0xf5, 0xd5, 0xe9, 0xcf, 0xd0, 0xa8, 0xa0, 0x16, 0xfb, 0xc9, 0x3f, 0x01, 0x00, 0x00,
|
||||
0xff, 0xff, 0xa9, 0x40, 0x9c, 0x90, 0x9f, 0x06, 0x00, 0x00,
|
||||
0x44, 0x59, 0x31, 0xdd, 0x70, 0x3e, 0x95, 0xbc, 0xa9, 0x6d, 0x97, 0x9e, 0x95, 0xed, 0x55, 0x68,
|
||||
0xcf, 0xe7, 0xdc, 0x9f, 0x90, 0xc4, 0x6f, 0x14, 0x5d, 0x34, 0x1d, 0x36, 0x4f, 0x5e, 0xd5, 0x7f,
|
||||
0x34, 0x20, 0x3b, 0x9c, 0xa1, 0xf7, 0x21, 0x3f, 0xe2, 0xde, 0xdc, 0x34, 0x6a, 0x46, 0x63, 0xeb,
|
||||
0xb1, 0x69, 0xdd, 0xce, 0xcb, 0x1a, 0xce, 0xda, 0xdc, 0x9b, 0x63, 0xc5, 0x42, 0x1f, 0x41, 0xc9,
|
||||
0x89, 0xe4, 0xd8, 0xa6, 0xec, 0x82, 0x9b, 0x59, 0x25, 0xa9, 0xac, 0x4a, 0x5a, 0x91, 0x1c, 0xf7,
|
||||
0xd8, 0x05, 0xc7, 0x45, 0x47, 0x47, 0xa8, 0x0a, 0x20, 0xa8, 0xcf, 0x1c, 0x19, 0x85, 0x44, 0x98,
|
||||
0xb9, 0x5a, 0xae, 0x71, 0x0f, 0xdf, 0x40, 0xea, 0xbf, 0x1b, 0xb0, 0x39, 0xa0, 0x3e, 0x3b, 0xe2,
|
||||
0xee, 0xff, 0x95, 0xd2, 0x1e, 0x14, 0xdd, 0xb1, 0x43, 0x99, 0x4d, 0x3d, 0x33, 0x57, 0x33, 0x1a,
|
||||
0x25, 0xbc, 0xa9, 0x9e, 0x7b, 0x1e, 0x3a, 0x84, 0x07, 0x8e, 0xeb, 0xf2, 0x88, 0x49, 0x9b, 0x45,
|
||||
0xc1, 0x88, 0x84, 0x66, 0xbe, 0x66, 0x34, 0xf2, 0xf8, 0xbe, 0x46, 0xfb, 0x0a, 0x44, 0xef, 0x42,
|
||||
0x39, 0xa5, 0x09, 0xf2, 0x75, 0x44, 0x98, 0x4b, 0xcc, 0x0d, 0x45, 0x7c, 0xa8, 0xf1, 0x81, 0x86,
|
||||
0xeb, 0x3f, 0x67, 0xa1, 0x90, 0xa4, 0x8d, 0x1e, 0x41, 0x31, 0x20, 0x42, 0x38, 0x3e, 0x11, 0xa6,
|
||||
0x51, 0xcb, 0x35, 0xb6, 0x1e, 0xef, 0x58, 0xc9, 0x98, 0xac, 0x74, 0x4c, 0x56, 0x8b, 0xcd, 0xf1,
|
||||
0x82, 0x85, 0x10, 0xe4, 0x03, 0x12, 0x24, 0xd5, 0x95, 0xb0, 0x8a, 0xe3, 0x14, 0x25, 0x0d, 0x08,
|
||||
0x8f, 0xa4, 0x3d, 0x26, 0xd4, 0x1f, 0x4b, 0x55, 0x43, 0x0e, 0xdf, 0xd7, 0xe8, 0x89, 0x02, 0x51,
|
||||
0x1b, 0xb6, 0xc9, 0x4c, 0x12, 0x26, 0x28, 0x67, 0x36, 0x9f, 0x4a, 0xca, 0x99, 0x30, 0xff, 0xde,
|
||||
0x5c, 0x73, 0x6c, 0x79, 0xc1, 0x3f, 0x4f, 0xe8, 0xe8, 0x25, 0x54, 0x19, 0x67, 0xb6, 0x1b, 0x52,
|
||||
0x49, 0x5d, 0x67, 0x62, 0xdf, 0x61, 0xf8, 0x70, 0x8d, 0xe1, 0x3e, 0xe3, 0xac, 0xa3, 0xb5, 0xdd,
|
||||
0x5b, 0xde, 0x75, 0x09, 0xc5, 0x74, 0x34, 0xe8, 0x19, 0xdc, 0x8b, 0x37, 0x82, 0x84, 0x6a, 0x96,
|
||||
0x69, 0x73, 0xde, 0x5c, 0x1d, 0xe6, 0x40, 0xb1, 0xd4, 0x38, 0xb7, 0xc4, 0x22, 0x16, 0xe8, 0x1d,
|
||||
0xc8, 0x5d, 0x10, 0xa2, 0x97, 0x60, 0x77, 0x55, 0x77, 0x4c, 0x08, 0x8e, 0x19, 0xf5, 0x6f, 0x01,
|
||||
0x96, 0x1e, 0xe8, 0x09, 0xc0, 0x34, 0x1a, 0x4d, 0xa8, 0x6b, 0x5f, 0x92, 0x74, 0xeb, 0xee, 0x2e,
|
||||
0xa5, 0x94, 0xf0, 0x3e, 0x23, 0x6a, 0xed, 0x02, 0xee, 0x91, 0xff, 0x58, 0xbb, 0x33, 0xee, 0x91,
|
||||
0x64, 0xed, 0x02, 0x1d, 0xd5, 0x7f, 0xcd, 0x42, 0x31, 0x85, 0xd1, 0x27, 0x50, 0x10, 0x94, 0xf9,
|
||||
0x13, 0xa2, 0x8f, 0x7d, 0xeb, 0xdf, 0x2d, 0xac, 0x81, 0x22, 0x9e, 0x64, 0xb0, 0x96, 0xa0, 0xa7,
|
||||
0xb0, 0x11, 0x44, 0x13, 0x49, 0xf5, 0xf1, 0xb5, 0x35, 0xda, 0xb3, 0x98, 0x77, 0x92, 0xc1, 0x89,
|
||||
0xa0, 0xf2, 0x14, 0x0a, 0x89, 0x1b, 0xb2, 0x20, 0x1f, 0x67, 0xa6, 0x8e, 0x7f, 0x70, 0x57, 0x05,
|
||||
0x71, 0x9f, 0x62, 0x1b, 0xac, 0x78, 0x95, 0x1f, 0x0c, 0xd8, 0x50, 0x66, 0xa8, 0x05, 0xc5, 0x11,
|
||||
0x95, 0x4e, 0x18, 0x3a, 0x69, 0xcf, 0x0e, 0x6f, 0xaa, 0x93, 0x5b, 0x2a, 0x76, 0xe8, 0xf0, 0x60,
|
||||
0xea, 0xb8, 0xb2, 0x4d, 0x65, 0x2b, 0x26, 0xe3, 0x85, 0x0c, 0x7d, 0x0c, 0xb0, 0xe8, 0xa1, 0x30,
|
||||
0xb3, 0x6a, 0xdc, 0xeb, 0x9a, 0x58, 0x4a, 0x9b, 0x28, 0xda, 0x1b, 0x90, 0x13, 0x51, 0x50, 0xff,
|
||||
0xde, 0x80, 0xdc, 0x31, 0x21, 0xe8, 0x2b, 0x28, 0x38, 0x41, 0xfc, 0x87, 0xd3, 0x4b, 0xf3, 0xc6,
|
||||
0x4d, 0x17, 0x95, 0x03, 0x65, 0xed, 0x47, 0xaf, 0xfe, 0x38, 0xc8, 0xfc, 0xf2, 0xe7, 0x41, 0xc3,
|
||||
0xa7, 0x72, 0x1c, 0x8d, 0x2c, 0x97, 0x07, 0xcd, 0x84, 0xa6, 0x7f, 0x3e, 0x10, 0xde, 0xa5, 0xbe,
|
||||
0x3e, 0x63, 0x81, 0xc0, 0xda, 0x14, 0xed, 0x43, 0xc9, 0x77, 0x84, 0x3d, 0xa1, 0x01, 0x95, 0xaa,
|
||||
0xdb, 0x79, 0x5c, 0xf4, 0x1d, 0x71, 0x1a, 0x3f, 0xbf, 0x27, 0xa0, 0x98, 0x36, 0x09, 0xed, 0xc1,
|
||||
0xee, 0xa0, 0xf7, 0xbc, 0x6f, 0x9f, 0x9d, 0x1f, 0x75, 0xed, 0x17, 0xfd, 0xc1, 0xe7, 0xdd, 0x4e,
|
||||
0xef, 0xb8, 0xd7, 0x3d, 0x2a, 0x67, 0xd0, 0x0e, 0x94, 0x97, 0xaf, 0x8e, 0x7a, 0xb8, 0xdb, 0x19,
|
||||
0x96, 0x0d, 0xb4, 0x0b, 0xdb, 0x4b, 0x74, 0xd8, 0xfd, 0x62, 0xf8, 0xa2, 0x75, 0x5a, 0xce, 0xa2,
|
||||
0x03, 0xd8, 0x5f, 0xc2, 0xa7, 0xdd, 0xe7, 0xad, 0xce, 0x97, 0x76, 0xeb, 0xac, 0xd7, 0x3f, 0xb7,
|
||||
0x3f, 0x1d, 0x9c, 0xf7, 0xcb, 0xdf, 0xb5, 0x9f, 0xbd, 0xba, 0xaa, 0x1a, 0xaf, 0xaf, 0xaa, 0xc6,
|
||||
0x5f, 0x57, 0x55, 0xe3, 0xa7, 0xeb, 0x6a, 0xe6, 0xf5, 0x75, 0x35, 0xf3, 0xdb, 0x75, 0x35, 0xf3,
|
||||
0xf2, 0x70, 0x7d, 0x75, 0xfa, 0x33, 0x34, 0x2a, 0xa8, 0xc5, 0x7e, 0xf2, 0x4f, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0x28, 0x03, 0x76, 0x89, 0x9f, 0x06, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *Tx) Marshal() (dAtA []byte, err error) {
|
||||
|
||||
@ -2,8 +2,8 @@ syntax = "proto3";
|
||||
package cosmos_sdk.tx.v1;
|
||||
|
||||
import "third_party/proto/gogoproto/gogo.proto";
|
||||
import "types/types.proto";
|
||||
import "crypto/types/types.proto";
|
||||
import "types/types.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/tx/types";
|
||||
|
||||
Loading…
Reference in New Issue
Block a user