github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/database/utxo_view.go (about)

     1  package database
     2  
     3  import (
     4  	"github.com/bytom/bytom/database/storage"
     5  	"github.com/bytom/bytom/errors"
     6  	"github.com/bytom/bytom/protocol/bc"
     7  	"github.com/bytom/bytom/protocol/state"
     8  	"github.com/golang/protobuf/proto"
     9  	dbm "github.com/bytom/bytom/database/leveldb"
    10  )
    11  
    12  const UtxoPreFix = "UT:"
    13  
    14  func CalcUtxoKey(hash *bc.Hash) []byte {
    15  	return []byte(UtxoPreFix + hash.String())
    16  }
    17  
    18  func getTransactionsUtxo(db dbm.DB, view *state.UtxoViewpoint, txs []*bc.Tx) error {
    19  	for _, tx := range txs {
    20  		for _, prevout := range tx.SpentOutputIDs {
    21  			if view.HasUtxo(&prevout) {
    22  				continue
    23  			}
    24  
    25  			data := db.Get(CalcUtxoKey(&prevout))
    26  			if data == nil {
    27  				continue
    28  			}
    29  
    30  			var utxo storage.UtxoEntry
    31  			if err := proto.Unmarshal(data, &utxo); err != nil {
    32  				return errors.Wrap(err, "unmarshaling utxo entry")
    33  			}
    34  
    35  			view.Entries[prevout] = &utxo
    36  		}
    37  	}
    38  
    39  	return nil
    40  }
    41  
    42  func getUtxo(db dbm.DB, hash *bc.Hash) (*storage.UtxoEntry, error) {
    43  	var utxo storage.UtxoEntry
    44  	data := db.Get(CalcUtxoKey(hash))
    45  	if data == nil {
    46  		return nil, errors.New("can't find utxo in db")
    47  	}
    48  	if err := proto.Unmarshal(data, &utxo); err != nil {
    49  		return nil, errors.Wrap(err, "unmarshaling utxo entry")
    50  	}
    51  	return &utxo, nil
    52  }
    53  
    54  func saveUtxoView(batch dbm.Batch, view *state.UtxoViewpoint) error {
    55  	for key, entry := range view.Entries {
    56  		if entry.Spent && !entry.IsCoinBase {
    57  			batch.Delete(CalcUtxoKey(&key))
    58  			continue
    59  		}
    60  
    61  		b, err := proto.Marshal(entry)
    62  		if err != nil {
    63  			return errors.Wrap(err, "marshaling utxo entry")
    64  		}
    65  		batch.Set(CalcUtxoKey(&key), b)
    66  	}
    67  	return nil
    68  }
    69  
    70  func SaveUtxoView(batch dbm.Batch, view *state.UtxoViewpoint) error {
    71  	return saveUtxoView(batch, view)
    72  }