OSDN Git Service

82e05a4e58823ed6a2a64a2d9b17d31d93af53c7
[bytom/vapor.git] / database / leveldb / utxo_view.go
1 package leveldb
2
3 import (
4         dbm "github.com/tendermint/tmlibs/db"
5
6         "github.com/golang/protobuf/proto"
7         "github.com/vapor/database/storage"
8         "github.com/vapor/errors"
9         "github.com/vapor/protocol/bc"
10         "github.com/vapor/protocol/state"
11 )
12
13 const utxoPreFix = "UT:"
14
15 func calcUtxoKey(hash *bc.Hash) []byte {
16         return []byte(utxoPreFix + hash.String())
17 }
18
19 func getTransactionsUtxo(db dbm.DB, view *state.UtxoViewpoint, txs []*bc.Tx) error {
20         for _, tx := range txs {
21                 for _, prevout := range tx.SpentOutputIDs {
22                         if view.HasUtxo(&prevout) {
23                                 continue
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 && !entry.IsCliam {
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 }