Repository: trustwallet/blockatlas
Pull request #1257 (2020-10-27 21:54:26)

[Zilliqa] Fix block number and timestamp in block parsing
http://localhost:8420/v2/zilliqa/blocks/850321

<img width="926" alt="Screen Shot 2020-10-27 at 3 58 18 PM" src="https://user-images.githubusercontent.com/1641795/97370878-3be07600-186d-11eb-9601-0ad421ecd7c0.png">


codecov[bot]: # [Codecov](https://codecov.io/gh/trustwallet/blockatlas/pull/1257?src=pr&el=h1) Report
> Merging [#1257](https://codecov.io/gh/trustwallet/blockatlas/pull/1257?src=pr&el=desc) into [master](https://codecov.io/gh/trustwallet/blockatlas/commit/3b76b7abe017bbd22e82f6854f5f9b8020698148?el=desc) will **decrease** coverage by `0%`.
> The diff coverage is `35%`.

[![Impacted file tree graph](https://codecov.io/gh/trustwallet/blockatlas/pull/1257/graphs/tree.svg?width=650&height=150&src=pr&token=jnrjoEQAqv)](https://codecov.io/gh/trustwallet/blockatlas/pull/1257?src=pr&el=tree)

```diff
@@          Coverage Diff           @@
##           master   #1257   +/-   ##
======================================
- Coverage      41%     41%   -1%     
======================================
  Files         162     162           
  Lines        5079    5088    +9     
======================================
+ Hits         2130    2132    +2     
- Misses       2761    2767    +6     
- Partials      188     189    +1     
```


| [Impacted Files](https://codecov.io/gh/trustwallet/blockatlas/pull/1257?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [platform/zilliqa/rpc.go](https://codecov.io/gh/trustwallet/blockatlas/pull/1257/diff?src=pr&el=tree#diff-cGxhdGZvcm0vemlsbGlxYS9ycGMuZ28=) | `0% <0%> (ø)` | |
| [platform/zilliqa/model.go](https://codecov.io/gh/trustwallet/blockatlas/pull/1257/diff?src=pr&el=tree#diff-cGxhdGZvcm0vemlsbGlxYS9tb2RlbC5nbw==) | `70% <71%> (-3%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/trustwallet/blockatlas/pull/1257?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/trustwallet/blockatlas/pull/1257?src=pr&el=footer). Last update [3b76b7a...eb32e93](https://codecov.io/gh/trustwallet/blockatlas/pull/1257?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/Makefile b/Makefile
index 7fae898..f30b178 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@ DOCKER_LOCAL_DB_IMAGE_NAME := test_db
 DOCKER_LOCAL_MQ_IMAGE_NAME := mq
 DOCKER_LOCAL_DB_USER :=user
 DOCKER_LOCAL_DB_PASS :=pass
-DOCKER_LOCAL_DB := my_db
+DOCKER_LOCAL_DB := blockatlas
 
 # Go related variables.
 GOBASE := $(shell pwd)
diff --git a/api/endpoint/block.go b/api/endpoint/block.go
new file mode 100644
index 0000000..7b5add0
--- /dev/null
+++ b/api/endpoint/block.go
@@ -0,0 +1,39 @@
+package endpoint
+
+import (
+	"errors"
+	"net/http"
+	"strconv"
+
+	"github.com/gin-gonic/gin"
+	"github.com/trustwallet/blockatlas/pkg/blockatlas"
+)
+
+// @Summary Get Block
+// @ID block_v2
+// @Description Get Block information
+// @Accept json
+// @Produce json
+// @Tags Transactions
+// @Param coin path string true "the coin name" default(zilliqa)
+// @Param address path string true "the query address" default(850321)
+// @Failure 500 {object} ErrorResponse
+// @Router /v2/{coin}/blocks/{block} [get]
+func GetBlock(c *gin.Context, blockAPI blockatlas.BlockAPI) {
+	blockString := c.Param("block")
+	blockNumber, err := strconv.ParseUint(blockString, 10, 32)
+
+	if err != nil || blockNumber <= 1 {
+		c.AbortWithStatusJSON(http.StatusBadRequest, errorResponse(errors.New("invalid block number")))
+		return
+	}
+
+	block, err := blockAPI.GetBlockByNumber(int64(blockNumber))
+
+	if err != nil {
+		c.AbortWithStatusJSON(http.StatusBadRequest, errorResponse(errors.New("block number not found")))
+		return
+	}
+
+	c.JSON(http.StatusOK, &block)
+}
diff --git a/api/registry.go b/api/registry.go
index 50d0cc1..8925a61 100644
--- a/api/registry.go
+++ b/api/registry.go
@@ -1,6 +1,8 @@
 package api
 
 import (
+	"time"
+
 	"github.com/chenjiandongx/ginprom"
 	"github.com/gin-gonic/gin"
 	"github.com/prometheus/client_golang/prometheus/promhttp"
@@ -10,7 +12,6 @@ import (
 	"github.com/trustwallet/blockatlas/platform"
 	"github.com/trustwallet/blockatlas/services/tokenindexer"
 	"github.com/trustwallet/blockatlas/services/tokensearcher"
-	"time"
 )
 
 func RegisterTransactionsAPI(router gin.IRouter, api blockatlas.Platform) {
@@ -38,6 +39,12 @@ func RegisterTransactionsAPI(router gin.IRouter, api blockatlas.Platform) {
 			endpoint.GetTransactionsHistory(c, txAPI, tokenTxAPI)
 		})
 	}
+
+	if blockAPI, ok := api.(blockatlas.BlockAPI); ok {
+		router.GET("/v2/"+handle+"/blocks/:block", func(c *gin.Context) {
+			endpoint.GetBlock(c, blockAPI)
+		})
+	}
 }
 
 func RegisterTokensAPI(router gin.IRouter, api blockatlas.Platform) {
diff --git a/config.yml b/config.yml
index 4f06471..d5ad0a0 100644
--- a/config.yml
+++ b/config.yml
@@ -41,8 +41,8 @@ observer:
       prefetch_count: 10
 
 postgres:
-  uri: postgresql://user:pass@localhost/my_db?sslmode=disable
-  read_uri: postgresql://user:pass@localhost/my_db?sslmode=disable
+  uri: postgresql://user:pass@localhost/blockatlas?sslmode=disable
+  read_uri: postgresql://user:pass@localhost/blockatlas?sslmode=disable
   log: false
 
 # [BNB] Binance DEX: https://www.binance.org/
diff --git a/configmock.yml b/configmock.yml
index 4035fe9..a91ad5c 100644
--- a/configmock.yml
+++ b/configmock.yml
@@ -35,8 +35,8 @@ observer:
       prefetch_count: 10
 
 postgres:
-  uri: postgresql://user:pass@localhost/my_db?sslmode=disable
-  read_uri: postgresql://user:pass@localhost/my_db?sslmode=disable
+  uri: postgresql://user:pass@localhost/blockatlas?sslmode=disable
+  read_uri: postgresql://user:pass@localhost/blockatlas?sslmode=disable
   log: false
 
 # [BNB] Binance DEX: https://wallet.binance.org
diff --git a/db/asset.go b/db/asset.go
index 1fa4984..db14c7e 100644
--- a/db/asset.go
+++ b/db/asset.go
@@ -2,11 +2,15 @@ package db
 
 import (
 	"context"
-	"gorm.io/gorm"
-	"gorm.io/gorm/clause"
+	"encoding/json"
 	"time"
 	"unicode/utf8"
 
+	"gorm.io/gorm"
+	"gorm.io/gorm/clause"
+
+	gocache "github.com/patrickmn/go-cache"
+
 	"github.com/trustwallet/blockatlas/db/models"
 )
 
@@ -17,15 +21,28 @@ func (i *Instance) AddNewAssets(assets []models.Asset, ctx context.Context) erro
 	}
 	uniqueAssets := getUniqueAssets(assets)
 	uniqueAssets = filterAssets(uniqueAssets)
-	existingAssets, err := i.GetAssetsByIDs(models.AssetIDs(uniqueAssets), ctx)
+
+	var notInMemoryAssets []models.Asset
+	for _, a := range uniqueAssets {
+		_, err := i.MemoryGet(a.Asset, ctx)
+		if err != nil {
+			notInMemoryAssets = append(notInMemoryAssets, a)
+		}
+	}
+	if len(notInMemoryAssets) == 0 {
+		return nil
+	}
+
+	existingAssets, err := i.GetAssetsByIDs(models.AssetIDs(notInMemoryAssets), ctx)
 	if err != nil {
 		return err
 	}
 	if len(existingAssets) == 0 {
-		return db.Clauses(clause.OnConflict{DoNothing: true}).Create(&uniqueAssets).Error
+		i.addToMemory(notInMemoryAssets, ctx)
+		return db.Clauses(clause.OnConflict{DoNothing: true}).Create(&notInMemoryAssets).Error
 	}
 	allAssetsMap := make(map[string]models.Asset)
-	for _, ua := range uniqueAssets {
+	for _, ua := range notInMemoryAssets {
 		allAssetsMap[ua.Asset] = ua
 	}
 	existingAssetsMap := make(map[string]models.Asset)
@@ -42,6 +59,7 @@ func (i *Instance) AddNewAssets(assets []models.Asset, ctx context.Context) erro
 	if len(newAssets) == 0 {
 		return nil
 	}
+	i.addToMemory(newAssets, ctx)
 
 	assetsBatch := assetsBatch(newAssets, batchCount)
 
@@ -56,12 +74,26 @@ func (i *Instance) AddNewAssets(assets []models.Asset, ctx context.Context) erro
 	})
 }
 
+func (i *Instance) addToMemory(newAssets []models.Asset, ctx context.Context) {
+	for _, a := range newAssets {
+		raw, err := json.Marshal(a)
+		if err != nil {
+			continue
+		}
+		err = i.MemorySet(a.Asset, raw, gocache.NoExpiration, ctx)
+		if err != nil {
+			continue
+		}
+	}
+}
+
 func (i *Instance) GetAssetsByIDs(ids []string, ctx context.Context) ([]models.Asset, error) {
 	db := i.Gorm.WithContext(ctx)
 	// todo: look why nil and len 0 make db calls rn
 	if len(ids) == 0 {
 		return nil, nil
 	}
+
 	var dbAssets []models.Asset
 	if err := db.Where("asset in (?)", ids).Find(&dbAssets).Error; err != nil {
 		return nil, err
@@ -96,10 +128,14 @@ func assetsBatch(values []models.Asset, sizeUint uint) [][]models.Asset {
 func filterAssets(values []models.Asset) []models.Asset {
 	result := make([]models.Asset, 0, len(values))
 	for _, v := range values {
-		if utf8.ValidString(v.Asset) &&
+		valuesAreAtUTF8 := utf8.ValidString(v.Asset) &&
 			utf8.ValidString(v.Type) &&
 			utf8.ValidString(v.Symbol) &&
-			utf8.ValidString(v.Name) {
+			utf8.ValidString(v.Name)
+		valuesAreNotEmpty := v.Asset != "" &&
+			v.Type != "" && v.Symbol != "" &&
+			v.Name != "" && v.Decimals != 0
+		if valuesAreAtUTF8 && valuesAreNotEmpty {
 			result = append(result, v)
 		}
 	}
diff --git a/db/db.go b/db/db.go
index df27d65..578113a 100644
--- a/db/db.go
+++ b/db/db.go
@@ -2,19 +2,26 @@ package db
 
 import (
 	"context"
+	"errors"
+	"log"
+	"os"
+	"time"
+
 	"github.com/trustwallet/blockatlas/db/models"
 	"github.com/trustwallet/blockatlas/pkg/logger"
+
+	gocache "github.com/patrickmn/go-cache"
+
+	gormlogger "gorm.io/gorm/logger"
+
 	"gorm.io/driver/postgres"
 	"gorm.io/gorm"
-	gormlogger "gorm.io/gorm/logger"
 	"gorm.io/plugin/dbresolver"
-	"log"
-	"os"
-	"time"
 )
 
 type Instance struct {
-	Gorm *gorm.DB
+	Gorm        *gorm.DB
+	MemoryCache *gocache.Cache
 }
 
 // By gorm-bulk-insert author:
@@ -58,8 +65,8 @@ func New(uri, readUri string, logMode bool) (*Instance, error) {
 	if err != nil {
 		return nil, err
 	}
-
-	i := &Instance{Gorm: db}
+	mc := gocache.New(gocache.NoExpiration, gocache.NoExpiration)
+	i := &Instance{Gorm: db, MemoryCache: mc}
 
 	return i, nil
 }
@@ -100,3 +107,16 @@ func (i *Instance) restoreConnection(uri string) error {
 	}
 	return nil
 }
+
+func (i *Instance) MemorySet(key string, data []byte, exp time.Duration, ctx context.Context) error {
+	i.MemoryCache.Set(key, data, exp)
+	return nil
+}
+
+func (i *Instance) MemoryGet(key string, ctx context.Context) ([]byte, error) {
+	res, ok := i.MemoryCache.Get(key)
+	if !ok {
+		return nil, errors.New("not found")
+	}
+	return res.([]byte), nil
+}
diff --git a/docker-compose.yml b/docker-compose.yml
index 6fae13f..dc5240c 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -78,7 +78,7 @@ services:
     environment:
       - POSTGRES_USER=user
       - POSTGRES_PASSWORD=pass
-      - POSTGRES_DB=my_db
+      - POSTGRES_DB=blockatlas
     ports:
       - 5432:5432
     healthcheck:
diff --git a/go.mod b/go.mod
index ab29c17..ab171ff 100644
--- a/go.mod
+++ b/go.mod
@@ -6,11 +6,9 @@ require (
 	github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
 	github.com/btcsuite/btcutil v1.0.2
 	github.com/chenjiandongx/ginprom v0.0.0-20200410120253-7cfb22707fa6
-	github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect
 	github.com/deckarep/golang-set v1.7.1
 	github.com/gin-gonic/gin v1.6.3
 	github.com/imroc/req v0.3.0
-	github.com/kr/pty v1.1.8 // indirect
 	github.com/mitchellh/mapstructure v1.3.3
 	github.com/mr-tron/base58 v1.2.0
 	github.com/ory/dockertest v3.3.5+incompatible
@@ -31,7 +29,6 @@ require (
 	go.elastic.co/apm/module/apmhttp v1.8.0
 	go.elastic.co/apm/module/apmlogrus v1.8.0
 	go.uber.org/atomic v1.7.0
-	go.uber.org/multierr v1.5.0 // indirect
 	golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
 	golang.org/x/net v0.0.0-20200506145744-7e3656a0809f
 	gopkg.in/yaml.v2 v2.3.0
diff --git a/go.sum b/go.sum
index 36c6156..da02348 100644
--- a/go.sum
+++ b/go.sum
@@ -64,9 +64,11 @@ github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufo
 github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
 github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts=
 github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts=
+github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw=
 github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
 github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
 github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
+github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc=
 github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
 github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
 github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
diff --git a/platform/zilliqa/model.go b/platform/zilliqa/model.go
index 45580e0..57ce225 100644
--- a/platform/zilliqa/model.go
+++ b/platform/zilliqa/model.go
@@ -70,16 +70,25 @@ type TxRPC struct {
 	Version      string    `json:"version"`
 }
 
-func (t *TxRPC) toTx() *Tx {
+func (t *TxRPC) toTx(header BlockHeader) *Tx {
+	// t.recipient is not parsed correctly. Empty strings.
+
 	to, err := hex.DecodeString(t.ToAddr)
 	if err != nil {
 		return nil
 	}
-	height, err := strconv.ParseUint(t.Receipt.EpochNum, 10, 64)
+
+	timestamp, err := strconv.ParseUint(header.Timestamp, 10, 64)
+	if err != nil {
+		timestamp = 0
+	}
+
+	height, err := strconv.ParseUint(header.Number, 10, 64)
 	if err != nil {
 		height = 0
 	}
-	gasLimt, ok := new(big.Int).SetString(t.GasLimit, 10)
+
+	gasLimit, ok := new(big.Int).SetString(t.GasLimit, 10)
 	if !ok {
 		return nil
 	}
@@ -87,7 +96,7 @@ func (t *TxRPC) toTx() *Tx {
 	if !ok {
 		return nil
 	}
-	fee := new(big.Int).Mul(gasLimt, gasPrice)
+	fee := new(big.Int).Mul(gasLimit, gasPrice)
 
 	return &Tx{
 		Hash:           "0x" + t.ID,
@@ -96,6 +105,7 @@ func (t *TxRPC) toTx() *Tx {
 		To:             EncodeKeyHashToAddress(to),
 		Value:          t.Amount,
 		Fee:            fee.String(),
+		Timestamp:      int64(timestamp / 1000),
 		Signature:      t.Signature,
 		Nonce:          t.Nonce,
 		ReceiptSuccess: t.Receipt.Success,
@@ -122,3 +132,12 @@ func (h HashesResponse) Txs() []string {
 	}
 	return result
 }
+
+type Block struct {
+	Header BlockHeader `json:"header"`
+}
+
+type BlockHeader struct {
+	Number    string `json:"BlockNum"`
+	Timestamp string `json:"Timestamp"`
+}
diff --git a/platform/zilliqa/rpc.go b/platform/zilliqa/rpc.go
index 0118cbc..e7e141d 100644
--- a/platform/zilliqa/rpc.go
+++ b/platform/zilliqa/rpc.go
@@ -1,9 +1,10 @@
 package zilliqa
 
 import (
-	"github.com/imroc/req"
 	"strconv"
 
+	"github.com/imroc/req"
+
 	"github.com/mitchellh/mapstructure"
 	"github.com/trustwallet/blockatlas/pkg/blockatlas"
 )
@@ -22,7 +23,7 @@ func (c *RpcClient) GetTx(hash string) (tx TxRPC, err error) {
 	return
 }
 
-func (c *RpcClient) GetBlockByNumber(number int64) ([]string, error) {
+func (c *RpcClient) GetTransactionsHashesInBlock(number int64) ([]string, error) {
 	strNumber := strconv.FormatInt(number, 10)
 	requestBody := &blockatlas.RpcRequest{
 		JsonRpc: blockatlas.JsonRpcVersion,
@@ -43,11 +44,16 @@ func (c *RpcClient) GetBlockByNumber(number int64) ([]string, error) {
 
 func (c *RpcClient) GetTxInBlock(number int64) ([]Tx, error) {
 	txs := make([]Tx, 0)
-	hashes, err := c.GetBlockByNumber(number)
+	hashes, err := c.GetTransactionsHashesInBlock(number)
 	if err != nil || len(hashes) == 0 {
 		return txs, err
 	}
 
+	block, err := c.GetBlock(number)
+	if err != nil {
+		return txs, err
+	}
+
 	var requests blockatlas.RpcRequests
 	for _, hash := range hashes {
 		requests = append(requests, &blockatlas.RpcRequest{
@@ -64,9 +70,14 @@ func (c *RpcClient) GetTxInBlock(number int64) ([]Tx, error) {
 		if mapstructure.Decode(result.Result, &txRPC) != nil {
 			continue
 		}
-		if tx := txRPC.toTx(); tx != nil {
+		if tx := txRPC.toTx(block.Header); tx != nil {
 			txs = append(txs, *tx)
 		}
 	}
 	return txs, nil
 }
+
+func (c *RpcClient) GetBlock(number int64) (block Block, err error) {
+	err = c.RpcCall(&block, "GetTxBlock", []string{strconv.FormatInt(number, 10)})
+	return
+}
diff --git a/services/notifier/delivery.go b/services/notifier/delivery.go
index 6306228..cc5c5c1 100644
--- a/services/notifier/delivery.go
+++ b/services/notifier/delivery.go
@@ -17,14 +17,9 @@ func GetTransactionsFromDelivery(delivery amqp.Delivery, ctx context.Context) (b
 	span, _ := apm.StartSpan(ctx, "GetTransactionsFromDelivery", "app")
 	defer span.End()
 
-	logger.Info("--------------------------------------------")
-	logger.Info("Unmarshal: ")
-	logger.Info(delivery.Body)
 	if err := json.Unmarshal(delivery.Body, &txs); err != nil {
 		return nil, err
 	}
-	logger.Info("Done")
-	logger.Info("--------------------------------------------")
 
 	logger.Info("Consumed", logger.Params{"txs": len(txs), "coin": txs[0].Coin})
 


Test patch:
diff --git a/platform/zilliqa/model_test.go b/platform/zilliqa/model_test.go
index bd9668d..b17204f 100644
--- a/platform/zilliqa/model_test.go
+++ b/platform/zilliqa/model_test.go
@@ -31,6 +31,7 @@ func TestTxRPC_toTx(t *testing.T) {
 		To:             "zil1vxdqe9ck4metep92l4lw2mju9t6wvge9zwkyyl",
 		Value:          "1380000000000",
 		Fee:            "1000000000",
+		Timestamp:      1603831144458,
 		Signature:      "0xF165643EA12514F62297854CE14F2C4EEFE0E19670A6A64E3C497E19442D0B36A91A8790FE320EC48DDCD3E212F0863955FB6AF5436422461916319D5133886D",
 		Nonce:          "16109",
 		ReceiptSuccess: true,
@@ -43,7 +44,9 @@ func TestTxRPC_toTx(t *testing.T) {
 		return
 	}
 
-	if got := txRPC.toTx(); !reflect.DeepEqual(*got, tx) {
+	header := BlockHeader{Number: "185343", Timestamp: "1603831144458128"}
+
+	if got := txRPC.toTx(header); !reflect.DeepEqual(*got, tx) {
 		t.Errorf("TxRPC.toTx() = %v, want %v", *got, tx)
 	}
 }
diff --git a/tests/integration/db_test/tokenindexer_test.go b/tests/integration/db_test/tokenindexer_test.go
index fc053b7..7a83724 100644
--- a/tests/integration/db_test/tokenindexer_test.go
+++ b/tests/integration/db_test/tokenindexer_test.go
@@ -4,13 +4,62 @@ package db_test
 
 import (
 	"context"
+	gocache "github.com/patrickmn/go-cache"
 	assert "github.com/stretchr/testify/assert"
 	"github.com/trustwallet/blockatlas/db/models"
+	"github.com/trustwallet/blockatlas/pkg/logger"
+	"github.com/trustwallet/blockatlas/tests/integration/setup"
 	"sort"
 	"testing"
 )
 
+func Test_AddNewAssets_Simple(t *testing.T) {
+	a := []models.Asset{
+		{
+			Asset:    "c714_a",
+			Decimals: 18,
+			Name:     "A",
+			Symbol:   "ABC",
+			Type:     "BEP20",
+		},
+		{
+			Asset:    "c714_b",
+			Decimals: 18,
+			Name:     "B",
+			Symbol:   "BCD",
+			Type:     "BEP20",
+		},
+	}
+	err := database.AddNewAssets(a, context.Background())
+	assert.Nil(t, err)
+	assets, err := database.GetAssetsByIDs([]string{"c714_b", "c714_a"}, context.Background())
+	assert.Nil(t, err)
+	assert.NotNil(t, assets)
+	a = append(a, models.Asset{
+		Asset:    "c714_d",
+		Decimals: 18,
+		Name:     "D",
+		Symbol:   "DTS",
+		Type:     "BEP20",
+	})
+	err = database.AddNewAssets(a, context.Background())
+	assert.Nil(t, err)
+	err = database.AddNewAssets([]models.Asset{{
+		Asset:    "c714_p",
+		Decimals: 0,
+		Name:     "D",
+		Symbol:   "DTS",
+		Type:     "BEP20",
+	}}, context.Background())
+	assert.Nil(t, err)
+	assets, err = database.GetAssetsByIDs([]string{"c714_p"}, context.Background())
+	assert.Nil(t, err)
+	assert.Equal(t, 0, len(assets))
+}
+
 func Test_AddNewAssets(t *testing.T) {
+	setup.CleanupPgContainer(database.Gorm)
+	database.MemoryCache = gocache.New(gocache.NoExpiration, gocache.NoExpiration)
 	type testsStruct struct {
 		Name         string
 		Assets       []models.Asset
@@ -24,15 +73,15 @@ func Test_AddNewAssets(t *testing.T) {
 			Assets: []models.Asset{
 				{
 					Asset:    "c714_a",
-					Decimals: 18,
+					Decimals: 15,
 					Name:     "A",
 					Symbol:   "ABC",
 					Type:     "BEP20",
 				},
 				{
 					Asset:    "c714_b",
-					Decimals: 18,
-					Name:     "B",
+					Decimals: 16,
+					Name:     "BB",
 					Symbol:   "BCD",
 					Type:     "BEP20",
 				},
@@ -42,15 +91,15 @@ func Test_AddNewAssets(t *testing.T) {
 			WantedAssets: []models.Asset{
 				{
 					Asset:    "c714_a",
-					Decimals: 18,
+					Decimals: 15,
 					Name:     "A",
 					Symbol:   "ABC",
 					Type:     "BEP20",
 				},
 				{
 					Asset:    "c714_b",
-					Decimals: 18,
-					Name:     "B",
+					Decimals: 16,
+					Name:     "BB",
 					Symbol:   "BCD",
 					Type:     "BEP20",
 				},
@@ -61,15 +110,15 @@ func Test_AddNewAssets(t *testing.T) {
 			Assets: []models.Asset{
 				{
 					Asset:    "c714_c",
-					Decimals: 18,
-					Name:     "C",
+					Decimals: 17,
+					Name:     "CCC",
 					Symbol:   "FFF",
 					Type:     "ERC20",
 				},
 				{
 					Asset:    "c714_d",
 					Decimals: 18,
-					Name:     "D",
+					Name:     "DDDD",
 					Symbol:   "RRR",
 					Type:     "TRC20",
 				},
@@ -79,29 +128,29 @@ func Test_AddNewAssets(t *testing.T) {
 			WantedAssets: []models.Asset{
 				{
 					Asset:    "c714_a",
-					Decimals: 18,
+					Decimals: 15,
 					Name:     "A",
 					Symbol:   "ABC",
 					Type:     "BEP20",
 				},
 				{
 					Asset:    "c714_b",
-					Decimals: 18,
-					Name:     "B",
+					Decimals: 16,
+					Name:     "BB",
 					Symbol:   "BCD",
 					Type:     "BEP20",
 				},
 				{
 					Asset:    "c714_c",
-					Decimals: 18,
-					Name:     "C",
+					Decimals: 17,
+					Name:     "CCC",
 					Symbol:   "FFF",
 					Type:     "ERC20",
 				},
 				{
 					Asset:    "c714_d",
 					Decimals: 18,
-					Name:     "D",
+					Name:     "DDDD",
 					Symbol:   "RRR",
 					Type:     "TRC20",
 				},
@@ -116,11 +165,14 @@ func Test_AddNewAssets(t *testing.T) {
 			assets, err := database.GetAssetsByIDs(tt.AssetsIDs, context.Background())
 			assert.Nil(t, err)
 			sort.Slice(tt.WantedAssets, func(i, j int) bool {
-				return tt.WantedAssets[i].Asset > tt.WantedAssets[j].Asset
+				return len(tt.WantedAssets[i].Name) > len(tt.WantedAssets[j].Name)
 			})
 			sort.Slice(assets, func(i, j int) bool {
-				return assets[i].Asset > assets[j].Asset
+				return len(assets[i].Name) > len(assets[j].Name)
 			})
+			logger.Info(tt.WantedAssets)
+			logger.Info("----------------------")
+			logger.Info(assets)
 			for i, a := range assets {
 				assert.Equal(t, tt.WantedAssets[i].Asset, a.Asset)
 				assert.Equal(t, tt.WantedAssets[i].Name, a.Name)
diff --git a/tests/integration/setup/postgres.go b/tests/integration/setup/postgres.go
index ac6d964..b10d72f 100644
--- a/tests/integration/setup/postgres.go
+++ b/tests/integration/setup/postgres.go
@@ -12,7 +12,7 @@ import (
 const (
 	pgUser = "user"
 	pgPass = "pass"
-	pgDB   = "my_db"
+	pgDB   = "blockatlas"
 )
 
 var (