From fe5e5ff44adcb455a65871b3c077aad7f928a9b0 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 7 Aug 2020 09:42:44 +0300 Subject: [PATCH] rpc: provide timestamps in `getnep5transfers` Set default value for the first timestamp to a week ago. --- pkg/rpc/server/server.go | 15 ++++++++++ pkg/rpc/server/server_test.go | 56 ++++++++++++++++++++++++++++------- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 07318983c..00335af5e 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -721,6 +721,18 @@ func (s *Server) getNEP5Transfers(ps request.Params) (interface{}, *response.Err return nil, response.ErrInvalidParams } + p1, p2 := ps.Value(1), ps.Value(2) + start, end, err := getTimestamps(p1, p2) + if err != nil { + return nil, response.NewInvalidParamsError("", err) + } + if p2 == nil { + end = uint32(time.Now().Unix()) + if p1 == nil { + start = uint32(time.Now().Add(-time.Hour * 24 * 7).Unix()) + } + } + bs := &result.NEP5Transfers{ Address: address.Uint160ToString(u), Received: []result.NEP5Transfer{}, @@ -728,6 +740,9 @@ func (s *Server) getNEP5Transfers(ps request.Params) (interface{}, *response.Err } tr := new(state.NEP5Transfer) err = s.chain.ForEachNEP5Transfer(u, tr, func() error { + if tr.Timestamp < start || tr.Timestamp > end { + return nil + } transfer := result.NEP5Transfer{ Timestamp: tr.Timestamp, Asset: tr.Asset, diff --git a/pkg/rpc/server/server_test.go b/pkg/rpc/server/server_test.go index 458a75603..bfec2bc7a 100644 --- a/pkg/rpc/server/server_test.go +++ b/pkg/rpc/server/server_test.go @@ -191,15 +191,20 @@ var rpcTestCases = map[string][]rpcTestCase{ params: `["notahex"]`, fail: true, }, + { + name: "invalid timestamp", + params: `["AKkkumHbBipZ46UMZJoFynJMXzSRnBvKcs", "notanumber"]`, + fail: true, + }, { name: "positive", - params: `["AKkkumHbBipZ46UMZJoFynJMXzSRnBvKcs"]`, + params: `["AKkkumHbBipZ46UMZJoFynJMXzSRnBvKcs", 0]`, result: func(e *executor) interface{} { return &result.NEP5Transfers{} }, check: checkNep5Transfers, }, { name: "positive_hash", - params: `["a90f00d94349a320376b7cb86c884b53ad76aa2b"]`, + params: `["a90f00d94349a320376b7cb86c884b53ad76aa2b", 0]`, result: func(e *executor) interface{} { return &result.NEP5Transfers{} }, check: checkNep5Transfers, }, @@ -1159,6 +1164,24 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) [] t.Run("TooBigStart", func(t *testing.T) { testGetUTXO(t, "", 300, 0) }) t.Run("RestrictAll", func(t *testing.T) { testGetUTXO(t, "", 202, 203) }) }) + + t.Run("getnep5transfers", func(t *testing.T) { + ps := []string{`"AKkkumHbBipZ46UMZJoFynJMXzSRnBvKcs"`} + h, err := e.chain.GetHeader(e.chain.GetHeaderHash(207)) + require.NoError(t, err) + ps = append(ps, strconv.Itoa(int(h.Timestamp))) + h, err = e.chain.GetHeader(e.chain.GetHeaderHash(208)) + require.NoError(t, err) + ps = append(ps, strconv.Itoa(int(h.Timestamp))) + + p := strings.Join(ps, ", ") + rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getnep5transfers", "params": [%s]}`, p) + body := doRPCCall(rpc, httpSrv.URL, t) + res := checkErrGetResult(t, body, false) + actual := new(result.NEP5Transfers) + require.NoError(t, json.Unmarshal(res, actual)) + checkNep5TransfersAux(t, e, actual, true) + }) } func (tc rpcTestCase) getResultPair(e *executor) (expected interface{}, res interface{}) { @@ -1214,6 +1237,10 @@ func checkNep5Balances(t *testing.T, e *executor, acc interface{}) { } func checkNep5Transfers(t *testing.T, e *executor, acc interface{}) { + checkNep5TransfersAux(t, e, acc, false) +} + +func checkNep5TransfersAux(t *testing.T, e *executor, acc interface{}, onlyFirst bool) { res, ok := acc.(*result.NEP5Transfers) require.True(t, ok) require.Equal(t, "AKkkumHbBipZ46UMZJoFynJMXzSRnBvKcs", res.Address) @@ -1224,20 +1251,27 @@ func checkNep5Transfers(t *testing.T, e *executor, acc interface{}) { assetHashOld, err := util.Uint160DecodeStringLE(testContractHashOld) require.NoError(t, err) - require.Equal(t, 3, len(res.Received)) + if onlyFirst { + require.Equal(t, 1, len(res.Received)) + } else { + require.Equal(t, 3, len(res.Received)) + } + require.Equal(t, "1000", res.Received[0].Amount) require.Equal(t, assetHashOld, res.Received[0].Asset) require.Equal(t, address.Uint160ToString(assetHashOld), res.Received[0].Address) - require.Equal(t, "2", res.Received[1].Amount) - require.Equal(t, assetHash, res.Received[1].Asset) - require.Equal(t, "AWLYWXB8C9Lt1nHdDZJnC5cpYJjgRDLk17", res.Received[1].Address) - require.Equal(t, uint32(0), res.Received[1].NotifyIndex) + if !onlyFirst { + require.Equal(t, "2", res.Received[1].Amount) + require.Equal(t, assetHash, res.Received[1].Asset) + require.Equal(t, "AWLYWXB8C9Lt1nHdDZJnC5cpYJjgRDLk17", res.Received[1].Address) + require.Equal(t, uint32(0), res.Received[1].NotifyIndex) - require.Equal(t, "1", res.Received[2].Amount) - require.Equal(t, assetHash, res.Received[2].Asset) - require.Equal(t, "AWLYWXB8C9Lt1nHdDZJnC5cpYJjgRDLk17", res.Received[2].Address) - require.Equal(t, uint32(1), res.Received[2].NotifyIndex) + require.Equal(t, "1", res.Received[2].Amount) + require.Equal(t, assetHash, res.Received[2].Asset) + require.Equal(t, "AWLYWXB8C9Lt1nHdDZJnC5cpYJjgRDLk17", res.Received[2].Address) + require.Equal(t, uint32(1), res.Received[2].NotifyIndex) + } require.Equal(t, 1, len(res.Sent)) require.Equal(t, "123", res.Sent[0].Amount)