7 "github.com/vapor/protocol/bc"
8 "github.com/vapor/protocol/bc/types"
11 type mempool interface {
16 bestBlockHeader *types.BlockHeader
17 heightMap map[uint64]*types.Block
18 blockMap map[bc.Hash]*types.Block
19 prevOrphans map[bc.Hash]*types.Block
23 func NewChain(mempool *Mempool) *Chain {
25 heightMap: map[uint64]*types.Block{},
26 blockMap: map[bc.Hash]*types.Block{},
27 prevOrphans: make(map[bc.Hash]*types.Block),
32 func (c *Chain) BestBlockHeader() *types.BlockHeader {
33 return c.bestBlockHeader
36 func (c *Chain) BestBlockHeight() uint64 {
37 return c.bestBlockHeader.Height
40 func (c *Chain) BestIrreversibleHeader() *types.BlockHeader {
41 return c.bestBlockHeader
44 func (c *Chain) CalcNextSeed(hash *bc.Hash) (*bc.Hash, error) {
45 return &bc.Hash{V0: hash.V1, V1: hash.V2, V2: hash.V3, V3: hash.V0}, nil
48 func (c *Chain) GetBlockByHash(hash *bc.Hash) (*types.Block, error) {
49 block, ok := c.blockMap[*hash]
51 return nil, errors.New("can't find block")
56 func (c *Chain) GetBlockByHeight(height uint64) (*types.Block, error) {
57 block, ok := c.heightMap[height]
59 return nil, errors.New("can't find block")
64 func (c *Chain) GetHeaderByHash(hash *bc.Hash) (*types.BlockHeader, error) {
65 block, ok := c.blockMap[*hash]
67 return nil, errors.New("can't find block")
69 return &block.BlockHeader, nil
72 func (c *Chain) GetHeaderByHeight(height uint64) (*types.BlockHeader, error) {
73 block, ok := c.heightMap[height]
75 return nil, errors.New("can't find block")
77 return &block.BlockHeader, nil
80 func (c *Chain) GetTransactionStatus(hash *bc.Hash) (*bc.TransactionStatus, error) {
81 block, err := c.GetBlockByHash(hash)
83 return nil, errors.New("can't find block by hash")
85 txCount := len(block.Transactions)
86 var statuses []*bc.TxVerifyResult
87 rand.Seed(int64(block.Height))
88 for i := 0; i < txCount; i++ {
89 status := &bc.TxVerifyResult{}
90 if fail := rand.Intn(2); fail == 0 {
91 status.StatusFail = true
93 status.StatusFail = false
95 statuses = append(statuses, status)
97 txStatus := &bc.TransactionStatus{VerifyStatus: statuses}
101 func (c *Chain) InMainChain(hash bc.Hash) bool {
102 block, ok := c.blockMap[hash]
106 return c.heightMap[block.Height] == block
109 func (c *Chain) ProcessBlock(block *types.Block) (bool, error) {
110 if c.bestBlockHeader.Hash() == block.PreviousBlockHash {
111 c.heightMap[block.Height] = block
112 c.blockMap[block.Hash()] = block
113 c.bestBlockHeader = &block.BlockHeader
117 if _, ok := c.blockMap[block.PreviousBlockHash]; !ok {
118 c.prevOrphans[block.PreviousBlockHash] = block
122 c.blockMap[block.Hash()] = block
123 for c.prevOrphans[block.Hash()] != nil {
124 block = c.prevOrphans[block.Hash()]
125 c.blockMap[block.Hash()] = block
128 if block.Height < c.bestBlockHeader.Height {
132 c.bestBlockHeader = &block.BlockHeader
133 for !c.InMainChain(block.Hash()) {
134 c.heightMap[block.Height] = block
135 block = c.blockMap[block.PreviousBlockHash]
140 func (c *Chain) SetBestBlockHeader(header *types.BlockHeader) {
141 c.bestBlockHeader = header
144 func (c *Chain) SetBlockByHeight(height uint64, block *types.Block) {
145 c.heightMap[height] = block
146 c.blockMap[block.Hash()] = block
149 func (c *Chain) ValidateTx(tx *types.Tx) (bool, error) {