diff --git a/api/service/explorer/storage.go b/api/service/explorer/storage.go index d10a0865d..232801eb4 100644 --- a/api/service/explorer/storage.go +++ b/api/service/explorer/storage.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" "github.com/harmony-one/harmony/core/types" + "github.com/harmony-one/harmony/internal/utils" ) // Constants for storage. @@ -68,11 +69,11 @@ func (storage *Storage) Init(ip, port string, remove bool) { if remove { var err = os.RemoveAll(dbFileName) if err != nil { - Log.Error(err.Error()) + utils.GetLogInstance().Error(err.Error()) } } if storage.db, err = ethdb.NewLDBDatabase(dbFileName, 0, 0); err != nil { - Log.Error(err.Error()) + utils.GetLogInstance().Error(err.Error()) } } @@ -83,21 +84,58 @@ func (storage *Storage) GetDB() *ethdb.LDBDatabase { // Dump extracts information from block and index them into lvdb for explorer. func (storage *Storage) Dump(block *types.Block, height uint32) { - Log.Info("Dumping block ", "block height", height) + utils.GetLogInstance().Info("Dumping block ", "block height", height) if block == nil { return } + + batch := storage.db.NewBatch() // Update block height. - storage.db.Put([]byte(BlockHeightKey), []byte(strconv.Itoa(int(height)))) + batch.Put([]byte(BlockHeightKey), []byte(strconv.Itoa(int(height)))) // Store block. blockData, err := rlp.EncodeToBytes(block) if err == nil { - storage.db.Put([]byte(GetBlockKey(int(height))), blockData) + batch.Put([]byte(GetBlockKey(int(height))), blockData) } else { - Log.Debug("Failed to serialize block ", "error", err) + utils.GetLogInstance().Debug("Failed to serialize block ", "error", err) } + // Debug code: will clean up after relaunching. + // keys := map[string]int{} + // for _, tx := range block.Transactions() { + // explorerTransaction := GetTransaction(tx, block) + // if explorerTransaction == nil { + // continue + // } + // utils.GetLogInstance().Info("minh tx info before adding", "from", explorerTransaction.From, "to", explorerTransaction.To) + // key := GetAddressKey(explorerTransaction.To) + // var address Address + // if data, err := storage.db.Get([]byte(key)); err == nil { + // err = rlp.DecodeBytes(data, &address) + // if err == nil { + // utils.GetLogInstance().Info("existed for", "key", key, "address", address) + // keys[key] = len(address.TXs) + // } else { + // utils.GetLogInstance().Error("error when decode bytes for address", "address", address, "err", err) + // } + // } else { + // utils.GetLogInstance().Info("not existed for", "key", key) + // } + // key = GetAddressKey(explorerTransaction.From) + // if data, err := storage.db.Get([]byte(key)); err == nil { + // err = rlp.DecodeBytes(data, &address) + // if err == nil { + // utils.GetLogInstance().Info("existed for", "key", key, "address", address) + // keys[key] = len(address.TXs) + // } else { + // utils.GetLogInstance().Error("error when decode bytes for address", "address", address, "err", err) + // } + // } else { + // utils.GetLogInstance().Info("not existed for", "key", key) + // } + // } + // Store txs for _, tx := range block.Transactions() { if tx.To() == nil { @@ -105,45 +143,90 @@ func (storage *Storage) Dump(block *types.Block, height uint32) { } explorerTransaction := GetTransaction(tx, block) - storage.UpdateTXStorage(explorerTransaction, tx) - storage.UpdateAddress(explorerTransaction, tx) + storage.UpdateTXStorage(batch, explorerTransaction, tx) + storage.UpdateAddress(batch, explorerTransaction, tx) } + batch.Write() + + // Debug code: will clean up after relaunching. + // utils.GetLogInstance().Info("minh test", "inserted", []byte(strconv.Itoa(int(height)))) + // res, _ := storage.db.Get([]byte(BlockHeightKey)) + // utils.GetLogInstance().Info("minh test", "after inserted", res) + // for _, tx := range block.Transactions() { + // explorerTransaction := GetTransaction(tx, block) + // if explorerTransaction == nil { + // continue + // } + // utils.GetLogInstance().Info("****minh tx info after adding***", "from", explorerTransaction.From, "to", explorerTransaction.To) + + // key := GetAddressKey(explorerTransaction.To) + // var address Address + // if data, err := storage.db.Get([]byte(key)); err == nil { + // err = rlp.DecodeBytes(data, &address) + // if err == nil { + // utils.GetLogInstance().Info("existed for", "key", key, "address", address) + // utils.GetLogInstance().Info("existed for", "key", key, "address", address, "before", keys[key], "after", len(address.TXs)) + // } else { + // utils.GetLogInstance().Error("error when decode bytes for address", "address", address, "err", err) + // } + // } else { + // utils.GetLogInstance().Info("not existed for", "key", key) + // } + + // key = GetAddressKey(explorerTransaction.From) + // if data, err := storage.db.Get([]byte(key)); err == nil { + // err = rlp.DecodeBytes(data, &address) + // if err == nil { + // utils.GetLogInstance().Info("existed for", "key", key, "address", address) + // utils.GetLogInstance().Info("existed for", "key", key, "address", address, "before", keys[key], "after", len(address.TXs)) + // } else { + // utils.GetLogInstance().Error("error when decode bytes for address", "address", address, "err", err) + // } + // } else { + // utils.GetLogInstance().Info("not existed for", "key", key) + // } + // } } // UpdateTXStorage ... -func (storage *Storage) UpdateTXStorage(explorerTransaction *Transaction, tx *types.Transaction) { +func (storage *Storage) UpdateTXStorage(batch ethdb.Batch, explorerTransaction *Transaction, tx *types.Transaction) { if data, err := rlp.EncodeToBytes(explorerTransaction); err == nil { key := GetTXKey(tx.Hash().Hex()) - storage.db.Put([]byte(key), data) + batch.Put([]byte(key), data) } else { - Log.Error("EncodeRLP transaction error") + utils.GetLogInstance().Error("EncodeRLP transaction error") } } // UpdateAddress ... -func (storage *Storage) UpdateAddress(explorerTransaction *Transaction, tx *types.Transaction) { - storage.UpdateAddressStorage(explorerTransaction.To, explorerTransaction, tx) - storage.UpdateAddressStorage(explorerTransaction.From, explorerTransaction, tx) +func (storage *Storage) UpdateAddress(batch ethdb.Batch, explorerTransaction *Transaction, tx *types.Transaction) { + storage.UpdateAddressStorage(batch, explorerTransaction.To, explorerTransaction, tx) + storage.UpdateAddressStorage(batch, explorerTransaction.From, explorerTransaction, tx) } // UpdateAddressStorage updates specific adr address. -func (storage *Storage) UpdateAddressStorage(adr string, explorerTransaction *Transaction, tx *types.Transaction) { +func (storage *Storage) UpdateAddressStorage(batch ethdb.Batch, adr string, explorerTransaction *Transaction, tx *types.Transaction) { key := GetAddressKey(adr) var address Address if data, err := storage.db.Get([]byte(key)); err == nil { - err = rlp.DecodeBytes(data, address) + err = rlp.DecodeBytes(data, &address) if err == nil { address.Balance.Add(address.Balance, tx.Value()) + } else { + utils.GetLogInstance().Error("Failed to error", "err", err) } } else { address.Balance = tx.Value() } address.ID = adr + // Debug code. clean it up after relaunching. + // utils.GetLogInstance().Info("minh UpdateAddressStorage:", "address", adr, "length:", len(address.TXs)) address.TXs = append(address.TXs, explorerTransaction) + // utils.GetLogInstance().Info("minh UpdateAddressStorage after append:", "address", adr, "length:", len(address.TXs)) if encoded, err := rlp.EncodeToBytes(address); err == nil { - storage.db.Put([]byte(key), encoded) + batch.Put([]byte(key), encoded) } else { - Log.Error("Can not encode address account.") + utils.GetLogInstance().Error("Can not encode address account.") } }