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 }