Skip to content

Commit

Permalink
manifest: add method validity check
Browse files Browse the repository at this point in the history
Refs. #1699.
  • Loading branch information
roman-khimov committed Feb 9, 2021
1 parent f3c761e commit f0c3066
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 17 deletions.
6 changes: 6 additions & 0 deletions pkg/smartcontract/manifest/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ func (a *ABI) IsValid() error {
if len(a.Methods) == 0 {
return errors.New("ABI contains no methods")
}
for i := range a.Methods {
err := a.Methods[i].IsValid()
if err != nil {
return err
}
}
for i := range a.Events {
err := a.Events[i].IsValid()
if err != nil {
Expand Down
18 changes: 1 addition & 17 deletions pkg/smartcontract/manifest/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package manifest

import (
"errors"
"sort"

"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)
Expand All @@ -18,22 +17,7 @@ func (e *Event) IsValid() error {
if e.Name == "" {
return errors.New("empty or absent name")
}
if len(e.Parameters) > 1 {
paramNames := make([]string, len(e.Parameters))
for i := range e.Parameters {
paramNames[i] = e.Parameters[i].Name
}
sort.Strings(paramNames)
for i := range paramNames {
if i == 0 {
continue
}
if paramNames[i] == paramNames[i-1] {
return errors.New("duplicate parameter name")
}
}
}
return nil
return Parameters(e.Parameters).AreValid()
}

// ToStackItem converts Event to stackitem.Item.
Expand Down
15 changes: 15 additions & 0 deletions pkg/smartcontract/manifest/method.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ type Method struct {
Safe bool `json:"safe"`
}

// IsValid checks Method consistency and correctness.
func (m *Method) IsValid() error {
if m.Name == "" {
return errors.New("empty or absent name")
}
if m.Offset < 0 {
return errors.New("negative offset")
}
_, err := smartcontract.ConvertToParamType(int(m.ReturnType))
if err != nil {
return err
}
return Parameters(m.Parameters).AreValid()
}

// ToStackItem converts Method to stackitem.Item.
func (m *Method) ToStackItem() stackitem.Item {
params := make([]stackitem.Item, len(m.Parameters))
Expand Down
21 changes: 21 additions & 0 deletions pkg/smartcontract/manifest/method_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,27 @@ import (
"github.com/stretchr/testify/require"
)

func TestMethodIsValid(t *testing.T) {
m := &Method{}
require.Error(t, m.IsValid()) // No name.

m.Name = "qwerty"
require.NoError(t, m.IsValid())

m.Offset = -100
require.Error(t, m.IsValid())

m.Offset = 100
m.ReturnType = 0x42 // Invalid type.
require.Error(t, m.IsValid())

m.ReturnType = smartcontract.BoolType
require.NoError(t, m.IsValid())

m.Parameters = append(m.Parameters, NewParameter("param", smartcontract.BoolType), NewParameter("param", smartcontract.BoolType))
require.Error(t, m.IsValid())
}

func TestMethod_ToStackItemFromStackItem(t *testing.T) {
m := &Method{
Name: "mur",
Expand Down
24 changes: 24 additions & 0 deletions pkg/smartcontract/manifest/parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ type Parameter struct {
Type smartcontract.ParamType `json:"type"`
}

// Parameters is just an array of Parameter.
type Parameters []Parameter

// NewParameter returns new parameter of specified name and type.
func NewParameter(name string, typ smartcontract.ParamType) Parameter {
return Parameter{
Expand Down Expand Up @@ -54,3 +57,24 @@ func (p *Parameter) FromStackItem(item stackitem.Item) error {
}
return nil
}

// AreValid checks all parameters for validity and consistency.
func (p Parameters) AreValid() error {
if len(p) < 2 {
return nil
}
names := make([]string, len(p))
for i := range p {
names[i] = p[i].Name
}
sort.Strings(names)
for i := range names {
if i == 0 {
continue
}
if names[i] == names[i-1] {
return errors.New("duplicate parameter name")
}
}
return nil
}

0 comments on commit f0c3066

Please sign in to comment.