OSDN Git Service

modify import path (#1805)
[bytom/bytom.git] / wallet / utxo.go
index 338fddc..0dc78d5 100644 (file)
@@ -4,47 +4,55 @@ import (
        "encoding/json"
 
        log "github.com/sirupsen/logrus"
-       "github.com/tendermint/tmlibs/db"
-
-       "github.com/bytom/account"
-       "github.com/bytom/consensus"
-       "github.com/bytom/consensus/segwit"
-       "github.com/bytom/crypto/sha3pool"
-       "github.com/bytom/errors"
-       "github.com/bytom/protocol/bc"
-       "github.com/bytom/protocol/bc/types"
+
+       "github.com/bytom/bytom/account"
+       "github.com/bytom/bytom/consensus"
+       "github.com/bytom/bytom/consensus/segwit"
+       "github.com/bytom/bytom/crypto/sha3pool"
+       "github.com/bytom/bytom/errors"
+       "github.com/bytom/bytom/protocol/bc"
+       "github.com/bytom/bytom/protocol/bc/types"
+       dbm "github.com/bytom/bytom/database/leveldb"
 )
 
 // GetAccountUtxos return all account unspent outputs
-func (w *Wallet) GetAccountUtxos(id string, isSmartContract bool) []*account.UTXO {
+func (w *Wallet) GetAccountUtxos(accountID string, id string, unconfirmed, isSmartContract bool) []*account.UTXO {
        prefix := account.UTXOPreFix
        if isSmartContract {
                prefix = account.SUTXOPrefix
        }
+
        accountUtxos := []*account.UTXO{}
+       if unconfirmed {
+               accountUtxos = w.AccountMgr.ListUnconfirmedUtxo(accountID, isSmartContract)
+       }
+
        accountUtxoIter := w.DB.IteratorPrefix([]byte(prefix + id))
        defer accountUtxoIter.Release()
 
        for accountUtxoIter.Next() {
                accountUtxo := &account.UTXO{}
                if err := json.Unmarshal(accountUtxoIter.Value(), accountUtxo); err != nil {
-                       log.WithField("err", err).Warn("GetAccountUtxos fail on unmarshal utxo")
+                       log.WithFields(log.Fields{"module": logModule, "err": err}).Warn("GetAccountUtxos fail on unmarshal utxo")
                        continue
                }
 
-               accountUtxos = append(accountUtxos, accountUtxo)
+               if accountID == accountUtxo.AccountID || accountID == "" {
+                       accountUtxos = append(accountUtxos, accountUtxo)
+               }
        }
        return accountUtxos
 }
 
-func (w *Wallet) attachUtxos(batch db.Batch, b *types.Block, txStatus *bc.TransactionStatus) {
+func (w *Wallet) attachUtxos(batch dbm.Batch, b *types.Block, txStatus *bc.TransactionStatus) {
        for txIndex, tx := range b.Transactions {
                statusFail, err := txStatus.GetStatus(txIndex)
                if err != nil {
-                       log.WithField("err", err).Error("attachUtxos fail on get tx status")
+                       log.WithFields(log.Fields{"module": logModule, "err": err}).Error("attachUtxos fail on get tx status")
                        continue
                }
 
+               //hand update the transaction input utxos
                inputUtxos := txInToUtxos(tx, statusFail)
                for _, inputUtxo := range inputUtxos {
                        if segwit.IsP2WScript(inputUtxo.ControlProgram) {
@@ -53,50 +61,23 @@ func (w *Wallet) attachUtxos(batch db.Batch, b *types.Block, txStatus *bc.Transa
                                batch.Delete(account.ContractUTXOKey(inputUtxo.OutputID))
                        }
                }
-       }
-
-       utxos := []*account.UTXO{}
-       for txIndex, tx := range b.Transactions {
-               statusFail, err := txStatus.GetStatus(txIndex)
-               if err != nil {
-                       log.WithField("err", err).Error("attachUtxos fail on get txStatus")
-                       continue
-               }
 
+               //hand update the transaction output utxos
                validHeight := uint64(0)
                if txIndex == 0 {
                        validHeight = b.Height + consensus.CoinbasePendingBlockNumber
                }
                outputUtxos := txOutToUtxos(tx, statusFail, validHeight)
-               utxos = append(utxos, outputUtxos...)
-       }
-
-       utxos = w.filterAccountUtxo(utxos)
-       if err := batchSaveUtxos(utxos, batch); err != nil {
-               log.WithField("err", err).Error("attachUtxos fail on batchSaveUtxos")
-       }
-}
-
-func (w *Wallet) detachUtxos(batch db.Batch, b *types.Block, txStatus *bc.TransactionStatus) {
-       utxos := []*account.UTXO{}
-       for txIndex, tx := range b.Transactions {
-               statusFail, err := txStatus.GetStatus(txIndex)
-               if err != nil {
-                       log.WithField("err", err).Error("detachUtxos fail on get tx status")
-                       continue
+               utxos := w.filterAccountUtxo(outputUtxos)
+               if err := batchSaveUtxos(utxos, batch); err != nil {
+                       log.WithFields(log.Fields{"module": logModule, "err": err}).Error("attachUtxos fail on batchSaveUtxos")
                }
-
-               inputUtxos := txInToUtxos(tx, statusFail)
-               utxos = append(utxos, inputUtxos...)
-       }
-
-       utxos = w.filterAccountUtxo(utxos)
-       if err := batchSaveUtxos(utxos, batch); err != nil {
-               log.WithField("err", err).Error("detachUtxos fail on batchSaveUtxos")
-               return
        }
+}
 
-       for _, tx := range b.Transactions {
+func (w *Wallet) detachUtxos(batch dbm.Batch, b *types.Block, txStatus *bc.TransactionStatus) {
+       for txIndex := len(b.Transactions) - 1; txIndex >= 0; txIndex-- {
+               tx := b.Transactions[txIndex]
                for j := range tx.Outputs {
                        resOut, err := tx.Output(*tx.ResultIds[j])
                        if err != nil {
@@ -109,6 +90,19 @@ func (w *Wallet) detachUtxos(batch db.Batch, b *types.Block, txStatus *bc.Transa
                                batch.Delete(account.ContractUTXOKey(*tx.ResultIds[j]))
                        }
                }
+
+               statusFail, err := txStatus.GetStatus(txIndex)
+               if err != nil {
+                       log.WithFields(log.Fields{"module": logModule, "err": err}).Error("detachUtxos fail on get tx status")
+                       continue
+               }
+
+               inputUtxos := txInToUtxos(tx, statusFail)
+               utxos := w.filterAccountUtxo(inputUtxos)
+               if err := batchSaveUtxos(utxos, batch); err != nil {
+                       log.WithFields(log.Fields{"module": logModule, "err": err}).Error("detachUtxos fail on batchSaveUtxos")
+                       return
+               }
        }
 }
 
@@ -137,7 +131,7 @@ func (w *Wallet) filterAccountUtxo(utxos []*account.UTXO) []*account.UTXO {
 
                cp := &account.CtrlProgram{}
                if err := json.Unmarshal(data, cp); err != nil {
-                       log.WithField("err", err).Error("filterAccountUtxo fail on unmarshal control program")
+                       log.WithFields(log.Fields{"module": logModule, "err": err}).Error("filterAccountUtxo fail on unmarshal control program")
                        continue
                }
 
@@ -152,7 +146,7 @@ func (w *Wallet) filterAccountUtxo(utxos []*account.UTXO) []*account.UTXO {
        return result
 }
 
-func batchSaveUtxos(utxos []*account.UTXO, batch db.Batch) error {
+func batchSaveUtxos(utxos []*account.UTXO, batch dbm.Batch) error {
        for _, utxo := range utxos {
                data, err := json.Marshal(utxo)
                if err != nil {
@@ -178,7 +172,7 @@ func txInToUtxos(tx *types.Tx, statusFail bool) []*account.UTXO {
 
                resOut, err := tx.Output(*sp.SpentOutputId)
                if err != nil {
-                       log.WithField("err", err).Error("txInToUtxos fail on get resOut")
+                       log.WithFields(log.Fields{"module": logModule, "err": err}).Error("txInToUtxos fail on get resOut")
                        continue
                }