manifest: add ABI validity check
Some methods must be defined in a valid ABI. Refs. neo-project/neo#2263.
This commit is contained in:
parent
5ba074b4cf
commit
1a4958b1d5
4 changed files with 31 additions and 1 deletions
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
"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/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
"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/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -23,6 +24,11 @@ func TestDeployGetUpdateDestroyContract(t *testing.T) {
|
||||||
ne, err := nef.NewFile(script)
|
ne, err := nef.NewFile(script)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
manif := manifest.NewManifest("Test")
|
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)
|
h := state.CreateContractHash(sender, ne.Checksum, manif.Name)
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,14 @@ func (a *ABI) GetEvent(name string) *Event {
|
||||||
return nil
|
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.
|
// ToStackItem converts ABI to stackitem.Item.
|
||||||
func (a *ABI) ToStackItem() stackitem.Item {
|
func (a *ABI) ToStackItem() stackitem.Item {
|
||||||
methods := make([]stackitem.Item, len(a.Methods))
|
methods := make([]stackitem.Item, len(a.Methods))
|
||||||
|
|
|
@ -70,9 +70,15 @@ func (m *Manifest) CanCall(hash util.Uint160, toCall *Manifest, method string) b
|
||||||
return false
|
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 {
|
func (m *Manifest) IsValid(hash util.Uint160) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
err = m.ABI.IsValid()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
for _, g := range m.Groups {
|
for _, g := range m.Groups {
|
||||||
err = g.IsValid(hash)
|
err = g.IsValid(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -111,6 +111,16 @@ func TestIsValid(t *testing.T) {
|
||||||
contractHash := util.Uint160{1, 2, 3}
|
contractHash := util.Uint160{1, 2, 3}
|
||||||
m := NewManifest("Test")
|
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) {
|
t.Run("valid, no groups", func(t *testing.T) {
|
||||||
require.NoError(t, m.IsValid(contractHash))
|
require.NoError(t, m.IsValid(contractHash))
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue