6 log "github.com/sirupsen/logrus"
8 "github.com/bytom/protocol/bc"
9 "github.com/bytom/protocol/bc/types"
12 // OrphanManage is use to handle all the orphan block
13 type OrphanManage struct {
14 //TODO: add orphan cached block limit
15 orphan map[bc.Hash]*types.Block
16 prevOrphans map[bc.Hash][]*bc.Hash
20 // NewOrphanManage return a new orphan block
21 func NewOrphanManage() *OrphanManage {
23 orphan: make(map[bc.Hash]*types.Block),
24 prevOrphans: make(map[bc.Hash][]*bc.Hash),
28 // BlockExist check is the block in OrphanManage
29 func (o *OrphanManage) BlockExist(hash *bc.Hash) bool {
31 _, ok := o.orphan[*hash]
36 // Add will add the block to OrphanManage
37 func (o *OrphanManage) Add(block *types.Block) {
38 blockHash := block.Hash()
42 if _, ok := o.orphan[blockHash]; ok {
46 o.orphan[blockHash] = block
47 o.prevOrphans[block.PreviousBlockHash] = append(o.prevOrphans[block.PreviousBlockHash], &blockHash)
49 log.WithFields(log.Fields{"hash": blockHash.String(), "height": block.Height}).Info("add block to orphan")
52 // Delete will delelte the block from OrphanManage
53 func (o *OrphanManage) Delete(hash *bc.Hash) {
56 block, ok := o.orphan[*hash]
60 delete(o.orphan, *hash)
62 prevOrphans, ok := o.prevOrphans[block.PreviousBlockHash]
63 if !ok || len(prevOrphans) == 1 {
64 delete(o.prevOrphans, block.PreviousBlockHash)
68 for i, preOrphan := range prevOrphans {
69 if preOrphan == hash {
70 o.prevOrphans[block.PreviousBlockHash] = append(prevOrphans[:i], prevOrphans[i+1:]...)
76 // Get return the orphan block by hash
77 func (o *OrphanManage) Get(hash *bc.Hash) (*types.Block, bool) {
79 block, ok := o.orphan[*hash]
84 // GetPrevOrphans return the list of child orphans
85 func (o *OrphanManage) GetPrevOrphans(hash *bc.Hash) ([]*bc.Hash, bool) {
87 prevOrphans, ok := o.prevOrphans[*hash]
89 return prevOrphans, ok