OSDN Git Service

Merge pull request #981 from Bytom/edit_addressbook
[bytom/bytom.git] / wallet / indexer.go
old mode 100755 (executable)
new mode 100644 (file)
index a983f78..72ce8af
@@ -156,10 +156,9 @@ func saveExternalAssetDefinition(b *types.Block, walletDB db.DB) {
                        if ii, ok := orig.TypedInput.(*types.IssuanceInput); ok {
                                if isValidJSON(ii.AssetDefinition) {
                                        assetID := ii.AssetID()
-                                       if assetExist := walletDB.Get(asset.CalcExtAssetKey(&assetID)); assetExist != nil {
-                                               continue
+                                       if assetExist := walletDB.Get(asset.ExtAssetKey(&assetID)); assetExist == nil {
+                                               storeBatch.Set(asset.ExtAssetKey(&assetID), ii.AssetDefinition)
                                        }
-                                       storeBatch.Set(asset.CalcExtAssetKey(&assetID), ii.AssetDefinition)
                                }
                        }
                }
@@ -189,7 +188,6 @@ type TxSummary struct {
 func (w *Wallet) indexTransactions(batch db.Batch, b *types.Block, txStatus *bc.TransactionStatus) error {
        annotatedTxs := w.filterAccountTxs(b, txStatus)
        saveExternalAssetDefinition(b, w.DB)
-       annotateTxsAsset(w, annotatedTxs)
        annotateTxsAccount(annotatedTxs, w.DB)
 
        for _, tx := range annotatedTxs {
@@ -211,24 +209,25 @@ func (w *Wallet) buildAccountUTXOs(batch db.Batch, b *types.Block, txStatus *bc.
        prevoutDBKeys(batch, b, txStatus)
 
        // handle new UTXOs
-       outs := make([]*rawOutput, 0, len(b.Transactions))
+       var outs []*rawOutput
        for txIndex, tx := range b.Transactions {
-               for j, out := range tx.Outputs {
-                       resOutID := tx.ResultIds[j]
+               for i, out := range tx.Outputs {
+                       resOutID := tx.ResultIds[i]
                        resOut, ok := tx.Entries[*resOutID].(*bc.Output)
                        if !ok {
                                continue
                        }
-                       statusFail, _ := txStatus.GetStatus(txIndex)
-                       if statusFail && *resOut.Source.Value.AssetId != *consensus.BTMAssetID {
+
+                       if statusFail, _ := txStatus.GetStatus(txIndex); statusFail && *resOut.Source.Value.AssetId != *consensus.BTMAssetID {
                                continue
                        }
+
                        out := &rawOutput{
-                               OutputID:       *tx.OutputID(j),
+                               OutputID:       *tx.OutputID(i),
                                AssetAmount:    out.AssetAmount,
                                ControlProgram: out.ControlProgram,
                                txHash:         tx.ID,
-                               outputIndex:    uint32(j),
+                               outputIndex:    uint32(i),
                                sourceID:       *resOut.Source.Ref,
                                sourcePos:      resOut.Source.Position,
                        }
@@ -244,7 +243,6 @@ func (w *Wallet) buildAccountUTXOs(batch db.Batch, b *types.Block, txStatus *bc.
 
        if err := upsertConfirmedAccountOutputs(accOuts, batch); err != nil {
                log.WithField("err", err).Error("building new account outputs")
-               return
        }
 }
 
@@ -309,7 +307,7 @@ func loadAccountInfo(outs []*rawOutput, w *Wallet) []*accountOutput {
                }
 
                sha3pool.Sum256(hash[:], []byte(s))
-               bytes := w.DB.Get(account.CPKey(hash))
+               bytes := w.DB.Get(account.ContractKey(hash))
                if bytes == nil {
                        continue
                }
@@ -357,6 +355,7 @@ func upsertConfirmedAccountOutputs(outs []*accountOutput, batch db.Batch) error
                        AccountID:           out.AccountID,
                        Address:             out.Address,
                        ValidHeight:         out.ValidHeight,
+                       Change:              out.change,
                }
 
                data, err := json.Marshal(u)
@@ -379,32 +378,27 @@ func upsertConfirmedAccountOutputs(outs []*accountOutput, batch db.Batch) error
 // filterAccountTxs related and build the fully annotated transactions.
 func (w *Wallet) filterAccountTxs(b *types.Block, txStatus *bc.TransactionStatus) []*query.AnnotatedTx {
        annotatedTxs := make([]*query.AnnotatedTx, 0, len(b.Transactions))
+
+transactionLoop:
        for pos, tx := range b.Transactions {
                statusFail, _ := txStatus.GetStatus(pos)
-               local := false
                for _, v := range tx.Outputs {
                        var hash [32]byte
-
                        sha3pool.Sum256(hash[:], v.ControlProgram)
-                       if bytes := w.DB.Get(account.CPKey(hash)); bytes != nil {
-                               annotatedTxs = append(annotatedTxs, buildAnnotatedTransaction(tx, b, statusFail, pos))
-                               local = true
-                               break
+                       if bytes := w.DB.Get(account.ContractKey(hash)); bytes != nil {
+                               annotatedTxs = append(annotatedTxs, w.buildAnnotatedTransaction(tx, b, statusFail, pos))
+                               continue transactionLoop
                        }
                }
 
-               if local == true {
-                       continue
-               }
-
                for _, v := range tx.Inputs {
                        outid, err := v.SpentOutputID()
                        if err != nil {
                                continue
                        }
                        if bytes := w.DB.Get(account.StandardUTXOKey(outid)); bytes != nil {
-                               annotatedTxs = append(annotatedTxs, buildAnnotatedTransaction(tx, b, statusFail, pos))
-                               break
+                               annotatedTxs = append(annotatedTxs, w.buildAnnotatedTransaction(tx, b, statusFail, pos))
+                               continue transactionLoop
                        }
                }
        }
@@ -441,14 +435,15 @@ func (w *Wallet) GetTransactionsByTxID(txID string) ([]*query.AnnotatedTx, error
                formatKey = string(rawFormatKey)
        }
 
-       txIter := w.DB.IteratorPrefix([]byte(TxPrefix + formatKey))
+       txIter := w.DB.IteratorPrefix(calcAnnotatedKey(formatKey))
        defer txIter.Release()
        for txIter.Next() {
                annotatedTx := &query.AnnotatedTx{}
                if err := json.Unmarshal(txIter.Value(), annotatedTx); err != nil {
                        return nil, err
                }
-               annotatedTxs = append(annotatedTxs, annotatedTx)
+               annotateTxsAsset(w, []*query.AnnotatedTx{annotatedTx})
+               annotatedTxs = append([]*query.AnnotatedTx{annotatedTx}, annotatedTxs...)
        }
 
        return annotatedTxs, nil
@@ -519,6 +514,7 @@ func (w *Wallet) GetTransactionsByAccountID(accountID string) ([]*query.Annotate
                }
 
                if findTransactionsByAccount(annotatedTx, accountID) {
+                       annotateTxsAsset(w, []*query.AnnotatedTx{annotatedTx})
                        annotatedTxs = append(annotatedTxs, annotatedTx)
                }
        }
@@ -527,46 +523,42 @@ func (w *Wallet) GetTransactionsByAccountID(accountID string) ([]*query.Annotate
 }
 
 // GetAccountUTXOs return all account unspent outputs
-func (w *Wallet) GetAccountUTXOs(id string) ([]account.UTXO, error) {
-       accountUTXO := account.UTXO{}
-       accountUTXOs := []account.UTXO{}
+func (w *Wallet) GetAccountUTXOs(id string) []account.UTXO {
+       var accountUTXOs []account.UTXO
 
        accountUTXOIter := w.DB.IteratorPrefix([]byte(account.UTXOPreFix + id))
        defer accountUTXOIter.Release()
        for accountUTXOIter.Next() {
+               accountUTXO := account.UTXO{}
                if err := json.Unmarshal(accountUTXOIter.Value(), &accountUTXO); err != nil {
                        hashKey := accountUTXOIter.Key()[len(account.UTXOPreFix):]
                        log.WithField("UTXO hash", string(hashKey)).Warn("get account UTXO")
-                       continue
+               } else {
+                       accountUTXOs = append(accountUTXOs, accountUTXO)
                }
-
-               accountUTXOs = append(accountUTXOs, accountUTXO)
        }
 
-       return accountUTXOs, nil
+       return accountUTXOs
 }
 
-func (w *Wallet) GetAccountBalances(id string) ([]accountBalance, error) {
-       accountUTXOs, err := w.GetAccountUTXOs("")
-       if err != nil {
-               return nil, err
-       }
-
-       return w.indexBalances(accountUTXOs), nil
+// GetAccountBalances return all account balances
+func (w *Wallet) GetAccountBalances(id string) ([]AccountBalance, error) {
+       return w.indexBalances(w.GetAccountUTXOs(""))
 }
 
-type accountBalance struct {
-       AccountID  string `json:"account_id"`
-       Alias      string `json:"account_alias"`
-       AssetAlias string `json:"asset_alias"`
-       AssetID    string `json:"asset_id"`
-       Amount     uint64 `json:"amount"`
+// AccountBalance account balance
+type AccountBalance struct {
+       AccountID       string                 `json:"account_id"`
+       Alias           string                 `json:"account_alias"`
+       AssetAlias      string                 `json:"asset_alias"`
+       AssetID         string                 `json:"asset_id"`
+       Amount          uint64                 `json:"amount"`
+       AssetDefinition map[string]interface{} `json:"asset_definition"`
 }
 
-func (w *Wallet) indexBalances(accountUTXOs []account.UTXO) []accountBalance {
+func (w *Wallet) indexBalances(accountUTXOs []account.UTXO) ([]AccountBalance, error) {
        accBalance := make(map[string]map[string]uint64)
-       balances := make([]accountBalance, 0)
-       tmpBalance := accountBalance{}
+       balances := make([]AccountBalance, 0)
 
        for _, accountUTXO := range accountUTXOs {
                assetID := accountUTXO.AssetID.String()
@@ -596,15 +588,22 @@ func (w *Wallet) indexBalances(accountUTXOs []account.UTXO) []accountBalance {
 
                for _, assetID := range sortedAsset {
                        alias := w.AccountMgr.GetAliasByID(id)
-                       assetAlias := w.AssetReg.GetAliasByID(assetID)
-                       tmpBalance.Alias = alias
-                       tmpBalance.AccountID = id
-                       tmpBalance.AssetID = assetID
-                       tmpBalance.AssetAlias = assetAlias
-                       tmpBalance.Amount = accBalance[id][assetID]
-                       balances = append(balances, tmpBalance)
+                       targetAsset, err := w.AssetReg.GetAsset(assetID)
+                       if err != nil {
+                               return nil, err
+                       }
+
+                       assetAlias := *targetAsset.Alias
+                       balances = append(balances, AccountBalance{
+                               Alias: alias,
+                               AccountID: id,
+                               AssetID: assetID,
+                               AssetAlias: assetAlias,
+                               Amount: accBalance[id][assetID],
+                               AssetDefinition: targetAsset.DefinitionMap,
+                       })
                }
        }
 
-       return balances
+       return balances, nil
 }