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

     1  package test
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/bytom/bytom/protocol"
     7  	"github.com/bytom/bytom/protocol/bc/types"
     8  	dbm "github.com/bytom/bytom/database/leveldb"
     9  )
    10  
    11  func declChain(name string, baseChain *protocol.Chain, baseHeight uint64, height uint64) (*protocol.Chain, error) {
    12  	chainDB := dbm.NewDB(name, "leveldb", name)
    13  	chain, _, _, err := MockChain(chainDB)
    14  	if err != nil {
    15  		return nil, err
    16  	}
    17  
    18  	if baseChain == nil {
    19  		if err := AppendBlocks(chain, height); err != nil {
    20  			return nil, err
    21  		}
    22  		return chain, nil
    23  	}
    24  
    25  	for i := uint64(1); i <= baseHeight; i++ {
    26  		block, err := baseChain.GetBlockByHeight(i)
    27  		if err != nil {
    28  			return nil, err
    29  		}
    30  		if err := SolveAndUpdate(chain, block); err != nil {
    31  			return nil, err
    32  		}
    33  	}
    34  
    35  	err = AppendBlocks(chain, height-baseHeight)
    36  	return chain, err
    37  }
    38  
    39  func ancestorOf(c1 *protocol.Chain, c2 *protocol.Chain) (*types.Block, error) {
    40  	start := c1.BestBlockHeight()
    41  	if c2.BestBlockHeight() < c1.BestBlockHeight() {
    42  		start = c2.BestBlockHeight()
    43  	}
    44  
    45  	for i := start; i >= 0; i-- {
    46  		b1, err := c1.GetBlockByHeight(i)
    47  		if err != nil {
    48  			return nil, err
    49  		}
    50  		b2, err := c2.GetBlockByHeight(i)
    51  		if err != nil {
    52  			return nil, err
    53  		}
    54  		if b1.Hash() == b2.Hash() {
    55  			return b1, nil
    56  		}
    57  	}
    58  	return nil, fmt.Errorf("can't find ancestor")
    59  }
    60  
    61  func merge(c1 *protocol.Chain, c2 *protocol.Chain) error {
    62  	// c1 and c2 are same
    63  	if c1.BestBlockHeight() == c2.BestBlockHeight() && *c1.BestBlockHash() == *c2.BestBlockHash() {
    64  		return nil
    65  	}
    66  
    67  	ancestor, err := ancestorOf(c1, c2)
    68  	if err != nil {
    69  		return err
    70  	}
    71  
    72  	processBlocks := func(dest *protocol.Chain, src *protocol.Chain, height uint64) error {
    73  		for h := src.BestBlockHeight(); h > height; h-- {
    74  			block, err := src.GetBlockByHeight(h)
    75  			if err != nil {
    76  				return err
    77  			}
    78  			_, err = dest.ProcessBlock(block)
    79  			if err != nil {
    80  				return err
    81  			}
    82  		}
    83  		return nil
    84  	}
    85  
    86  	if err := processBlocks(c1, c2, ancestor.Height); err != nil {
    87  		return err
    88  	}
    89  	return processBlocks(c2, c1, ancestor.Height)
    90  }