From 0dd1730632077976574175968873f62701a5b46a Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Tue, 28 Jul 2020 19:05:16 +0300 Subject: [PATCH] core: store NEP5Transfer asset by ID instead of hash To avoid problems with retrieving decimals for migrated contracts. --- pkg/core/blockchain.go | 16 ++++++++-------- pkg/core/state/nep5.go | 10 +++++----- pkg/core/state/nep5_test.go | 4 ++-- pkg/rpc/server/server.go | 8 ++++++-- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index bb9525191..8df7dfd37 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -707,14 +707,6 @@ func parseUint160(addr []byte) util.Uint160 { func (bc *Blockchain) processNEP5Transfer(cache *dao.Cached, h util.Uint256, b *block.Block, sc util.Uint160, from, to []byte, amount *big.Int) { toAddr := parseUint160(to) fromAddr := parseUint160(from) - transfer := &state.NEP5Transfer{ - Asset: sc, - From: fromAddr, - To: toAddr, - Block: b.Index, - Timestamp: b.Timestamp, - Tx: h, - } var id int32 nativeContract := bc.contracts.ByHash(sc) if nativeContract != nil { @@ -726,6 +718,14 @@ func (bc *Blockchain) processNEP5Transfer(cache *dao.Cached, h util.Uint256, b * } id = assetContract.ID } + transfer := &state.NEP5Transfer{ + Asset: id, + From: fromAddr, + To: toAddr, + Block: b.Index, + Timestamp: b.Timestamp, + Tx: h, + } if !fromAddr.Equals(util.Uint160{}) { balances, err := cache.GetNEP5Balances(fromAddr) if err != nil { diff --git a/pkg/core/state/nep5.go b/pkg/core/state/nep5.go index 9a93b2f53..36ac13ec3 100644 --- a/pkg/core/state/nep5.go +++ b/pkg/core/state/nep5.go @@ -26,8 +26,8 @@ type NEP5TransferLog struct { // NEP5Transfer represents a single NEP5 Transfer event. type NEP5Transfer struct { - // Asset is a NEP5 contract hash. - Asset util.Uint160 + // Asset is a NEP5 contract ID. + Asset int32 // Address is the address of the sender. From util.Uint160 // To is the address of the receiver. @@ -132,7 +132,7 @@ func (t *NEP5Tracker) DecodeBinary(r *io.BinReader) { // EncodeBinary implements io.Serializable interface. func (t *NEP5Transfer) EncodeBinary(w *io.BinWriter) { - w.WriteBytes(t.Asset[:]) + w.WriteU32LE(uint32(t.Asset)) w.WriteBytes(t.Tx[:]) w.WriteBytes(t.From[:]) w.WriteBytes(t.To[:]) @@ -150,7 +150,7 @@ func (t *NEP5Transfer) DecodeBinary(r *io.BinReader) { // DecodeBinaryReturnCount decodes NEP5Transfer and returns the number of bytes read. func (t *NEP5Transfer) DecodeBinaryReturnCount(r *io.BinReader) int { - r.ReadBytes(t.Asset[:]) + t.Asset = int32(r.ReadU32LE()) r.ReadBytes(t.Tx[:]) r.ReadBytes(t.From[:]) r.ReadBytes(t.To[:]) @@ -160,5 +160,5 @@ func (t *NEP5Transfer) DecodeBinaryReturnCount(r *io.BinReader) int { amountBytes := make([]byte, amountLen) r.ReadBytes(amountBytes) t.Amount = *bigint.FromBytes(amountBytes) - return util.Uint160Size*3 + 8 + 4 + (8 + len(amountBytes)) + +util.Uint256Size + return 4 + util.Uint160Size*2 + 8 + 4 + (8 + len(amountBytes)) + +util.Uint256Size } diff --git a/pkg/core/state/nep5_test.go b/pkg/core/state/nep5_test.go index 9681fe2ec..507e848c0 100644 --- a/pkg/core/state/nep5_test.go +++ b/pkg/core/state/nep5_test.go @@ -50,7 +50,7 @@ func TestNEP5Tracker_EncodeBinary(t *testing.T) { func TestNEP5Transfer_DecodeBinary(t *testing.T) { expected := &NEP5Transfer{ - Asset: util.Uint160{1, 2, 3}, + Asset: 123, From: util.Uint160{5, 6, 7}, To: util.Uint160{8, 9, 10}, Amount: *big.NewInt(42), @@ -78,7 +78,7 @@ func randomTransfer(r *rand.Rand) *NEP5Transfer { return &NEP5Transfer{ Amount: *big.NewInt(int64(r.Uint64())), Block: r.Uint32(), - Asset: random.Uint160(), + Asset: int32(random.Int(10, 10000000)), From: random.Uint160(), To: random.Uint160(), Tx: random.Uint256(), diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 3593b9164..fb0de6b7a 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -549,13 +549,17 @@ func (s *Server) getNEP5Transfers(ps request.Params) (interface{}, *response.Err lg := s.chain.GetNEP5TransferLog(u) cache := make(map[util.Uint160]int64) err = lg.ForEach(func(tr *state.NEP5Transfer) error { + h, err := s.chain.GetContractScriptHash(tr.Asset) + if err != nil { + return nil + } transfer := result.NEP5Transfer{ Timestamp: tr.Timestamp, - Asset: tr.Asset, + Asset: h, Index: tr.Block, TxHash: tr.Tx, } - d, err := s.getDecimals(tr.Asset, cache) + d, err := s.getDecimals(h, cache) if err != nil { return nil }