github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/database/utxo_view.go (about)

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