parent
284476c070
commit
dc3967ae7b
5 changed files with 131 additions and 5 deletions
1
cli/testdata/deploy/neo-go.yml
vendored
1
cli/testdata/deploy/neo-go.yml
vendored
|
@ -0,0 +1 @@
|
||||||
|
name: Test deploy
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
@ -20,6 +21,9 @@ type Group struct {
|
||||||
Signature []byte `json:"signature"`
|
Signature []byte `json:"signature"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Groups is just an array of Group.
|
||||||
|
type Groups []Group
|
||||||
|
|
||||||
type groupAux struct {
|
type groupAux struct {
|
||||||
PublicKey string `json:"pubkey"`
|
PublicKey string `json:"pubkey"`
|
||||||
Signature []byte `json:"signature"`
|
Signature []byte `json:"signature"`
|
||||||
|
@ -33,6 +37,33 @@ func (g *Group) IsValid(h util.Uint160) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AreValid checks for groups correctness and uniqueness.
|
||||||
|
func (g Groups) AreValid(h util.Uint160) error {
|
||||||
|
for i := range g {
|
||||||
|
err := g[i].IsValid(h)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(g) < 2 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
pkeys := make(keys.PublicKeys, len(g))
|
||||||
|
for i := range g {
|
||||||
|
pkeys[i] = g[i].PublicKey
|
||||||
|
}
|
||||||
|
sort.Sort(pkeys)
|
||||||
|
for i := range pkeys {
|
||||||
|
if i == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if pkeys[i].Cmp(pkeys[i-1]) == 0 {
|
||||||
|
return errors.New("duplicate group keys")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalJSON implements json.Marshaler interface.
|
// MarshalJSON implements json.Marshaler interface.
|
||||||
func (g *Group) MarshalJSON() ([]byte, error) {
|
func (g *Group) MarshalJSON() ([]byte, error) {
|
||||||
aux := &groupAux{
|
aux := &groupAux{
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/internal/testserdes"
|
"github.com/nspcc-dev/neo-go/internal/testserdes"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,3 +17,27 @@ func TestGroupJSONInOut(t *testing.T) {
|
||||||
g := Group{pub, sig}
|
g := Group{pub, sig}
|
||||||
testserdes.MarshalUnmarshalJSON(t, &g, new(Group))
|
testserdes.MarshalUnmarshalJSON(t, &g, new(Group))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGroupsAreValid(t *testing.T) {
|
||||||
|
h := util.Uint160{42, 42, 42}
|
||||||
|
priv, err := keys.NewPrivateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
priv2, err := keys.NewPrivateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
pub := priv.PublicKey()
|
||||||
|
pub2 := priv2.PublicKey()
|
||||||
|
gcorrect := Group{pub, priv.Sign(h.BytesBE())}
|
||||||
|
gcorrect2 := Group{pub2, priv2.Sign(h.BytesBE())}
|
||||||
|
gincorrect := Group{pub, priv.Sign(h.BytesLE())}
|
||||||
|
gps := Groups{gcorrect}
|
||||||
|
require.NoError(t, gps.AreValid(h))
|
||||||
|
|
||||||
|
gps = Groups{gincorrect}
|
||||||
|
require.Error(t, gps.AreValid(h))
|
||||||
|
|
||||||
|
gps = Groups{gcorrect, gcorrect2}
|
||||||
|
require.NoError(t, gps.AreValid(h))
|
||||||
|
|
||||||
|
gps = Groups{gcorrect, gcorrect}
|
||||||
|
require.Error(t, gps.AreValid(h))
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"math"
|
"math"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
|
@ -75,14 +76,43 @@ func (m *Manifest) CanCall(hash util.Uint160, toCall *Manifest, method string) b
|
||||||
func (m *Manifest) IsValid(hash util.Uint160) error {
|
func (m *Manifest) IsValid(hash util.Uint160) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
if m.Name == "" {
|
||||||
|
return errors.New("no name")
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range m.SupportedStandards {
|
||||||
|
if m.SupportedStandards[i] == "" {
|
||||||
|
return errors.New("invalid nameless supported standard")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(m.SupportedStandards) > 1 {
|
||||||
|
names := make([]string, len(m.SupportedStandards))
|
||||||
|
copy(names, m.SupportedStandards)
|
||||||
|
if stringsHaveDups(names) {
|
||||||
|
return errors.New("duplicate supported standards")
|
||||||
|
}
|
||||||
|
}
|
||||||
err = m.ABI.IsValid()
|
err = m.ABI.IsValid()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, g := range m.Groups {
|
err = Groups(m.Groups).AreValid(hash)
|
||||||
err = g.IsValid(hash)
|
if err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return err
|
}
|
||||||
|
if len(m.Trusts.Value) > 1 {
|
||||||
|
hashes := make([]util.Uint160, len(m.Trusts.Value))
|
||||||
|
copy(hashes, m.Trusts.Value)
|
||||||
|
sort.Slice(hashes, func(i, j int) bool {
|
||||||
|
return hashes[i].Less(hashes[j])
|
||||||
|
})
|
||||||
|
for i := range hashes {
|
||||||
|
if i == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if hashes[i] == hashes[i-1] {
|
||||||
|
return errors.New("duplicate trusted contracts")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Permissions(m.Permissions).AreValid()
|
return Permissions(m.Permissions).AreValid()
|
||||||
|
|
|
@ -109,7 +109,13 @@ func TestPermission_IsAllowed(t *testing.T) {
|
||||||
|
|
||||||
func TestIsValid(t *testing.T) {
|
func TestIsValid(t *testing.T) {
|
||||||
contractHash := util.Uint160{1, 2, 3}
|
contractHash := util.Uint160{1, 2, 3}
|
||||||
m := NewManifest("Test")
|
m := &Manifest{}
|
||||||
|
|
||||||
|
t.Run("invalid, no name", func(t *testing.T) {
|
||||||
|
require.Error(t, m.IsValid(contractHash))
|
||||||
|
})
|
||||||
|
|
||||||
|
m = NewManifest("Test")
|
||||||
|
|
||||||
t.Run("invalid, no ABI methods", func(t *testing.T) {
|
t.Run("invalid, no ABI methods", func(t *testing.T) {
|
||||||
require.Error(t, m.IsValid(contractHash))
|
require.Error(t, m.IsValid(contractHash))
|
||||||
|
@ -158,6 +164,39 @@ func TestIsValid(t *testing.T) {
|
||||||
})
|
})
|
||||||
m.Permissions = m.Permissions[:1]
|
m.Permissions = m.Permissions[:1]
|
||||||
|
|
||||||
|
m.SupportedStandards = append(m.SupportedStandards, "NEP-17")
|
||||||
|
t.Run("valid, with standards", func(t *testing.T) {
|
||||||
|
require.NoError(t, m.IsValid(contractHash))
|
||||||
|
})
|
||||||
|
|
||||||
|
m.SupportedStandards = append(m.SupportedStandards, "")
|
||||||
|
t.Run("invalid, with nameless standard", func(t *testing.T) {
|
||||||
|
require.Error(t, m.IsValid(contractHash))
|
||||||
|
})
|
||||||
|
m.SupportedStandards = m.SupportedStandards[:1]
|
||||||
|
|
||||||
|
m.SupportedStandards = append(m.SupportedStandards, "NEP-17")
|
||||||
|
t.Run("invalid, with duplicate standards", func(t *testing.T) {
|
||||||
|
require.Error(t, m.IsValid(contractHash))
|
||||||
|
})
|
||||||
|
m.SupportedStandards = m.SupportedStandards[:1]
|
||||||
|
|
||||||
|
m.Trusts.Add(util.Uint160{1, 2, 3})
|
||||||
|
t.Run("valid, with trust", func(t *testing.T) {
|
||||||
|
require.NoError(t, m.IsValid(contractHash))
|
||||||
|
})
|
||||||
|
|
||||||
|
m.Trusts.Add(util.Uint160{3, 2, 1})
|
||||||
|
t.Run("valid, with trusts", func(t *testing.T) {
|
||||||
|
require.NoError(t, m.IsValid(contractHash))
|
||||||
|
})
|
||||||
|
|
||||||
|
m.Trusts.Add(util.Uint160{1, 2, 3})
|
||||||
|
t.Run("invalid, with trusts", func(t *testing.T) {
|
||||||
|
require.Error(t, m.IsValid(contractHash))
|
||||||
|
})
|
||||||
|
m.Trusts.Restrict()
|
||||||
|
|
||||||
t.Run("with groups", func(t *testing.T) {
|
t.Run("with groups", func(t *testing.T) {
|
||||||
m.Groups = make([]Group, 3)
|
m.Groups = make([]Group, 3)
|
||||||
pks := make([]*keys.PrivateKey, 3)
|
pks := make([]*keys.PrivateKey, 3)
|
||||||
|
|
Loading…
Reference in a new issue