github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/protocol/casper/apply_block.go (about) 1 package casper 2 3 import ( 4 "fmt" 5 6 log "github.com/sirupsen/logrus" 7 8 "github.com/bytom/bytom/config" 9 "github.com/bytom/bytom/consensus" 10 "github.com/bytom/bytom/errors" 11 "github.com/bytom/bytom/protocol/bc" 12 "github.com/bytom/bytom/protocol/bc/types" 13 "github.com/bytom/bytom/protocol/state" 14 ) 15 16 // ApplyBlock used to receive a new block from upper layer, it provides idempotence 17 // and parse the vote and mortgage from the transactions, then save to the checkpoint 18 // the tree of checkpoint will grow with the arrival of new blocks 19 // it will return verification when an epoch is reached and the current node is the validator, otherwise return nil 20 // the chain module must broadcast the verification 21 func (c *Casper) ApplyBlock(block *types.Block) (bc.Hash, error) { 22 if block.Height%consensus.ActiveNetParams.BlocksOfEpoch == 1 { 23 c.newEpochCh <- block.PreviousBlockHash 24 } 25 26 c.mu.Lock() 27 defer c.mu.Unlock() 28 if node := c.tree.nodeByHash(block.Hash()); node != nil { 29 return c.bestChain(), nil 30 } 31 32 target, err := c.applyBlockToCheckpoint(block) 33 if err != nil { 34 return bc.Hash{}, errors.Wrap(err, "apply block to checkpoint") 35 } 36 37 if err := c.applyMyVerification(target, block); err != nil { 38 return bc.Hash{}, err 39 } 40 41 affectedCheckpoints, err := c.applySupLinks(target, block.SupLinks) 42 if err != nil { 43 return bc.Hash{}, err 44 } 45 46 return c.bestChain(), c.saveCheckpoints(affectedCheckpoints) 47 } 48 49 func (c *Casper) applyBlockToCheckpoint(block *types.Block) (*state.Checkpoint, error) { 50 node, err := c.checkpointNodeByHash(block.PreviousBlockHash) 51 if err != nil { 52 return nil, err 53 } 54 55 if block.Height%consensus.ActiveNetParams.BlocksOfEpoch == 1 { 56 node = node.newChild() 57 } 58 return node.Checkpoint, node.Increase(block) 59 } 60 61 func (c *Casper) checkpointNodeByHash(hash bc.Hash) (*treeNode, error) { 62 if node := c.tree.nodeByHash(hash); node != nil { 63 return node, nil 64 } 65 66 block, err := c.store.GetBlock(&hash) 67 if err != nil { 68 return nil, err 69 } 70 71 if block.Height%consensus.ActiveNetParams.BlocksOfEpoch == 0 { 72 return nil, errors.New("checkpointNodeByHash fail on previous round checkpoint") 73 } 74 75 node, err := c.checkpointNodeByHash(block.PreviousBlockHash) 76 if err != nil { 77 return nil, err 78 } 79 80 if block.Height%consensus.ActiveNetParams.BlocksOfEpoch == 1 { 81 node = node.newChild() 82 } 83 return node, node.Increase(block) 84 } 85 86 // applySupLinks copy the block's supLink to the checkpoint 87 func (c *Casper) applySupLinks(target *state.Checkpoint, supLinks []*types.SupLink) ([]*state.Checkpoint, error) { 88 affectedCheckpoints := []*state.Checkpoint{target} 89 if target.Status == state.Growing { 90 return nil, nil 91 } 92 93 for _, supLink := range supLinks { 94 validVerifications, err := c.validVerificationsFromSupLink(target, supLink) 95 if err != nil { 96 return nil, err 97 } 98 99 checkpoints, err := c.addVerificationToCheckpoint(target, validVerifications...) 100 if err != nil { 101 return nil, err 102 } 103 104 affectedCheckpoints = append(affectedCheckpoints, checkpoints...) 105 } 106 return affectedCheckpoints, nil 107 } 108 109 func (c *Casper) applyMyVerification(target *state.Checkpoint, block *types.Block) error { 110 v := c.myVerification(target) 111 if v == nil { 112 return nil 113 } 114 115 if err := c.msgQueue.Post(v.toValidCasperSignMsg()); err != nil { 116 return err 117 } 118 119 block.SupLinks.AddSupLink(v.SourceHeight, v.SourceHash, v.Signature, v.order) 120 return nil 121 } 122 123 func (c *Casper) myVerification(target *state.Checkpoint) *verification { 124 if target.Status == state.Growing { 125 return nil 126 } 127 128 source := lastJustifiedCheckpoint(target) 129 if source == nil { 130 log.WithField("module", logModule).Warn("myVerification fail on find last justified") 131 return nil 132 } 133 134 prvKey := config.CommonConfig.PrivateKey() 135 v, err := convertVerification(source, target, &ValidCasperSignMsg{PubKey: prvKey.XPub().String()}) 136 if err != nil { 137 return nil 138 } 139 140 if target.ContainsVerification(v.order, nil) { 141 log.WithField("module", logModule).Warn("myVerification fail on find same height sign") 142 return nil 143 } 144 145 if err := v.Sign(*prvKey); err != nil { 146 log.WithField("module", logModule).Error("myVerification fail on sign msg") 147 return nil 148 } 149 150 if err := c.verifyVerification(v); err != nil { 151 log.WithField("module", logModule).Warn("myVerification fail on find nest sign") 152 return nil 153 } 154 155 return v 156 } 157 158 func (c *Casper) saveCheckpoints(checkpoints []*state.Checkpoint) error { 159 checkpointSet := make(map[bc.Hash]*state.Checkpoint) 160 for _, c := range checkpoints { 161 checkpointSet[c.Hash] = c 162 } 163 164 var result []*state.Checkpoint 165 for _, c := range checkpointSet { 166 result = append(result, c) 167 } 168 169 return c.store.SaveCheckpoints(result) 170 } 171 172 func lastJustifiedCheckpoint(branch *state.Checkpoint) *state.Checkpoint { 173 for parent := branch.Parent; parent != nil; parent = parent.Parent { 174 if parent.Status == state.Justified { 175 return parent 176 } 177 } 178 return nil 179 } 180 181 func (c *Casper) validVerificationsFromSupLink(target *state.Checkpoint, supLink *types.SupLink) ([]*verification, error) { 182 source, err := c.store.GetCheckpoint(&supLink.SourceHash) 183 if err != nil { 184 return nil, err 185 } 186 187 if source.Height != supLink.SourceHeight { 188 return nil, fmt.Errorf("suplink has incorrect source height") 189 } 190 191 var result []*verification 192 for _, v := range supLinkToVerifications(source, target, supLink) { 193 if c.verifyVerification(v) == nil { 194 result = append(result, v) 195 } 196 } 197 return result, nil 198 }