-
Notifications
You must be signed in to change notification settings - Fork 0
/
block.go
120 lines (100 loc) · 2.39 KB
/
block.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package flyclientdemo
import (
"errors"
"fmt"
"github.com/zcheng9/FlyclientDemo/common"
"github.com/zcheng9/FlyclientDemo/diskdb"
"github.com/zcheng9/FlyclientDemo/diskdb/memorydb"
"github.com/zcheng9/FlyclientDemo/mmr"
"github.com/zcheng9/FlyclientDemo/rlp"
"math/big"
)
var RightDif = big.NewInt(100000)
func getDB() diskdb.Database {
return memorydb.New()
}
type Block struct {
Nonce uint64 `json:"nonce"`
Number uint64 `json:"height"`
PreHash common.Hash `json:"parentId"`
Difficulty *big.Int `json:"difficulty"`
MRoot common.Hash `json:"m_root"`
}
func NewBlock(num uint64, nonce uint64, diff *big.Int) *Block {
return &Block{Nonce: nonce,
Number: num,
Difficulty: diff,
}
}
func (b Block) Hash() common.Hash {
return mmr.RlpHash(b)
}
func (b Block) String() string {
return fmt.Sprintf(`Header(%s):
Height: %d
Prehash: %s
Difficulty %s
Mmr: %s
____________________________________________________________
`, b.Hash(), b.Number, b.PreHash, b.Difficulty, b.MRoot)
}
type BlockChain struct {
genesis *Block
blocks []*Block
header *Block
db diskdb.Database
Mmr *mmr.Mmr
}
var genesisBlock = &Block{
Nonce: 1,
Number: 0,
PreHash: common.Hash{},
Difficulty: big.NewInt(0),
MRoot: common.Hash{},
}
func NewBlockChain() (bc *BlockChain) {
bc = &BlockChain{
header: genesisBlock,
genesis: genesisBlock,
blocks: []*Block{genesisBlock},
Mmr: mmr.NewMMR(),
db: getDB(),
}
node := mmr.NewNode(genesisBlock.Hash(), big.NewInt(0))
bc.Mmr.Push(node)
ghash := genesisBlock.Hash().Bytes()
genc, _ := rlp.EncodeToBytes(genesisBlock)
bc.db.Put(ghash, genc)
return
}
func (bc *BlockChain) InsertBlock(b *Block) error {
if b.Number == 0 {
return errors.New("can not add genesis block")
}
b.PreHash = bc.header.Hash()
b.MRoot = bc.Mmr.GetRoot()
node := mmr.NewNode(b.Hash(), b.Difficulty)
bc.Mmr.Push(node)
//bc.header = bc.blocks[len(bc.blocks)]
enc, err := rlp.EncodeToBytes(b)
if err != nil {
return err
}
bc.db.Put(b.Hash().Bytes(), enc)
bc.blocks = append(bc.blocks, b)
bc.header = b
return nil
}
func (bc *BlockChain) Len() int {
return len(bc.blocks)
}
func (bc *BlockChain) GetTailMmr() *mmr.Mmr {
m := bc.Mmr.Copy()
m.Pop()
return m
}
func (bc *BlockChain) GetProof() *mmr.ProofInfo {
m := bc.GetTailMmr()
res, _, _ := m.CreateNewProof(RightDif)
return res
}