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("Hash160", func(t *testing.T) {
t.Run("good", 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) src := fmt.Sprintf(src, a, a)
eval(t, src, []byte(a)) eval(t, src, []byte(a))
}) })
@ -58,7 +58,7 @@ func TestTypeConstantSize(t *testing.T) {
}) })
t.Run("Hash256", func(t *testing.T) { t.Run("Hash256", func(t *testing.T) {
t.Run("good", 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) src := fmt.Sprintf(src, a, a)
eval(t, src, []byte(a)) eval(t, src, []byte(a))
}) })

View file

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

View file

@ -38,6 +38,14 @@ const (
VoidType ParamType = 0xff 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. // fileBytesParamType is a string representation of `filebytes` parameter type used in cli.
const fileBytesParamType string = "filebytes" 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 // 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. // and a simple push+convert is used for boolean. Other types produce no code at all.
func (pt ParamType) EncodeDefaultValue(w *io.BinWriter) { func (pt ParamType) EncodeDefaultValue(w *io.BinWriter) {
var b [64]byte var b [SignatureLen]byte
switch pt { switch pt {
case AnyType, SignatureType, StringType, ByteArrayType: case AnyType, SignatureType, StringType, ByteArrayType:
@ -161,11 +169,11 @@ func (pt ParamType) EncodeDefaultValue(w *io.BinWriter) {
case IntegerType: case IntegerType:
emit.Instruction(w, opcode.PUSHINT256, b[:32]) emit.Instruction(w, opcode.PUSHINT256, b[:32])
case Hash160Type: case Hash160Type:
emit.Bytes(w, b[:20]) emit.Bytes(w, b[:Hash160Len])
case Hash256Type: case Hash256Type:
emit.Bytes(w, b[:32]) emit.Bytes(w, b[:Hash256Len])
case PublicKeyType: case PublicKeyType:
emit.Bytes(w, b[:33]) emit.Bytes(w, b[:PublicKeyLen])
case ArrayType, MapType, InteropInterfaceType, VoidType: case ArrayType, MapType, InteropInterfaceType, VoidType:
} }
} }
@ -198,13 +206,13 @@ func (pt ParamType) Match(v stackitem.Item) bool {
case ByteArrayType, StringType: case ByteArrayType, StringType:
return vt == stackitem.ByteArrayT || vt == stackitem.BufferT || vt == stackitem.AnyT return vt == stackitem.ByteArrayT || vt == stackitem.BufferT || vt == stackitem.AnyT
case Hash160Type: case Hash160Type:
return checkBytesWithLen(vt, v, 20) return checkBytesWithLen(vt, v, Hash160Len)
case Hash256Type: case Hash256Type:
return checkBytesWithLen(vt, v, 32) return checkBytesWithLen(vt, v, Hash256Len)
case PublicKeyType: case PublicKeyType:
return checkBytesWithLen(vt, v, 33) return checkBytesWithLen(vt, v, PublicKeyLen)
case SignatureType: case SignatureType:
return checkBytesWithLen(vt, v, 64) return checkBytesWithLen(vt, v, SignatureLen)
case ArrayType: case ArrayType:
return vt == stackitem.AnyT || vt == stackitem.ArrayT || vt == stackitem.StructT return vt == stackitem.AnyT || vt == stackitem.ArrayT || vt == stackitem.StructT
case MapType: case MapType:
@ -274,7 +282,7 @@ func adjustValToType(typ ParamType, val string) (interface{}, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if len(b) != 64 { if len(b) != SignatureLen {
return nil, errors.New("not a signature") return nil, errors.New("not a signature")
} }
return b, nil return b, nil
@ -356,11 +364,11 @@ func inferParamType(val string) ParamType {
unhexed, err := hex.DecodeString(val) unhexed, err := hex.DecodeString(val)
if err == nil { if err == nil {
switch len(unhexed) { switch len(unhexed) {
case 20: case Hash160Len:
return Hash160Type return Hash160Type
case 32: case Hash256Len:
return Hash256Type return Hash256Type
case 64: case SignatureLen:
return SignatureType return SignatureType
default: default:
return ByteArrayType 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()) require.Falsef(t, pt.Match(itm), "%s - %s", pt.String(), itm.String())
} }
for itm, pt := range map[stackitem.Item]ParamType{ for itm, pt := range map[stackitem.Item]ParamType{
stackitem.Make(false): BoolType, stackitem.Make(false): BoolType,
stackitem.Make(true): BoolType, stackitem.Make(true): BoolType,
stackitem.Make(0): IntegerType, stackitem.Make(0): IntegerType,
stackitem.Make(100500): IntegerType, stackitem.Make(100500): IntegerType,
stackitem.Make([]byte{1}): ByteArrayType, stackitem.Make([]byte{1}): ByteArrayType,
stackitem.Make([]byte{1}): StringType, stackitem.Make([]byte{1}): StringType,
stackitem.NewBuffer([]byte{1}): ByteArrayType, stackitem.NewBuffer([]byte{1}): ByteArrayType,
stackitem.NewBuffer([]byte{1}): StringType, stackitem.NewBuffer([]byte{1}): StringType,
stackitem.Null{}: ByteArrayType, stackitem.Null{}: ByteArrayType,
stackitem.Null{}: StringType, stackitem.Null{}: StringType,
stackitem.Make(util.Uint160{}.BytesBE()): Hash160Type, stackitem.Make(util.Uint160{}.BytesBE()): Hash160Type,
stackitem.Make(util.Uint256{}.BytesBE()): Hash256Type, stackitem.Make(util.Uint256{}.BytesBE()): Hash256Type,
stackitem.Null{}: Hash160Type, stackitem.Null{}: Hash160Type,
stackitem.Null{}: Hash256Type, stackitem.Null{}: Hash256Type,
stackitem.Make(make([]byte, 33)): PublicKeyType, stackitem.Make(make([]byte, PublicKeyLen)): PublicKeyType,
stackitem.Null{}: PublicKeyType, stackitem.Null{}: PublicKeyType,
stackitem.Make(make([]byte, 64)): SignatureType, stackitem.Make(make([]byte, SignatureLen)): SignatureType,
stackitem.Null{}: SignatureType, stackitem.Null{}: SignatureType,
stackitem.Make([]stackitem.Item{}): ArrayType, stackitem.Make([]stackitem.Item{}): ArrayType,
stackitem.NewStruct([]stackitem.Item{}): ArrayType, stackitem.NewStruct([]stackitem.Item{}): ArrayType,
stackitem.Null{}: ArrayType, stackitem.Null{}: ArrayType,
stackitem.NewMap(): MapType, stackitem.NewMap(): MapType,
stackitem.Null{}: MapType, stackitem.Null{}: MapType,
stackitem.NewInterop(true): InteropInterfaceType, stackitem.NewInterop(true): InteropInterfaceType,
stackitem.Null{}: InteropInterfaceType, stackitem.Null{}: InteropInterfaceType,
} { } {
require.Truef(t, pt.Match(itm), "%s - %s", pt.String(), itm.String()) require.Truef(t, pt.Match(itm), "%s - %s", pt.String(), itm.String())
} }