manifest: add ABI validity check

Some methods must be defined in a valid ABI. Refs. neo-project/neo#2263.
This commit is contained in:
Roman Khimov 2021-02-08 13:15:10 +03:00
parent 5ba074b4cf
commit 1a4958b1d5
4 changed files with 31 additions and 1 deletions

View file

@ -8,6 +8,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/core/storage"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
"github.com/nspcc-dev/neo-go/pkg/util"
@ -23,6 +24,11 @@ func TestDeployGetUpdateDestroyContract(t *testing.T) {
ne, err := nef.NewFile(script)
require.NoError(t, err)
manif := manifest.NewManifest("Test")
manif.ABI.Methods = append(manif.ABI.Methods, manifest.Method{
Name: "dummy",
ReturnType: smartcontract.VoidType,
Parameters: []manifest.Parameter{},
})
h := state.CreateContractHash(sender, ne.Checksum, manif.Name)

View file

@ -49,6 +49,14 @@ func (a *ABI) GetEvent(name string) *Event {
return nil
}
// IsValid checks ABI consistency and correctness.
func (a *ABI) IsValid() error {
if len(a.Methods) == 0 {
return errors.New("ABI contains no methods")
}
return nil
}
// ToStackItem converts ABI to stackitem.Item.
func (a *ABI) ToStackItem() stackitem.Item {
methods := make([]stackitem.Item, len(a.Methods))

View file

@ -70,9 +70,15 @@ func (m *Manifest) CanCall(hash util.Uint160, toCall *Manifest, method string) b
return false
}
// IsValid checks whether the hash given is correct wrt manifest's groups.
// IsValid checks manifest internal consistency and correctness, one of the
// checks is for group signature correctness, contract hash is passed for it.
func (m *Manifest) IsValid(hash util.Uint160) error {
var err error
err = m.ABI.IsValid()
if err != nil {
return err
}
for _, g := range m.Groups {
err = g.IsValid(hash)
if err != nil {

View file

@ -111,6 +111,16 @@ func TestIsValid(t *testing.T) {
contractHash := util.Uint160{1, 2, 3}
m := NewManifest("Test")
t.Run("invalid, no ABI methods", func(t *testing.T) {
require.Error(t, m.IsValid(contractHash))
})
m.ABI.Methods = append(m.ABI.Methods, Method{
Name: "dummy",
ReturnType: smartcontract.VoidType,
Parameters: []Parameter{},
})
t.Run("valid, no groups", func(t *testing.T) {
require.NoError(t, m.IsValid(contractHash))
})