5 "github.com/bytom/bytom/protocol/bc"
6 "github.com/bytom/bytom/protocol/bc/types"
10 ErrFoundHeaderByHash = errors.New("can't find header by hash")
11 ErrFoundHeaderByHeight = errors.New("can't find header by height")
15 bestBlockHeader *types.BlockHeader
16 heightMap map[uint64]*types.Block
17 blockMap map[bc.Hash]*types.Block
19 prevOrphans map[bc.Hash]*types.Block
22 func NewChain() *Chain {
24 heightMap: map[uint64]*types.Block{},
25 blockMap: map[bc.Hash]*types.Block{},
26 prevOrphans: make(map[bc.Hash]*types.Block),
30 func (c *Chain) LastIrreversibleHeader() *types.BlockHeader {
34 func (c *Chain) BestBlockHeader() *types.BlockHeader {
35 return c.bestBlockHeader
38 func (c *Chain) BestBlockHeight() uint64 {
39 return c.bestBlockHeader.Height
42 func (c *Chain) CalcNextSeed(hash *bc.Hash) (*bc.Hash, error) {
43 return &bc.Hash{V0: hash.V1, V1: hash.V2, V2: hash.V3, V3: hash.V0}, nil
46 func (c *Chain) GetBlockByHash(hash *bc.Hash) (*types.Block, error) {
47 block, ok := c.blockMap[*hash]
49 return nil, errors.New("can't find block")
54 func (c *Chain) GetBlockByHeight(height uint64) (*types.Block, error) {
55 block, ok := c.heightMap[height]
57 return nil, errors.New("can't find block")
62 func (c *Chain) GetHeaderByHash(hash *bc.Hash) (*types.BlockHeader, error) {
63 block, ok := c.blockMap[*hash]
65 return nil, errors.New("can't find block")
67 return &block.BlockHeader, nil
70 func (c *Chain) GetHeaderByHeight(height uint64) (*types.BlockHeader, error) {
71 block, ok := c.heightMap[height]
73 return nil, errors.New("can't find block")
75 return &block.BlockHeader, nil
78 func (c *Chain) InMainChain(hash bc.Hash) bool {
79 block, ok := c.blockMap[hash]
83 return c.heightMap[block.Height] == block
86 func (c *Chain) ProcessBlock(block *types.Block) (bool, error) {
87 if c.bestBlockHeader.Hash() == block.PreviousBlockHash {
88 c.heightMap[block.Height] = block
89 c.blockMap[block.Hash()] = block
90 c.bestBlockHeader = &block.BlockHeader
94 if _, ok := c.blockMap[block.PreviousBlockHash]; !ok {
95 c.prevOrphans[block.PreviousBlockHash] = block
99 c.blockMap[block.Hash()] = block
100 for c.prevOrphans[block.Hash()] != nil {
101 block = c.prevOrphans[block.Hash()]
102 c.blockMap[block.Hash()] = block
105 if block.Height < c.bestBlockHeader.Height {
109 c.bestBlockHeader = &block.BlockHeader
110 for !c.InMainChain(block.Hash()) {
111 c.heightMap[block.Height] = block
112 block = c.blockMap[block.PreviousBlockHash]
117 func (c *Chain) SetBestBlockHeader(header *types.BlockHeader) {
118 c.bestBlockHeader = header
121 func (c *Chain) SetBlockByHeight(height uint64, block *types.Block) {
122 c.heightMap[height] = block
123 c.blockMap[block.Hash()] = block
126 func (c *Chain) ValidateTx(*types.Tx) (bool, error) {