6 "github.com/golang/protobuf/proto"
7 dbm "github.com/tendermint/tmlibs/db"
9 "github.com/bytom/blockchain/txdb/storage"
10 "github.com/bytom/errors"
11 "github.com/bytom/protocol/bc"
14 const mainchainPreFix = "MC:"
16 func calcMainchainKey(hash *bc.Hash) []byte {
17 return []byte(mainchainPreFix + hash.String())
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")
27 mainchain := make(map[uint64]*bc.Hash)
28 for i, rawHash := range mainchainList.Hashs {
30 copy(b32[:], rawHash.Key)
31 hash := bc.NewHash(b32)
32 mainchain[uint64(i+1)] = &hash
38 func saveMainchain(batch dbm.Batch, 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)
45 b, err := proto.Marshal(&mainchainList)
47 return errors.Wrap(err, "marshaling Mainchain")
50 batch.Set(calcMainchainKey(hash), b)
54 func getMainchain(db dbm.DB, hash *bc.Hash) (map[uint64]*bc.Hash, error) {
55 data := db.Get(calcMainchainKey(hash))
57 return nil, errors.New("no this Mainchain")
60 mainchain, err := DecodeMainchain(data)
62 return nil, errors.Wrap(err, "decoding Mainchain")
67 func cleanMainchainDB(db dbm.DB, hash *bc.Hash) {
68 keepKey := calcMainchainKey(hash)
70 iter := db.IteratorPrefix([]byte(mainchainPreFix))
73 if key := iter.Key(); !bytes.Equal(key, keepKey) {