OSDN Git Service

f8576dfe2ca07dd5e27e8111ab66e3aa35e0c7dd
[bytom/vapor.git] / database / utxo_view.go
1 package database
2
3 import (
4         "github.com/golang/protobuf/proto"
5         dbm "github.com/vapor/database/leveldb"
6         "github.com/vapor/database/storage"
7         "github.com/vapor/errors"
8         "github.com/vapor/protocol/bc"
9         "github.com/vapor/protocol/state"
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 }