|
|
@ -1,6 +1,10 @@ |
|
|
|
package multisig |
|
|
|
|
|
|
|
import "github.com/tendermint/tendermint/crypto" |
|
|
|
import ( |
|
|
|
"errors" |
|
|
|
|
|
|
|
"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.
|
|
|
@ -17,7 +21,7 @@ func NewMultisig(n int) *Multisignature { |
|
|
|
} |
|
|
|
|
|
|
|
// GetIndex returns the index of pk in keys. Returns -1 if not found
|
|
|
|
func GetIndex(pk crypto.PubKey, keys []crypto.PubKey) int { |
|
|
|
func getIndex(pk crypto.PubKey, keys []crypto.PubKey) int { |
|
|
|
for i := 0; i < len(keys); i++ { |
|
|
|
if pk.Equals(keys[i]) { |
|
|
|
return i |
|
|
@ -28,30 +32,34 @@ func GetIndex(pk crypto.PubKey, keys []crypto.PubKey) int { |
|
|
|
|
|
|
|
// AddSignature adds a signature to the multisig, at the corresponding index.
|
|
|
|
func (mSig *Multisignature) AddSignature(sig []byte, index int) { |
|
|
|
i := mSig.BitArray.trueIndex(index) |
|
|
|
newSigIndex := mSig.BitArray.NumOfTrueBitsBefore(index) |
|
|
|
// Signature already exists, just replace the value there
|
|
|
|
if mSig.BitArray.GetIndex(index) { |
|
|
|
mSig.Sigs[i] = sig |
|
|
|
mSig.Sigs[newSigIndex] = sig |
|
|
|
return |
|
|
|
} |
|
|
|
mSig.BitArray.SetIndex(index, true) |
|
|
|
// Optimization if the index is the greatest index
|
|
|
|
if i > len(mSig.Sigs) { |
|
|
|
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[i+1:], mSig.Sigs[i:]) |
|
|
|
mSig.Sigs[i] = sig |
|
|
|
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) { |
|
|
|
index := GetIndex(pubkey, keys) |
|
|
|
func (mSig *Multisignature) AddSignatureFromPubkey(sig []byte, pubkey crypto.PubKey, keys []crypto.PubKey) error { |
|
|
|
index := getIndex(pubkey, keys) |
|
|
|
if index == -1 { |
|
|
|
return errors.New("provided key didn't exist in pubkeys") |
|
|
|
} |
|
|
|
mSig.AddSignature(sig, index) |
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
// Marshal the multisignature with amino
|
|
|
|