diff --git a/pkg/core/native/management.go b/pkg/core/native/management.go index 217168afc..a216fa950 100644 --- a/pkg/core/native/management.go +++ b/pkg/core/native/management.go @@ -265,8 +265,9 @@ func (m *Management) Deploy(d dao.DAO, sender util.Uint160, neff *nef.File, mani if err != nil { return nil, err } - if !manif.IsValid(h) { - return nil, errors.New("invalid manifest for this contract") + err = manif.IsValid(h) + if err != nil { + return nil, fmt.Errorf("invalid manifest: %w", err) } newcontract := &state.Contract{ ID: id, @@ -322,8 +323,9 @@ func (m *Management) Update(d dao.DAO, hash util.Uint160, neff *nef.File, manif if manif.Name != contract.Manifest.Name { return nil, errors.New("contract name can't be changed") } - if !manif.IsValid(contract.Hash) { - return nil, errors.New("invalid manifest for this contract") + err = manif.IsValid(contract.Hash) + if err != nil { + return nil, fmt.Errorf("invalid manifest: %w", err) } m.markUpdated(hash) contract.Manifest = *manif diff --git a/pkg/smartcontract/manifest/manifest.go b/pkg/smartcontract/manifest/manifest.go index 3a593ea21..d8afdd5a9 100644 --- a/pkg/smartcontract/manifest/manifest.go +++ b/pkg/smartcontract/manifest/manifest.go @@ -71,13 +71,15 @@ func (m *Manifest) CanCall(hash util.Uint160, toCall *Manifest, method string) b } // IsValid checks whether the hash given is correct wrt manifest's groups. -func (m *Manifest) IsValid(hash util.Uint160) bool { +func (m *Manifest) IsValid(hash util.Uint160) error { + var err error for _, g := range m.Groups { - if !g.IsValid(hash) { - return false + err = g.IsValid(hash) + if err != nil { + break } } - return true + return err } // ToStackItem converts Manifest to stackitem.Item. diff --git a/pkg/smartcontract/manifest/manifest_test.go b/pkg/smartcontract/manifest/manifest_test.go index 629bea1d9..c92dcd289 100644 --- a/pkg/smartcontract/manifest/manifest_test.go +++ b/pkg/smartcontract/manifest/manifest_test.go @@ -112,7 +112,7 @@ func TestIsValid(t *testing.T) { m := NewManifest("Test") t.Run("valid, no groups", func(t *testing.T) { - require.True(t, m.IsValid(contractHash)) + require.NoError(t, m.IsValid(contractHash)) }) t.Run("with groups", func(t *testing.T) { @@ -129,11 +129,11 @@ func TestIsValid(t *testing.T) { } t.Run("valid", func(t *testing.T) { - require.True(t, m.IsValid(contractHash)) + require.NoError(t, m.IsValid(contractHash)) }) t.Run("invalid, wrong contract hash", func(t *testing.T) { - require.False(t, m.IsValid(util.Uint160{4, 5, 6})) + require.Error(t, m.IsValid(util.Uint160{4, 5, 6})) }) t.Run("invalid, wrong group signature", func(t *testing.T) { @@ -145,7 +145,7 @@ func TestIsValid(t *testing.T) { // of the contract hash. Signature: pk.Sign([]byte{1, 2, 3}), }) - require.False(t, m.IsValid(contractHash)) + require.Error(t, m.IsValid(contractHash)) }) }) } diff --git a/pkg/smartcontract/manifest/method.go b/pkg/smartcontract/manifest/method.go index b3ef30ab9..e56a89165 100644 --- a/pkg/smartcontract/manifest/method.go +++ b/pkg/smartcontract/manifest/method.go @@ -56,8 +56,11 @@ func NewParameter(name string, typ smartcontract.ParamType) Parameter { } // IsValid checks whether group's signature corresponds to the given hash. -func (g *Group) IsValid(h util.Uint160) bool { - return g.PublicKey.Verify(g.Signature, hash.Sha256(h.BytesBE()).BytesBE()) +func (g *Group) IsValid(h util.Uint160) error { + if !g.PublicKey.Verify(g.Signature, hash.Sha256(h.BytesBE()).BytesBE()) { + return errors.New("incorrect group signature") + } + return nil } // MarshalJSON implements json.Marshaler interface.