OSDN Git Service

add dpos consensus
[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                         var utxo storage.UtxoEntry
30                         if err := proto.Unmarshal(data, &utxo); err != nil {
31                                 return errors.Wrap(err, "unmarshaling utxo entry")
32                         }
33
34                         view.Entries[prevout] = &utxo
35                 }
36         }
37
38         return nil
39 }
40
41 func getUtxo(db dbm.DB, hash *bc.Hash) (*storage.UtxoEntry, error) {
42         var utxo storage.UtxoEntry
43         data := db.Get(calcUtxoKey(hash))
44         if data == nil {
45                 return nil, errors.New("can't find utxo in db")
46         }
47         if err := proto.Unmarshal(data, &utxo); err != nil {
48                 return nil, errors.Wrap(err, "unmarshaling utxo entry")
49         }
50         return &utxo, nil
51 }
52
53 func saveUtxoView(batch dbm.Batch, view *state.UtxoViewpoint) error {
54         for key, entry := range view.Entries {
55                 if entry.Spent && !entry.IsCoinBase && !entry.IsCliam {
56                         batch.Delete(calcUtxoKey(&key))
57                         continue
58                 }
59
60                 b, err := proto.Marshal(entry)
61                 if err != nil {
62                         return errors.Wrap(err, "marshaling utxo entry")
63                 }
64                 batch.Set(calcUtxoKey(&key), b)
65         }
66         return nil
67 }
68
69 func SaveUtxoView(batch dbm.Batch, view *state.UtxoViewpoint) error {
70         return saveUtxoView(batch, view)
71 }