smartcontract: define parameter lengths as constants and use them

This commit is contained in:
Roman Khimov 2022-10-05 10:46:21 +03:00
parent 317dd42513
commit 8893163803
4 changed files with 50 additions and 41 deletions

View file

@ -45,7 +45,7 @@ func TestTypeConstantSize(t *testing.T) {
t.Run("Hash160", func(t *testing.T) {
t.Run("good", func(t *testing.T) {
a := make(cinterop.Hash160, 20)
a := make(cinterop.Hash160, smartcontract.Hash160Len)
src := fmt.Sprintf(src, a, a)
eval(t, src, []byte(a))
})
@ -58,7 +58,7 @@ func TestTypeConstantSize(t *testing.T) {
})
t.Run("Hash256", func(t *testing.T) {
t.Run("good", func(t *testing.T) {
a := make(cinterop.Hash256, 32)
a := make(cinterop.Hash256, smartcontract.Hash256Len)
src := fmt.Sprintf(src, a, a)
eval(t, src, []byte(a))
})

View file

@ -15,6 +15,7 @@ import (
istorage "github.com/nspcc-dev/neo-go/pkg/core/interop/storage"
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
"github.com/nspcc-dev/neo-go/pkg/interop/storage"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm"
@ -488,6 +489,6 @@ func TestInteropTypesComparison(t *testing.T) {
}
typeCheck(t, "Hash160", util.Uint160Size)
typeCheck(t, "Hash256", util.Uint256Size)
typeCheck(t, "Signature", 64)
typeCheck(t, "PublicKey", 33)
typeCheck(t, "Signature", smartcontract.SignatureLen)
typeCheck(t, "PublicKey", smartcontract.PublicKeyLen)
}

View file

@ -38,6 +38,14 @@ const (
VoidType ParamType = 0xff
)
// Lengths (in bytes) of fixed-size types.
const (
Hash160Len = util.Uint160Size
Hash256Len = util.Uint256Size
PublicKeyLen = 33
SignatureLen = keys.SignatureLen
)
// fileBytesParamType is a string representation of `filebytes` parameter type used in cli.
const fileBytesParamType string = "filebytes"
@ -151,7 +159,7 @@ func (pt *ParamType) DecodeBinary(r *io.BinReader) {
// public key is represented by 33-byte value while 32 bytes are used for integer
// and a simple push+convert is used for boolean. Other types produce no code at all.
func (pt ParamType) EncodeDefaultValue(w *io.BinWriter) {
var b [64]byte
var b [SignatureLen]byte
switch pt {
case AnyType, SignatureType, StringType, ByteArrayType:
@ -161,11 +169,11 @@ func (pt ParamType) EncodeDefaultValue(w *io.BinWriter) {
case IntegerType:
emit.Instruction(w, opcode.PUSHINT256, b[:32])
case Hash160Type:
emit.Bytes(w, b[:20])
emit.Bytes(w, b[:Hash160Len])
case Hash256Type:
emit.Bytes(w, b[:32])
emit.Bytes(w, b[:Hash256Len])
case PublicKeyType:
emit.Bytes(w, b[:33])
emit.Bytes(w, b[:PublicKeyLen])
case ArrayType, MapType, InteropInterfaceType, VoidType:
}
}
@ -198,13 +206,13 @@ func (pt ParamType) Match(v stackitem.Item) bool {
case ByteArrayType, StringType:
return vt == stackitem.ByteArrayT || vt == stackitem.BufferT || vt == stackitem.AnyT
case Hash160Type:
return checkBytesWithLen(vt, v, 20)
return checkBytesWithLen(vt, v, Hash160Len)
case Hash256Type:
return checkBytesWithLen(vt, v, 32)
return checkBytesWithLen(vt, v, Hash256Len)
case PublicKeyType:
return checkBytesWithLen(vt, v, 33)
return checkBytesWithLen(vt, v, PublicKeyLen)
case SignatureType:
return checkBytesWithLen(vt, v, 64)
return checkBytesWithLen(vt, v, SignatureLen)
case ArrayType:
return vt == stackitem.AnyT || vt == stackitem.ArrayT || vt == stackitem.StructT
case MapType:
@ -274,7 +282,7 @@ func adjustValToType(typ ParamType, val string) (interface{}, error) {
if err != nil {
return nil, err
}
if len(b) != 64 {
if len(b) != SignatureLen {
return nil, errors.New("not a signature")
}
return b, nil
@ -356,11 +364,11 @@ func inferParamType(val string) ParamType {
unhexed, err := hex.DecodeString(val)
if err == nil {
switch len(unhexed) {
case 20:
case Hash160Len:
return Hash160Type
case 32:
case Hash256Len:
return Hash256Type
case 64:
case SignatureLen:
return SignatureType
default:
return ByteArrayType

View file

@ -444,31 +444,31 @@ func TestParamTypeMatch(t *testing.T) {
require.Falsef(t, pt.Match(itm), "%s - %s", pt.String(), itm.String())
}
for itm, pt := range map[stackitem.Item]ParamType{
stackitem.Make(false): BoolType,
stackitem.Make(true): BoolType,
stackitem.Make(0): IntegerType,
stackitem.Make(100500): IntegerType,
stackitem.Make([]byte{1}): ByteArrayType,
stackitem.Make([]byte{1}): StringType,
stackitem.NewBuffer([]byte{1}): ByteArrayType,
stackitem.NewBuffer([]byte{1}): StringType,
stackitem.Null{}: ByteArrayType,
stackitem.Null{}: StringType,
stackitem.Make(util.Uint160{}.BytesBE()): Hash160Type,
stackitem.Make(util.Uint256{}.BytesBE()): Hash256Type,
stackitem.Null{}: Hash160Type,
stackitem.Null{}: Hash256Type,
stackitem.Make(make([]byte, 33)): PublicKeyType,
stackitem.Null{}: PublicKeyType,
stackitem.Make(make([]byte, 64)): SignatureType,
stackitem.Null{}: SignatureType,
stackitem.Make([]stackitem.Item{}): ArrayType,
stackitem.NewStruct([]stackitem.Item{}): ArrayType,
stackitem.Null{}: ArrayType,
stackitem.NewMap(): MapType,
stackitem.Null{}: MapType,
stackitem.NewInterop(true): InteropInterfaceType,
stackitem.Null{}: InteropInterfaceType,
stackitem.Make(false): BoolType,
stackitem.Make(true): BoolType,
stackitem.Make(0): IntegerType,
stackitem.Make(100500): IntegerType,
stackitem.Make([]byte{1}): ByteArrayType,
stackitem.Make([]byte{1}): StringType,
stackitem.NewBuffer([]byte{1}): ByteArrayType,
stackitem.NewBuffer([]byte{1}): StringType,
stackitem.Null{}: ByteArrayType,
stackitem.Null{}: StringType,
stackitem.Make(util.Uint160{}.BytesBE()): Hash160Type,
stackitem.Make(util.Uint256{}.BytesBE()): Hash256Type,
stackitem.Null{}: Hash160Type,
stackitem.Null{}: Hash256Type,
stackitem.Make(make([]byte, PublicKeyLen)): PublicKeyType,
stackitem.Null{}: PublicKeyType,
stackitem.Make(make([]byte, SignatureLen)): SignatureType,
stackitem.Null{}: SignatureType,
stackitem.Make([]stackitem.Item{}): ArrayType,
stackitem.NewStruct([]stackitem.Item{}): ArrayType,
stackitem.Null{}: ArrayType,
stackitem.NewMap(): MapType,
stackitem.Null{}: MapType,
stackitem.NewInterop(true): InteropInterfaceType,
stackitem.Null{}: InteropInterfaceType,
} {
require.Truef(t, pt.Match(itm), "%s - %s", pt.String(), itm.String())
}