smartcontract: require manifest serialization in (*Manifest).IsValid

Port the restrictive part of https://github.com/neo-project/neo/pull/2948.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
This commit is contained in:
Anna Shaleva 2023-11-22 14:07:15 +03:00
parent 387c411da0
commit 6824bd9f40
2 changed files with 26 additions and 1 deletions

View file

@ -118,7 +118,19 @@ func (m *Manifest) IsValid(hash util.Uint160) error {
return errors.New("duplicate trusted contracts") return errors.New("duplicate trusted contracts")
} }
} }
return Permissions(m.Permissions).AreValid() err = Permissions(m.Permissions).AreValid()
if err != nil {
return err
}
si, err := m.ToStackItem()
if err != nil {
return fmt.Errorf("failed to check manifest serialisation: %w", err)
}
_, err = stackitem.Serialize(si)
if err != nil {
return fmt.Errorf("manifest is not serializable: %w", err)
}
return nil
} }
// IsStandardSupported denotes whether the specified standard is supported by the contract. // IsStandardSupported denotes whether the specified standard is supported by the contract.

View file

@ -2,6 +2,7 @@ package manifest
import ( import (
"encoding/json" "encoding/json"
"fmt"
"math/big" "math/big"
"testing" "testing"
@ -243,6 +244,18 @@ func TestIsValid(t *testing.T) {
require.Error(t, m.IsValid(contractHash)) require.Error(t, m.IsValid(contractHash))
}) })
}) })
m.Groups = m.Groups[:0]
t.Run("invalid, unserializable", func(t *testing.T) {
for i := 0; i < stackitem.MaxSerialized; i++ {
m.ABI.Events = append(m.ABI.Events, Event{
Name: fmt.Sprintf("Event%d", i),
Parameters: []Parameter{},
})
}
err := m.IsValid(contractHash)
require.ErrorIs(t, err, stackitem.ErrTooBig)
})
} }
func TestManifestToStackItem(t *testing.T) { func TestManifestToStackItem(t *testing.T) {