github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/test/mock/chain.go (about)

     1  package mock
     2  
     3  import (
     4  	"errors"
     5  	"math/rand"
     6  
     7  	"github.com/bytom/bytom/protocol/bc"
     8  	"github.com/bytom/bytom/protocol/bc/types"
     9  )
    10  
    11  type Chain struct {
    12  	bestBlockHeader *types.BlockHeader
    13  	heightMap       map[uint64]*types.Block
    14  	blockMap        map[bc.Hash]*types.Block
    15  
    16  	prevOrphans map[bc.Hash]*types.Block
    17  }
    18  
    19  func NewChain() *Chain {
    20  	return &Chain{
    21  		heightMap:   map[uint64]*types.Block{},
    22  		blockMap:    map[bc.Hash]*types.Block{},
    23  		prevOrphans: make(map[bc.Hash]*types.Block),
    24  	}
    25  }
    26  
    27  func (c *Chain) BestBlockHeader() *types.BlockHeader {
    28  	return c.bestBlockHeader
    29  }
    30  
    31  func (c *Chain) BestBlockHeight() uint64 {
    32  	return c.bestBlockHeader.Height
    33  }
    34  
    35  func (c *Chain) CalcNextSeed(hash *bc.Hash) (*bc.Hash, error) {
    36  	return &bc.Hash{V0: hash.V1, V1: hash.V2, V2: hash.V3, V3: hash.V0}, nil
    37  }
    38  
    39  func (c *Chain) GetBlockByHash(hash *bc.Hash) (*types.Block, error) {
    40  	block, ok := c.blockMap[*hash]
    41  	if !ok {
    42  		return nil, errors.New("can't find block")
    43  	}
    44  	return block, nil
    45  }
    46  
    47  func (c *Chain) GetBlockByHeight(height uint64) (*types.Block, error) {
    48  	block, ok := c.heightMap[height]
    49  	if !ok {
    50  		return nil, errors.New("can't find block")
    51  	}
    52  	return block, nil
    53  }
    54  
    55  func (c *Chain) GetHeaderByHash(hash *bc.Hash) (*types.BlockHeader, error) {
    56  	block, ok := c.blockMap[*hash]
    57  	if !ok {
    58  		return nil, errors.New("can't find block")
    59  	}
    60  	return &block.BlockHeader, nil
    61  }
    62  
    63  func (c *Chain) GetHeaderByHeight(height uint64) (*types.BlockHeader, error) {
    64  	block, ok := c.heightMap[height]
    65  	if !ok {
    66  		return nil, errors.New("can't find block")
    67  	}
    68  	return &block.BlockHeader, nil
    69  }
    70  
    71  func (c *Chain) GetTransactionStatus(hash *bc.Hash) (*bc.TransactionStatus, error) {
    72  	block, err := c.GetBlockByHash(hash)
    73  	if err != nil {
    74  		return nil, errors.New("can't find block by hash")
    75  	}
    76  	txCount := len(block.Transactions)
    77  	var statuses []*bc.TxVerifyResult
    78  	rand.Seed(int64(block.Height))
    79  	for i := 0; i < txCount; i++ {
    80  		status := &bc.TxVerifyResult{}
    81  		if fail := rand.Intn(2); fail == 0 {
    82  			status.StatusFail = true
    83  		} else {
    84  			status.StatusFail = false
    85  		}
    86  		statuses = append(statuses, status)
    87  	}
    88  	txStatus := &bc.TransactionStatus{VerifyStatus: statuses}
    89  	return txStatus, nil
    90  }
    91  
    92  func (c *Chain) InMainChain(hash bc.Hash) bool {
    93  	block, ok := c.blockMap[hash]
    94  	if !ok {
    95  		return false
    96  	}
    97  	return c.heightMap[block.Height] == block
    98  }
    99  
   100  func (c *Chain) ProcessBlock(block *types.Block) (bool, error) {
   101  	if c.bestBlockHeader.Hash() == block.PreviousBlockHash {
   102  		c.heightMap[block.Height] = block
   103  		c.blockMap[block.Hash()] = block
   104  		c.bestBlockHeader = &block.BlockHeader
   105  		return false, nil
   106  	}
   107  
   108  	if _, ok := c.blockMap[block.PreviousBlockHash]; !ok {
   109  		c.prevOrphans[block.PreviousBlockHash] = block
   110  		return true, nil
   111  	}
   112  
   113  	c.blockMap[block.Hash()] = block
   114  	for c.prevOrphans[block.Hash()] != nil {
   115  		block = c.prevOrphans[block.Hash()]
   116  		c.blockMap[block.Hash()] = block
   117  	}
   118  
   119  	if block.Height < c.bestBlockHeader.Height {
   120  		return false, nil
   121  	}
   122  
   123  	c.bestBlockHeader = &block.BlockHeader
   124  	for !c.InMainChain(block.Hash()) {
   125  		c.heightMap[block.Height] = block
   126  		block = c.blockMap[block.PreviousBlockHash]
   127  	}
   128  	return false, nil
   129  }
   130  
   131  func (c *Chain) SetBestBlockHeader(header *types.BlockHeader) {
   132  	c.bestBlockHeader = header
   133  }
   134  
   135  func (c *Chain) SetBlockByHeight(height uint64, block *types.Block) {
   136  	c.heightMap[height] = block
   137  	c.blockMap[block.Hash()] = block
   138  }
   139  
   140  func (c *Chain) ValidateTx(*types.Tx) (bool, error) {
   141  	return false, nil
   142  }