neo-go/cli/wallet/legacy_test.go

107 lines
3.4 KiB
Go
Raw Normal View History

package wallet
import (
"bytes"
"crypto/elliptic"
"encoding/hex"
"testing"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/stretchr/testify/require"
)
func testParseMultisigContract(t *testing.T, s []byte, nsigs int, keys ...*keys.PublicKey) {
ns, ks, ok := parseMultisigContract(s)
if len(keys) == 0 {
require.False(t, ok)
return
}
require.True(t, ok)
require.Equal(t, nsigs, ns)
require.Equal(t, len(keys), len(ks))
for i := range keys {
require.Equal(t, keys[i], ks[i])
}
}
func TestParseMultisigContract(t *testing.T) {
t.Run("single multisig", func(t *testing.T) {
s := fromHex(t, "512102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc251ae")
pub := pubFromHex(t, "02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2")
t.Run("good, no ret", func(t *testing.T) {
testParseMultisigContract(t, s, 1, pub)
})
t.Run("good, with ret", func(t *testing.T) {
s := append(s, opRet)
testParseMultisigContract(t, s, 1, pub)
})
t.Run("bad, no check multisig", func(t *testing.T) {
sBad := bytes.Clone(s)
sBad[len(sBad)-1] ^= 0xFF
testParseMultisigContract(t, sBad, 0)
})
t.Run("bad, invalid number of keys", func(t *testing.T) {
sBad := bytes.Clone(s)
sBad[len(sBad)-2] = opPush1 + 1
testParseMultisigContract(t, sBad, 0)
})
t.Run("bad, invalid first instruction", func(t *testing.T) {
sBad := bytes.Clone(s)
sBad[0] = 0xFF
testParseMultisigContract(t, sBad, 0)
})
t.Run("bad, invalid public key", func(t *testing.T) {
sBad := bytes.Clone(s)
sBad[2] = 0xFF
testParseMultisigContract(t, sBad, 0)
})
t.Run("bad, many sigs", func(t *testing.T) {
sBad := bytes.Clone(s)
sBad[0] = opPush1 + 1
testParseMultisigContract(t, sBad, 0)
})
t.Run("empty, no panic", func(t *testing.T) {
testParseMultisigContract(t, []byte{}, 0)
})
})
t.Run("3/4 multisig", func(t *testing.T) {
// From privnet consensus wallet.
s := fromHex(t, "532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae")
ks := keys.PublicKeys{
pubFromHex(t, "02103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e"),
pubFromHex(t, "02a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd62"),
pubFromHex(t, "02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2"),
pubFromHex(t, "03d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699"),
}
t.Run("good", func(t *testing.T) {
testParseMultisigContract(t, s, 3, ks...)
})
t.Run("good, with pushbytes1", func(t *testing.T) {
s := append([]byte{opPushBytes1, 3}, s[1:]...)
testParseMultisigContract(t, s, 3, ks...)
})
t.Run("good, with pushbytes2", func(t *testing.T) {
s := append([]byte{opPushBytes2, 3, 0}, s[1:]...)
testParseMultisigContract(t, s, 3, ks...)
})
t.Run("bad, no panic on prefix", func(t *testing.T) {
for i := minMultisigLen; i < len(s)-1; i++ {
testParseMultisigContract(t, s[:i], 0)
}
})
})
}
func fromHex(t *testing.T, s string) []byte {
bs, err := hex.DecodeString(s)
require.NoError(t, err)
return bs
}
func pubFromHex(t *testing.T, s string) *keys.PublicKey {
bs := fromHex(t, s)
pub, err := keys.NewPublicKeyFromBytes(bs, elliptic.P256())
require.NoError(t, err)
return pub
}