github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/smartcontract/nef/nef_test.go (about) 1 package nef 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "strconv" 7 "testing" 8 9 "github.com/nspcc-dev/neo-go/internal/random" 10 "github.com/nspcc-dev/neo-go/internal/testserdes" 11 "github.com/nspcc-dev/neo-go/pkg/io" 12 "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" 13 "github.com/nspcc-dev/neo-go/pkg/util" 14 "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" 15 "github.com/stretchr/testify/require" 16 ) 17 18 func TestEncodeDecodeBinary(t *testing.T) { 19 script := []byte{12, 32, 84, 35, 14} 20 expected := &File{ 21 Header: Header{ 22 Magic: Magic, 23 Compiler: "best compiler version 1", 24 }, 25 Tokens: []MethodToken{{ 26 Hash: random.Uint160(), 27 Method: "method", 28 ParamCount: 3, 29 HasReturn: true, 30 CallFlag: callflag.WriteStates, 31 }}, 32 Script: script, 33 } 34 35 t.Run("invalid Magic", func(t *testing.T) { 36 expected.Header.Magic = 123 37 checkDecodeError(t, expected) 38 }) 39 40 t.Run("invalid checksum", func(t *testing.T) { 41 expected.Header.Magic = Magic 42 expected.Checksum = 123 43 checkDecodeError(t, expected) 44 }) 45 46 t.Run("zero-length script", func(t *testing.T) { 47 expected.Script = make([]byte, 0) 48 expected.Checksum = expected.CalculateChecksum() 49 checkDecodeError(t, expected) 50 }) 51 52 t.Run("invalid script length", func(t *testing.T) { 53 newScript := make([]byte, stackitem.MaxSize+1) 54 expected.Script = newScript 55 expected.Checksum = expected.CalculateChecksum() 56 checkDecodeError(t, expected) 57 }) 58 t.Run("invalid tokens list", func(t *testing.T) { 59 expected.Script = script 60 expected.Tokens[0].Method = "_reserved" 61 expected.Checksum = expected.CalculateChecksum() 62 checkDecodeError(t, expected) 63 }) 64 65 t.Run("positive", func(t *testing.T) { 66 expected.Script = script 67 expected.Tokens[0].Method = "method" 68 expected.Checksum = expected.CalculateChecksum() 69 expected.Header.Magic = Magic 70 testserdes.EncodeDecodeBinary(t, expected, &File{}) 71 }) 72 t.Run("positive with empty tokens", func(t *testing.T) { 73 expected.Script = script 74 // Check `Tokens` won't be deserialized to `nil`. We expect them to be non-nil slice in the related code. 75 expected.Tokens = []MethodToken{} 76 expected.Checksum = expected.CalculateChecksum() 77 expected.Header.Magic = Magic 78 testserdes.EncodeDecodeBinary(t, expected, &File{}) 79 }) 80 t.Run("invalid reserved bytes", func(t *testing.T) { 81 expected.Script = script 82 expected.Tokens = expected.Tokens[:0] 83 expected.Checksum = expected.CalculateChecksum() 84 bytes, err := testserdes.EncodeBinary(expected) 85 require.NoError(t, err) 86 87 sz := io.GetVarSize(&expected.Header) 88 bytes[sz] = 1 89 err = testserdes.DecodeBinary(bytes, new(File)) 90 require.ErrorIs(t, err, errInvalidReserved) 91 92 bytes[sz] = 0 93 bytes[sz+3] = 1 94 err = testserdes.DecodeBinary(bytes, new(File)) 95 require.ErrorIs(t, err, errInvalidReserved) 96 }) 97 } 98 99 func checkDecodeError(t *testing.T, expected *File) { 100 bytes, err := testserdes.EncodeBinary(expected) 101 require.NoError(t, err) 102 require.Error(t, testserdes.DecodeBinary(bytes, &File{})) 103 } 104 105 func TestBytesFromBytes(t *testing.T) { 106 script := []byte{12, 32, 84, 35, 14} 107 expected := File{ 108 Header: Header{ 109 Magic: Magic, 110 Compiler: "best compiler version 1", 111 }, 112 Tokens: []MethodToken{{ 113 Hash: random.Uint160(), 114 Method: "someMethod", 115 ParamCount: 3, 116 HasReturn: true, 117 CallFlag: callflag.WriteStates, 118 }}, 119 Script: script, 120 } 121 expected.Checksum = expected.CalculateChecksum() 122 123 bytes, err := expected.Bytes() 124 require.NoError(t, err) 125 actual, err := FileFromBytes(bytes) 126 require.NoError(t, err) 127 require.Equal(t, expected, actual) 128 } 129 130 func TestNewFileFromBytesLimits(t *testing.T) { 131 expected := File{ 132 Header: Header{ 133 Magic: Magic, 134 Compiler: "best compiler version 1", 135 }, 136 Tokens: []MethodToken{{ 137 Hash: random.Uint160(), 138 Method: "someMethod", 139 ParamCount: 3, 140 HasReturn: true, 141 CallFlag: callflag.WriteStates, 142 }}, 143 Script: make([]byte, stackitem.MaxSize-100), 144 } 145 expected.Checksum = expected.CalculateChecksum() 146 147 bytes, err := expected.BytesLong() 148 require.NoError(t, err) 149 _, err = FileFromBytes(bytes) 150 require.Error(t, err) 151 require.Contains(t, err.Error(), "invalid NEF file size") 152 } 153 154 func TestMarshalUnmarshalJSON(t *testing.T) { 155 expected := &File{ 156 Header: Header{ 157 Magic: Magic, 158 Compiler: "test.compiler-test.ver", 159 }, 160 Tokens: []MethodToken{{ 161 Hash: util.Uint160{0x12, 0x34, 0x56, 0x78, 0x91, 0x00}, 162 Method: "someMethod", 163 ParamCount: 3, 164 HasReturn: true, 165 CallFlag: callflag.WriteStates, 166 }}, 167 Script: []byte{1, 2, 3, 4}, 168 } 169 expected.Checksum = expected.CalculateChecksum() 170 171 data, err := json.Marshal(expected) 172 require.NoError(t, err) 173 require.JSONEq(t, `{ 174 "magic":`+strconv.FormatUint(uint64(Magic), 10)+`, 175 "compiler": "test.compiler-test.ver", 176 "source": "", 177 "tokens": [ 178 { 179 "hash": "0x`+expected.Tokens[0].Hash.StringLE()+`", 180 "method": "someMethod", 181 "paramcount": 3, 182 "hasreturnvalue": true, 183 "callflags": "`+expected.Tokens[0].CallFlag.String()+`" 184 } 185 ], 186 "script": "`+base64.StdEncoding.EncodeToString(expected.Script)+`", 187 "checksum":`+strconv.FormatUint(uint64(expected.Checksum), 10)+`}`, string(data)) 188 189 actual := new(File) 190 require.NoError(t, json.Unmarshal(data, actual)) 191 require.Equal(t, expected, actual) 192 }