"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) {
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 {
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
+ }
}
}
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
}
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 {
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
}