github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/core/wavm/env_test.go (about) 1 // Copyright 2019 The go-vnt Authors 2 // This file is part of the go-vnt library. 3 // 4 // The go-vnt library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-vnt library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-vnt library. If not, see <http://www.gnu.org/licenses/>. 16 17 package wavm 18 19 import ( 20 "testing" 21 22 "fmt" 23 "io/ioutil" 24 "math/big" 25 "os" 26 "path/filepath" 27 28 "github.com/stretchr/testify/assert" 29 "github.com/vntchain/go-vnt/accounts/abi" 30 "github.com/vntchain/go-vnt/common" 31 "github.com/vntchain/go-vnt/core/state" 32 "github.com/vntchain/go-vnt/core/vm" 33 "github.com/vntchain/go-vnt/core/wavm/contract" 34 g "github.com/vntchain/go-vnt/core/wavm/gas" 35 "github.com/vntchain/go-vnt/log" 36 "github.com/vntchain/go-vnt/params" 37 "github.com/vntchain/go-vnt/trie" 38 "github.com/vntchain/go-vnt/vntdb" 39 "github.com/vntchain/vnt-wasm/exec" 40 "github.com/vntchain/vnt-wasm/validate" 41 "github.com/vntchain/vnt-wasm/wasm" 42 ) 43 44 var debugCodePath = filepath.Join("tests/debug", "program.wasm") 45 var debugAbiPath = filepath.Join("tests/debug", "abi.json") 46 47 var eventCodePath = filepath.Join("tests/event", "program.wasm") 48 var eventAbiPath = filepath.Join("tests/event", "abi.json") 49 50 var logMsg = "" 51 var logCtx []interface{} = nil 52 var logHandler = log.FuncHandler(func(r *log.Record) error { 53 logMsg = r.Msg 54 logCtx = r.Ctx 55 return nil 56 }) 57 58 var tHash common.Hash 59 var bHash common.Hash 60 61 func clearLog() { 62 logMsg = "" 63 logCtx = nil 64 } 65 66 func init() { 67 //log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) 68 log.Root().SetHandler(logHandler) 69 } 70 71 type fakeDB struct { 72 } 73 74 func (db *fakeDB) OpenTrie(root common.Hash) (state.Trie, error) { 75 return nil, nil 76 } 77 78 func (db *fakeDB) OpenStorageTrie(addrHash, root common.Hash) (state.Trie, error) { 79 return nil, nil 80 } 81 82 // CopyTrie returns an independent copy of the given trie. 83 func (db *fakeDB) CopyTrie(state.Trie) state.Trie { 84 return nil 85 } 86 87 // ContractCode retrieves a particular contract's code. 88 func (db *fakeDB) ContractCode(addrHash, codeHash common.Hash) ([]byte, error) { 89 return nil, nil 90 } 91 92 // ContractCodeSize retrieves a particular contracts code's size. 93 func (db *fakeDB) ContractCodeSize(addrHash, codeHash common.Hash) (int, error) { 94 return 0, nil 95 } 96 97 // TrieDB retrieves the low level trie database used for data storage. 98 func (db *fakeDB) TrieDB() *trie.Database { 99 return nil 100 } 101 102 func readAbi(abiPath string) abi.ABI { 103 abiData, err := ioutil.ReadFile(abiPath) 104 if err != nil { 105 log.Crit("could not read abi: ", "error", err) 106 } 107 108 abi, err := GetAbi(abiData) 109 if err != nil { 110 log.Crit("could not read abi: ", "error", err) 111 } 112 113 return abi 114 } 115 116 func importer(name string) (*wasm.Module, error) { 117 f, err := os.Open(name + ".wasm") 118 if err != nil { 119 return nil, err 120 } 121 defer f.Close() 122 123 m, err := wasm.ReadModule(f, nil) 124 if err != nil { 125 return nil, err 126 } 127 err = validate.VerifyModule(m) 128 if err != nil { 129 return nil, err 130 } 131 return m, nil 132 } 133 134 func getVM(codeFile string, abiPath string) (*exec.Interpreter, EnvFunctions) { 135 var fileHandler, err = os.Open(codeFile) 136 defer fileHandler.Close() 137 abi := readAbi(abiPath) 138 addr := common.BytesToAddress([]byte("0xd2be7e0d40c1a73ec1709f00b11cb5e24c784077")) 139 140 chainconfig := ¶ms.ChainConfig{HubbleBlock: big.NewInt(0)} 141 gasRule := g.NewGas(false) 142 gasTable := chainconfig.GasTable(new(big.Int).SetInt64(10000)) 143 contract := contract.NewWASMContract(vm.AccountRef(addr), 144 vm.AccountRef(addr), big.NewInt(100), 200000) 145 gasCounter := g.NewGasCounter(contract, gasTable) 146 cc := ChainContext{ 147 BlockNumber: big.NewInt(1), 148 Contract: contract, 149 Abi: abi, 150 GasRule: gasRule, 151 GasCounter: gasCounter, 152 GasLimit: 10000000, 153 Wavm: &WAVM{ 154 wavmConfig: Config{Debug: true, Tracer: NewWasmLogger(nil)}, 155 Wavm: &Wavm{}, 156 }, 157 } 158 159 cc.StateDB = prepareState() 160 cc.StateDB.GetOrNewStateObject(cc.Contract.Address()) 161 162 envModule := EnvModule{} 163 envModule.InitModule(&cc) 164 165 resolveHost := func(name string) (*wasm.Module, error) { 166 return envModule.GetModule(), nil 167 } 168 169 m, err := wasm.ReadModule(fileHandler, resolveHost) 170 171 fmt.Println(err) 172 if err != nil { 173 log.Crit("could not read module: ", "error", err) 174 } 175 176 //compiled, err := CompileModule(m, cc) 177 //compiled := make([]vnt.Compiled, 0) 178 179 vm, err := exec.NewInterpreter(m, nil, instantiateMemory, cc.Wavm.Wavm.captureOp, cc.Wavm.Wavm.captureEnvFunctionStart, cc.Wavm.Wavm.captureEnvFunctionEnd, false) 180 if err != nil { 181 log.Crit("failed to create vm: ", "error", err) 182 } 183 vm.ResetContext() 184 185 return vm, envModule.GetEnvFunctions() 186 } 187 188 func handlePanic(t *testing.T, msg string) { 189 if r := recover(); r != nil { 190 assert.Equal(t, msg, r) 191 } else { 192 assert.Equal(t, 1, 2) 193 } 194 } 195 196 func TestVM_PrintAddress(t *testing.T) { 197 log.Root().SetHandler(logHandler) 198 defer clearLog() 199 vm, ef := getVM(debugCodePath, debugAbiPath) 200 ef.ctx.Wavm.Wavm.SetFuncName("init") 201 202 var mutable = true 203 proc := exec.NewWavmProcess(vm.VM, vm.Memory, &mutable) 204 205 fmt.Println("testing...") 206 207 remarkIdx := uint64(vm.Memory.SetBytes([]byte("The sender is: "))) 208 strIdx := uint64(vm.Memory.SetBytes(common.HexToAddress("0x880d84da2bE4D02830b03FF4CF0840924Be6B0A6").Bytes())) 209 210 ef.PrintAddress(proc, remarkIdx, strIdx) 211 212 expectedMsg := "Contract Debug >>>>" 213 214 assert.Equal(t, expectedMsg, logMsg) 215 assert.Equal(t, 4, len(logCtx)) 216 assert.Equal(t, "init", logCtx[1]) 217 assert.Equal(t, "The sender is: 0x880d84da2bE4D02830b03FF4CF0840924Be6B0A6", logCtx[3]) 218 } 219 220 func TestVM_PrintStr(t *testing.T) { 221 log.Root().SetHandler(logHandler) 222 defer clearLog() 223 224 vm, ef := getVM(debugCodePath, debugAbiPath) 225 226 ef.ctx.Wavm.Wavm.SetFuncName("init") 227 var mutable = true 228 229 proc := exec.NewWavmProcess(vm.VM, vm.Memory, &mutable) 230 231 fmt.Println("testing...") 232 233 remarkIdx := uint64(vm.Memory.SetBytes([]byte("The contract name is: "))) 234 strIdx := uint64(vm.Memory.SetBytes([]byte("VNT Token"))) 235 236 ef.PrintStr(proc, remarkIdx, strIdx) 237 238 expectedMsg := "Contract Debug >>>>" 239 240 assert.Equal(t, expectedMsg, logMsg) 241 assert.Equal(t, 4, len(logCtx)) 242 assert.Equal(t, "init", logCtx[1]) 243 assert.Equal(t, "The contract name is: VNT Token", logCtx[3]) 244 } 245 246 func TestVM_PrintInt64T(t *testing.T) { 247 log.Root().SetHandler(logHandler) 248 defer clearLog() 249 vm, ef := getVM(debugCodePath, debugAbiPath) 250 var mutable = true 251 252 proc := exec.NewWavmProcess(vm.VM, vm.Memory, &mutable) 253 254 fmt.Println("testing...") 255 256 remarkIdx := uint64(vm.Memory.SetBytes([]byte("The value is: "))) 257 intValue := uint64(0x0f) 258 259 expectedMsg := "Contract Debug >>>>" 260 261 ef.PrintUint64T(proc, remarkIdx, intValue) 262 263 assert.Equal(t, expectedMsg, logMsg) 264 assert.Equal(t, 4, len(logCtx)) 265 assert.Equal(t, "The value is: 15", logCtx[3]) 266 } 267 268 func TestVM_PrintInt32T(t *testing.T) { 269 log.Root().SetHandler(logHandler) 270 defer clearLog() 271 vm, ef := getVM(debugCodePath, debugAbiPath) 272 273 var mutable = true 274 275 proc := exec.NewWavmProcess(vm.VM, vm.Memory, &mutable) 276 277 fmt.Println("testing...") 278 279 remarkIdx := uint64(vm.Memory.SetBytes([]byte("The value is: "))) 280 intValue := uint64(0x01) 281 282 expectedMsg := "Contract Debug >>>>" 283 284 ef.PrintUint64T(proc, remarkIdx, intValue) 285 286 assert.Equal(t, expectedMsg, logMsg) 287 assert.Equal(t, 4, len(logCtx)) 288 assert.Equal(t, "The value is: 1", logCtx[3]) 289 } 290 291 func TestVM_PrintUint64T(t *testing.T) { 292 log.Root().SetHandler(logHandler) 293 defer clearLog() 294 vm, ef := getVM(debugCodePath, debugAbiPath) 295 296 var mutable = true 297 298 proc := exec.NewWavmProcess(vm.VM, vm.Memory, &mutable) 299 300 fmt.Println("testing...") 301 302 remarkIdx := uint64(vm.Memory.SetBytes([]byte("The value is: "))) 303 intValue := uint64(0x01) 304 305 expectedMsg := "Contract Debug >>>>" 306 307 ef.PrintUint64T(proc, remarkIdx, intValue) 308 309 assert.Equal(t, expectedMsg, logMsg) 310 assert.Equal(t, 4, len(logCtx)) 311 assert.Equal(t, "The value is: 1", logCtx[3]) 312 } 313 314 func TestVM_PrintUint32T(t *testing.T) { 315 log.Root().SetHandler(logHandler) 316 defer clearLog() 317 vm, ef := getVM(debugCodePath, debugAbiPath) 318 319 var mutable = true 320 321 proc := exec.NewWavmProcess(vm.VM, vm.Memory, &mutable) 322 323 fmt.Println("testing...") 324 325 remarkIdx := uint64(vm.Memory.SetBytes([]byte("The value is: "))) 326 intValue := uint64(0x01) 327 328 expectedMsg := "Contract Debug >>>>" 329 330 ef.PrintUint64T(proc, remarkIdx, intValue) 331 332 assert.Equal(t, expectedMsg, logMsg) 333 assert.Equal(t, 4, len(logCtx)) 334 assert.Equal(t, "The value is: 1", logCtx[3]) 335 } 336 337 func TestVM_getPrintRemark(t *testing.T) { 338 defer clearLog() 339 vm, ef := getVM(debugCodePath, debugAbiPath) 340 341 var mutable = true 342 343 proc := exec.NewWavmProcess(vm.VM, vm.Memory, &mutable) 344 345 fmt.Println("testing...") 346 347 remarkIdx := uint64(vm.Memory.SetBytes([]byte("The value is: "))) 348 349 remark := ef.getPrintRemark(proc, remarkIdx) 350 351 assert.Equal(t, "The value is: ", remark) 352 } 353 354 // 355 //func TestVM_Event_One_Topic_No_Data(t *testing.T) { 356 // defer clearLog() 357 // 358 // vm, _ := getVM(eventCodePath, eventAbiPath) 359 // //proc := exec.NewWavmProcess(vm.VM, vm.Memory) 360 361 //fmt.Println("testing...") 362 // 363 // // make a fake db 364 // db := &fakeDB{} 365 // 366 // // make a fake statedb object 367 // value := make([]byte, 1) 368 // value[0] = 0x01 369 // hash := common.BytesToHash(value) 370 // stateDB, _ := state.New(hash, db) 371 // tHash := common.BytesToHash(value) 372 // bHash := common.BytesToHash(value) 373 // stateDB.Prepare(tHash, bHash, 1) 374 // vm.StateDB = stateDB 375 // 376 // // construct the memorydata 377 // evtName := "INIT" 378 // addr := "0xd2be7e0d40c1a73ec1709f00b11cb5e24c784077" 379 // address := common.HexToAddress(addr) 380 // 381 // // construct the locals 382 // locals := vm.GetContext().GetLocals() 383 // locals = append(locals, uint64(vm.Memory.SetBytes([]byte(evtName)))) 384 // locals = append(locals, uint64(vm.Memory.SetBytes(address.Bytes()))) 385 // vm.GetContext().SetLocals(locals) 386 // 387 // // Execute the target method 388 // vm.Event() 389 // 390 // // check the result 391 // addedLog := stateDB.GetLogs(tHash) 392 // assert.Equal(t, 1, len(addedLog)) 393 // assert.Equal(t, tHash, addedLog[0].TxHash) 394 // assert.Equal(t, bHash, addedLog[0].BlockHash) 395 // assert.Equal(t, uint(1), addedLog[0].TxIndex) 396 // assert.Equal(t, uint(0), addedLog[0].Index) 397 // assert.Equal(t, 0, len(addedLog[0].Data)) 398 // assert.Equal(t, 2, len(addedLog[0].Topics)) 399 // assert.Equal(t, vm.Abi.Events[evtName].Id(), addedLog[0].Topics[0]) 400 // assert.Equal(t, common.BytesToHash(address.Bytes()), addedLog[0].Topics[1]) 401 //} 402 // 403 //func TestVM_Event_Two_Topic_One_Data(t *testing.T) { 404 // defer clearLog() 405 // vm, ef := getVM(eventCodePath, eventAbiPath) 406 // 407 // // construct the memorydata 408 // evtName := "TESTEVENT" 409 // addrFrom := "0xd2be7e0d40c1a73ec1709f00b11cb5e24c784077" 410 // addrTo := "0xd2be7e0d40c1a73ec1709f00b11cb5e24c784078" 411 // addressFrom := common.HexToAddress(addrFrom) 412 // addressTo := common.HexToAddress(addrTo) 413 // 414 // var mutable = true 415 // 416 // proc := exec.NewWavmProcess(vm.VM, vm.Memory, &mutable) 417 // 418 // fmt.Println("testing...") 419 // 420 // // construct the locals 421 // var1 := uint64(proc.SetBytes(addressFrom.Bytes())) 422 // var2 := uint64(proc.SetBytes(addressTo.Bytes())) 423 // var3 := uint64(1000) 424 // var4 := uint64(proc.SetBytes([]byte("this is a balance transfer"))) 425 // 426 // fn := ef.GetFuncTable()[evtName].Host 427 // args := make([]reflect.Value, 5) 428 // args[0] = reflect.ValueOf(proc) 429 // //args[1] = reflect.ValueOf(var1) 430 // //args[2] = reflect.ValueOf(var2) 431 // //args[3] = reflect.ValueOf(var3) 432 // //args[4] = reflect.ValueOf(var4) 433 // 434 // //arg1 := reflect.New(fn.Type().In(0)).Elem() 435 // //arg2 := reflect.New(fn.Type().In(1)).Elem() 436 // //arg3 := reflect.New(fn.Type().In(2)).Elem() 437 // //arg4 := reflect.New(fn.Type().In(3)).Elem() 438 // // 439 // //arg1.SetUint(var1) 440 // //arg2.SetUint(var2) 441 // //arg3.SetUint(var3) 442 // //arg4.SetUint(var4) 443 // 444 // args[1] = reflect.ValueOf(var1) 445 // args[2] = reflect.ValueOf(var2) 446 // args[3] = reflect.ValueOf(var3) 447 // args[4] = reflect.ValueOf(var4) 448 // 449 // valueByte := make([]byte, 8) 450 // binary.BigEndian.PutUint64(valueByte, uint64(1000)) 451 // 452 // // Execute the target method 453 // fn.Call(args) 454 // 455 // // check the result 456 // addedLog := ef.ctx.StateDB.GetLogs(tHash) 457 // assert.Equal(t, 1, len(addedLog)) 458 // assert.Equal(t, tHash, addedLog[0].TxHash) 459 // assert.Equal(t, bHash, addedLog[0].BlockHash) 460 // assert.Equal(t, uint(1), addedLog[0].TxIndex) 461 // assert.Equal(t, uint(0), addedLog[0].Index) 462 // assert.Equal(t, 128, len(addedLog[0].Data)) 463 // assert.Equal(t, valueByte, addedLog[0].Data[24:32]) 464 // assert.Equal(t, 3, len(addedLog[0].Topics)) 465 // assert.Equal(t, ef.ctx.Abi.Events[evtName].Id(), addedLog[0].Topics[0]) 466 // assert.Equal(t, common.BytesToHash(addressFrom.Bytes()), addedLog[0].Topics[1]) 467 // assert.Equal(t, common.BytesToHash(addressTo.Bytes()), addedLog[0].Topics[2]) 468 //} 469 470 func prepareState() *state.StateDB { 471 // make a fake db 472 //db := &fakeDB{} 473 // 474 //// make a fake statedb object 475 //value := make([]byte, 1) 476 //value[0] = 0x01 477 //hash := common.BytesToHash(value) 478 //stateDB, _ := state.New(hash, db) 479 //tHash := common.BytesToHash(value) 480 //bHash := common.BytesToHash(value) 481 //stateDB.Prepare(tHash, bHash, 1) 482 483 db := vntdb.NewMemDatabase() 484 value := make([]byte, 1) 485 value[0] = 0x01 486 state, _ := state.New(common.Hash{}, state.NewDatabase(db)) 487 tHash = common.BytesToHash(value) 488 bHash = common.BytesToHash(value) 489 state.Prepare(tHash, bHash, 1) 490 491 return state 492 } 493 494 func TestVM_Address(t *testing.T) { 495 //log.Root().SetHandler(logHandler) 496 //defer clearLog() 497 vm, ef := getVM(eventCodePath, eventAbiPath) 498 var mutable = true 499 500 proc := exec.NewWavmProcess(vm.VM, vm.Memory, &mutable) 501 502 fmt.Println("testing...") 503 504 address := string("0x0523029b179009a28a7fae478cd0c2e5ba2adc38") 505 506 offset := vm.Memory.SetBytes([]byte(address)) 507 508 tOffset := ef.AddressFrom(proc, uint64(offset)) 509 510 strBytes := vm.Memory.GetPtr(tOffset) 511 assert.Equal(t, common.HexToAddress(address).String(), common.BytesToAddress(strBytes).String()) 512 } 513 514 func TestVM_AddressNoPrefix(t *testing.T) { 515 //log.Root().SetHandler(logHandler) 516 //defer clearLog() 517 vm, ef := getVM(eventCodePath, eventAbiPath) 518 519 mutable := true 520 521 proc := exec.NewWavmProcess(vm.VM, vm.Memory, &mutable) 522 523 fmt.Println("testing...") 524 525 address := string("0523029b179009a28a7fae478cd0c2e5ba2adc38") 526 527 offset := vm.Memory.SetBytes([]byte(address)) 528 529 tOffset := ef.AddressFrom(proc, uint64(offset)) 530 531 strBytes := vm.Memory.GetPtr(tOffset) 532 533 assert.Equal(t, common.HexToAddress(address).String(), common.BytesToAddress(strBytes).String()) 534 } 535 536 func TestVM_AddressTooShort(t *testing.T) { 537 //log.Root().SetHandler(logHandler) 538 //defer clearLog() 539 //defer handlePanic(t, "wrong format of address string literal '0x0523029b179009a28a7fae478cd0c2e5ba2adc' with length '40'") 540 vm, ef := getVM(eventCodePath, eventAbiPath) 541 542 mutable := true 543 544 proc := exec.NewWavmProcess(vm.VM, vm.Memory, &mutable) 545 546 fmt.Println("testing...") 547 548 address := string("0x0523029b179009a28a7fae478cd0c2e5ba2adc") 549 550 offset := vm.Memory.SetBytes([]byte(address)) 551 552 dest := string("0x00523029b179009a28a7fae478cd0c2e5ba2adc") 553 554 tOffset := ef.AddressFrom(proc, uint64(offset)) 555 556 strBytes := vm.Memory.GetPtr(tOffset) 557 558 assert.Equal(t, common.HexToAddress(dest).String(), common.BytesToAddress(strBytes).String()) 559 560 } 561 562 func TestVM_AddressTooLong(t *testing.T) { 563 //log.Root().SetHandler(logHandler) 564 //defer clearLog() 565 //defer handlePanic(t, "wrong format of address string literal '0x0523029b179009a28a7fae478cd0c2e5ba2adc' with length '40'") 566 vm, ef := getVM(eventCodePath, eventAbiPath) 567 568 mutable := true 569 570 proc := exec.NewWavmProcess(vm.VM, vm.Memory, &mutable) 571 572 fmt.Println("testing...") 573 574 address := string("0x0523029b179009a28a7fae478cd0c2e5ba2adc00") 575 576 offset := vm.Memory.SetBytes([]byte(address)) 577 578 dest := string("0x523029b179009a28a7fae478cd0c2e5ba2adc00") 579 580 tOffset := ef.AddressFrom(proc, uint64(offset)) 581 582 strBytes := vm.Memory.GetPtr(tOffset) 583 584 assert.Equal(t, common.HexToAddress(dest).String(), common.BytesToAddress(strBytes).String()) 585 586 }