mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2025-02-16 21:16:30 +00:00
manifest: deduplicate duplicate-checking code
Signed-off-by: Roman Khimov <roman@nspcc.ru>
This commit is contained in:
parent
db820cb0dc
commit
49438798b5
5 changed files with 35 additions and 78 deletions
|
@ -4,7 +4,6 @@ import (
|
|||
"cmp"
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
@ -63,23 +62,14 @@ func (a *ABI) IsValid() error {
|
|||
return fmt.Errorf("method %q/%d: %w", a.Methods[i].Name, len(a.Methods[i].Parameters), err)
|
||||
}
|
||||
}
|
||||
if len(a.Methods) > 1 {
|
||||
var methods = slices.Clone(a.Methods)
|
||||
slices.SortFunc(methods, func(a, b Method) int {
|
||||
return cmp.Or(
|
||||
cmp.Compare(a.Name, b.Name),
|
||||
cmp.Compare(len(a.Parameters), len(b.Parameters)),
|
||||
)
|
||||
})
|
||||
for i := range methods {
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
if methods[i].Name == methods[i-1].Name &&
|
||||
len(methods[i].Parameters) == len(methods[i-1].Parameters) {
|
||||
return errors.New("duplicate method specifications")
|
||||
}
|
||||
if sliceHasDups(a.Methods, func(a, b Method) int {
|
||||
res := cmp.Compare(a.Name, b.Name)
|
||||
if res != 0 {
|
||||
return res
|
||||
}
|
||||
return cmp.Compare(len(a.Parameters), len(b.Parameters))
|
||||
}) {
|
||||
return errors.New("duplicate method specifications")
|
||||
}
|
||||
for i := range a.Events {
|
||||
err := a.Events[i].IsValid()
|
||||
|
@ -87,14 +77,10 @@ func (a *ABI) IsValid() error {
|
|||
return fmt.Errorf("event %q/%d: %w", a.Events[i].Name, len(a.Events[i].Parameters), err)
|
||||
}
|
||||
}
|
||||
if len(a.Events) > 1 {
|
||||
names := make([]string, len(a.Events))
|
||||
for i := range a.Events {
|
||||
names[i] = a.Events[i].Name
|
||||
}
|
||||
if stringsHaveDups(names) {
|
||||
return errors.New("duplicate event names")
|
||||
}
|
||||
if sliceHasDups(a.Events, func(a, b Event) int {
|
||||
return cmp.Compare(a.Name, b.Name)
|
||||
}) {
|
||||
return errors.New("duplicate event names")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"slices"
|
||||
"sort"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
|
@ -59,7 +58,7 @@ func (g Groups) AreValid(h util.Uint160) error {
|
|||
for i := range g {
|
||||
pkeys[i] = g[i].PublicKey
|
||||
}
|
||||
sort.Sort(pkeys)
|
||||
slices.SortFunc(pkeys, (*keys.PublicKey).Cmp)
|
||||
for i := range pkeys {
|
||||
if i == 0 {
|
||||
continue
|
||||
|
|
|
@ -95,11 +95,8 @@ func (m *Manifest) IsValid(hash util.Uint160, checkSize bool) error {
|
|||
if slices.Contains(m.SupportedStandards, "") {
|
||||
return errors.New("invalid nameless supported standard")
|
||||
}
|
||||
if len(m.SupportedStandards) > 1 {
|
||||
names := slices.Clone(m.SupportedStandards)
|
||||
if stringsHaveDups(names) {
|
||||
return errors.New("duplicate supported standards")
|
||||
}
|
||||
if sliceHasDups(m.SupportedStandards, strings.Compare) {
|
||||
return errors.New("duplicate supported standards")
|
||||
}
|
||||
err = m.ABI.IsValid()
|
||||
if err != nil {
|
||||
|
@ -122,11 +119,8 @@ func (m *Manifest) IsValid(hash util.Uint160, checkSize bool) error {
|
|||
if m.Trusts.Value == nil && !m.Trusts.Wildcard {
|
||||
return errors.New("invalid (null?) trusts")
|
||||
}
|
||||
if len(m.Trusts.Value) > 1 {
|
||||
hashes := slices.Clone(m.Trusts.Value)
|
||||
if permissionDescsHaveDups(hashes) {
|
||||
return errors.New("duplicate trusted contracts")
|
||||
}
|
||||
if sliceHasDups(m.Trusts.Value, PermissionDesc.Compare) {
|
||||
return errors.New("duplicate trusted contracts")
|
||||
}
|
||||
err = Permissions(m.Permissions).AreValid()
|
||||
if err != nil {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package manifest
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
|
@ -79,42 +80,28 @@ func (p Parameters) AreValid() error {
|
|||
return fmt.Errorf("parameter #%d/%q: %w", i, p[i].Name, err)
|
||||
}
|
||||
}
|
||||
if len(p) < 2 {
|
||||
return nil
|
||||
}
|
||||
names := make([]string, len(p))
|
||||
for i := range p {
|
||||
names[i] = p[i].Name
|
||||
}
|
||||
if stringsHaveDups(names) {
|
||||
if sliceHasDups(p, func(a, b Parameter) int {
|
||||
return cmp.Compare(a.Name, b.Name)
|
||||
}) {
|
||||
return errors.New("duplicate parameter name")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// stringsHaveDups checks the given set of strings for duplicates. It modifies the slice given!
|
||||
func stringsHaveDups(strings []string) bool {
|
||||
slices.Sort(strings)
|
||||
for i := range strings {
|
||||
// sliceHasDups checks the slice for duplicate elements.
|
||||
func sliceHasDups[S ~[]E, E any](x S, cmp func(a, b E) int) bool {
|
||||
if len(x) < 2 {
|
||||
return false
|
||||
}
|
||||
if len(x) > 2 {
|
||||
x = slices.Clone(x)
|
||||
slices.SortFunc(x, cmp)
|
||||
}
|
||||
for i := range x {
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
if strings[i] == strings[i-1] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// permissionDescsHaveDups checks the given set of strings for duplicates. It modifies the slice given!
|
||||
func permissionDescsHaveDups(descs []PermissionDesc) bool {
|
||||
slices.SortFunc(descs, PermissionDesc.Compare)
|
||||
for i := range descs {
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
j := i - 1
|
||||
if descs[i].Compare(descs[j]) == 0 {
|
||||
if cmp(x[i-1], x[i]) == 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,11 +119,7 @@ func (p *Permission) IsValid() error {
|
|||
if slices.Contains(p.Methods.Value, "") {
|
||||
return errors.New("empty method name")
|
||||
}
|
||||
if len(p.Methods.Value) < 2 {
|
||||
return nil
|
||||
}
|
||||
names := slices.Clone(p.Methods.Value)
|
||||
if stringsHaveDups(names) {
|
||||
if sliceHasDups(p.Methods.Value, cmp.Compare) {
|
||||
return errors.New("duplicate method names")
|
||||
}
|
||||
return nil
|
||||
|
@ -137,14 +133,9 @@ func (ps Permissions) AreValid() error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
if len(ps) < 2 {
|
||||
return nil
|
||||
}
|
||||
contracts := make([]PermissionDesc, 0, len(ps))
|
||||
for i := range ps {
|
||||
contracts = append(contracts, ps[i].Contract)
|
||||
}
|
||||
if permissionDescsHaveDups(contracts) {
|
||||
if sliceHasDups(ps, func(a, b Permission) int {
|
||||
return a.Contract.Compare(b.Contract)
|
||||
}) {
|
||||
return errors.New("contracts have duplicates")
|
||||
}
|
||||
return nil
|
||||
|
|
Loading…
Add table
Reference in a new issue