From d25dddc7803cd239b1fc14666a1c650eac6228e4 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 11 Mar 2020 15:07:14 +0300 Subject: [PATCH] rpc: refactor getDecimals Use existing functions to invoke smartcontract's method instead of constructing ad-hoc script. --- pkg/rpc/server/server.go | 45 +++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 43e4091b7..6beddb0ea 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -6,7 +6,6 @@ import ( "encoding/json" "fmt" "math" - "math/big" "net/http" "strconv" @@ -23,9 +22,9 @@ import ( "github.com/nspcc-dev/neo-go/pkg/rpc/request" "github.com/nspcc-dev/neo-go/pkg/rpc/response" "github.com/nspcc-dev/neo-go/pkg/rpc/response/result" + "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/emit" - "github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/pkg/errors" "go.uber.org/zap" ) @@ -515,29 +514,33 @@ func (s *Server) getDecimals(h util.Uint160, cache map[util.Uint160]int64) (int6 if d, ok := cache[h]; ok { return d, nil } - w := io.NewBufBinWriter() - emit.Int(w.BinWriter, 0) - emit.Opcode(w.BinWriter, opcode.NEWARRAY) - emit.String(w.BinWriter, "decimals") - emit.AppCall(w.BinWriter, h, true) - v, _ := s.chain.GetTestVM() - v.LoadScript(w.Bytes()) - if err := v.Run(); err != nil { + script, err := request.CreateFunctionInvocationScript(h, request.Params{ + { + Type: request.StringT, + Value: "decimals", + }, + { + Type: request.ArrayT, + Value: []request.Param{}, + }, + }) + if err != nil { return 0, err } - res := v.PopResult() - if res == nil { + res := s.runScriptInVM(script) + if res == nil || res.State != "HALT" || len(res.Stack) == 0 { + return 0, errors.New("execution error") + } + + var d int64 + switch item := res.Stack[len(res.Stack)-1]; item.Type { + case smartcontract.IntegerType: + d = item.Value.(int64) + case smartcontract.ByteArrayType: + d = emit.BytesToInt(item.Value.([]byte)).Int64() + default: return 0, errors.New("invalid result") } - bi, ok := res.(*big.Int) - if !ok { - bs, ok := res.([]byte) - if !ok { - return 0, errors.New("invalid result") - } - bi = emit.BytesToInt(bs) - } - d := bi.Int64() if d < 0 { return 0, errors.New("negative decimals") }