OSDN Git Service

ac8ebd5533a84f54159455b4dcc8f90779c2bd91
[bytom/bytom.git] / blockchain / txdb / mainchain.go
1 package txdb
2
3 import (
4         "bytes"
5
6         "github.com/golang/protobuf/proto"
7         dbm "github.com/tendermint/tmlibs/db"
8
9         "github.com/bytom/blockchain/txdb/internal/storage"
10         "github.com/bytom/errors"
11         "github.com/bytom/protocol/bc"
12 )
13
14 const mainchainPreFix = "MC:"
15
16 func calcMainchainKey(hash *bc.Hash) []byte {
17         return []byte(mainchainPreFix + hash.String())
18 }
19
20 // DecodeMainchain decodes a Mainchain from bytes
21 func DecodeMainchain(data []byte) (map[uint64]*bc.Hash, error) {
22         var mainchainList storage.Mainchain
23         if err := proto.Unmarshal(data, &mainchainList); err != nil {
24                 return nil, errors.Wrap(err, "unmarshaling Mainchain proto")
25         }
26
27         mainchain := make(map[uint64]*bc.Hash)
28         for i, rawHash := range mainchainList.Hashs {
29                 var b32 [32]byte
30                 copy(b32[:], rawHash.Key)
31                 hash := bc.NewHash(b32)
32                 mainchain[uint64(i+1)] = &hash
33         }
34
35         return mainchain, nil
36 }
37
38 func saveMainchain(db dbm.DB, mainchain map[uint64]*bc.Hash, hash *bc.Hash) error {
39         var mainchainList storage.Mainchain
40         for i := 1; i <= len(mainchain); i++ {
41                 rawHash := &storage.Mainchain_Hash{Key: mainchain[uint64(i)].Bytes()}
42                 mainchainList.Hashs = append(mainchainList.Hashs, rawHash)
43         }
44
45         b, err := proto.Marshal(&mainchainList)
46         if err != nil {
47                 return errors.Wrap(err, "marshaling Mainchain")
48         }
49
50         db.Set(calcMainchainKey(hash), b)
51         db.SetSync(nil, nil)
52         return nil
53 }
54
55 func getMainchain(db dbm.DB, hash *bc.Hash) (map[uint64]*bc.Hash, error) {
56         data := db.Get(calcMainchainKey(hash))
57         if data == nil {
58                 return nil, errors.New("no this Mainchain")
59         }
60
61         mainchain, err := DecodeMainchain(data)
62         if err != nil {
63                 return nil, errors.Wrap(err, "decoding Mainchain")
64         }
65         return mainchain, nil
66 }
67
68 func cleanMainchainDB(db dbm.DB, hash *bc.Hash) {
69         keepKey := calcMainchainKey(hash)
70
71         iter := db.IteratorPrefix([]byte(mainchainPreFix))
72         defer iter.Release()
73         for iter.Next() {
74                 if key := iter.Key(); !bytes.Equal(key, keepKey) {
75                         db.Delete(key)
76                 }
77         }
78         db.SetSync(nil, nil)
79 }