github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/test/protocol_test_util.go (about) 1 package test 2 3 import ( 4 "fmt" 5 6 dbm "github.com/bytom/bytom/database/leveldb" 7 "github.com/bytom/bytom/protocol" 8 "github.com/bytom/bytom/protocol/bc/types" 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 := chain.ProcessBlock(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 }