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/json"
|
||||
"errors"
|
||||
"sort"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
|
@ -20,6 +21,9 @@ type Group struct {
|
|||
Signature []byte `json:"signature"`
|
||||
}
|
||||
|
||||
// Groups is just an array of Group.
|
||||
type Groups []Group
|
||||
|
||||
type groupAux struct {
|
||||
PublicKey string `json:"pubkey"`
|
||||
Signature []byte `json:"signature"`
|
||||
|
@ -33,6 +37,33 @@ func (g *Group) IsValid(h util.Uint160) error {
|
|||
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.
|
||||
func (g *Group) MarshalJSON() ([]byte, error) {
|
||||
aux := &groupAux{
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/nspcc-dev/neo-go/internal/testserdes"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
@ -16,3 +17,27 @@ func TestGroupJSONInOut(t *testing.T) {
|
|||
g := Group{pub, sig}
|
||||
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"
|
||||
"errors"
|
||||
"math"
|
||||
"sort"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"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 {
|
||||
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()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, g := range m.Groups {
|
||||
err = g.IsValid(hash)
|
||||
if err != nil {
|
||||
return err
|
||||
err = Groups(m.Groups).AreValid(hash)
|
||||
if err != nil {
|
||||
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()
|
||||
|
|
|
@ -109,7 +109,13 @@ func TestPermission_IsAllowed(t *testing.T) {
|
|||
|
||||
func TestIsValid(t *testing.T) {
|
||||
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) {
|
||||
require.Error(t, m.IsValid(contractHash))
|
||||
|
@ -158,6 +164,39 @@ func TestIsValid(t *testing.T) {
|
|||
})
|
||||
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) {
|
||||
m.Groups = make([]Group, 3)
|
||||
pks := make([]*keys.PrivateKey, 3)
|
||||
|
|
Loading…
Reference in a new issue