6 "github.com/sirupsen/logrus"
8 "github.com/bytom/bytom/config"
9 "github.com/bytom/bytom/consensus"
10 "github.com/bytom/bytom/errors"
11 "github.com/bytom/bytom/math/checked"
12 "github.com/bytom/bytom/protocol/bc"
13 "github.com/bytom/bytom/protocol/bc/types"
14 "github.com/bytom/bytom/protocol/state"
17 type applyBlockReply struct {
18 verification *Verification
22 // ApplyBlock used to receive a new block from upper layer, it provides idempotence
23 // and parse the vote and mortgage from the transactions, then save to the checkpoint
24 // the tree of checkpoint will grow with the arrival of new blocks
25 // it will return verification when an epoch is reached and the current node is the validator, otherwise return nil
26 // the chain module must broadcast the verification
27 func (c *Casper) ApplyBlock(block *types.Block) (*applyBlockReply, error) {
28 if block.Height%consensus.ActiveNetParams.BlocksOfEpoch == 1 {
29 c.newEpochCh <- block.PreviousBlockHash
35 if _, err := c.tree.nodeByHash(block.Hash()); err == nil {
36 return &applyBlockReply{bestHash: c.bestChain()}, nil
39 target, err := c.applyBlockToCheckpoint(block)
41 return nil, errors.Wrap(err, "apply block to checkpoint")
44 if err := applyTransactions(target, block.Transactions); err != nil {
48 validators, err := c.Validators(&target.Hash)
53 verification, err := c.applyMyVerification(target, block, validators)
58 affectedCheckpoints, err := c.applySupLinks(target, block.SupLinks, validators)
63 return &applyBlockReply{verification: verification, bestHash: c.bestChain()}, c.saveCheckpoints(affectedCheckpoints)
66 func (c *Casper) applyBlockToCheckpoint(block *types.Block) (*state.Checkpoint, error) {
67 node, err := c.checkpointNodeByHash(block.PreviousBlockHash)
72 checkpoint := node.checkpoint
73 if mod := block.Height % consensus.ActiveNetParams.BlocksOfEpoch; mod == 1 {
75 checkpoint = state.NewCheckpoint(parent)
76 node.addChild(&treeNode{checkpoint: checkpoint})
78 checkpoint.Status = state.Unjustified
79 if err := checkpoint.ApplyFederationReward(); err != nil {
84 if err := checkpoint.ApplyValidatorReward(block); err != nil {
88 return checkpoint, checkpoint.Increase(block)
91 func (c *Casper) checkpointNodeByHash(blockHash bc.Hash) (*treeNode, error) {
92 node, err := c.tree.nodeByHash(blockHash)
94 logrus.WithField("err", err).Error("fail find checkpoint, start to reorganize checkpoint")
96 return c.replayCheckpoint(blockHash)
102 func (c *Casper) replayCheckpoint(hash bc.Hash) (*treeNode, error) {
104 var attachBlocks []*types.Block
106 prevBlock, err := c.store.GetBlock(&prevHash)
111 if prevBlock.Height%consensus.ActiveNetParams.BlocksOfEpoch == 0 {
115 attachBlocks = append([]*types.Block{prevBlock}, attachBlocks...)
116 prevHash = prevBlock.PreviousBlockHash
119 parent, err := c.tree.nodeByHash(prevHash)
124 node := &treeNode{checkpoint: state.NewCheckpoint(parent.checkpoint)}
125 parent.addChild(node)
126 for _, attachBlock := range attachBlocks {
127 if err := applyTransactions(node.checkpoint, attachBlock.Transactions); err != nil {
131 if err := node.checkpoint.ApplyValidatorReward(attachBlock); err != nil {
135 if err := node.checkpoint.Increase(attachBlock); err != nil {
142 func applyTransactions(target *state.Checkpoint, transactions []*types.Tx) error {
143 for _, tx := range transactions {
144 for _, input := range tx.Inputs {
145 if vetoInput, ok := input.TypedInput.(*types.VetoInput); ok {
146 if err := processVeto(vetoInput, target); err != nil {
152 for _, output := range tx.Outputs {
153 if _, ok := output.TypedOutput.(*types.VoteOutput); ok {
154 if err := processVote(output, target); err != nil {
163 // applySupLinks copy the block's supLink to the checkpoint
164 func (c *Casper) applySupLinks(target *state.Checkpoint, supLinks []*types.SupLink, validators map[string]*state.Validator) ([]*state.Checkpoint, error) {
165 affectedCheckpoints := []*state.Checkpoint{target}
166 if target.Height%consensus.ActiveNetParams.BlocksOfEpoch != 0 {
170 for _, supLink := range supLinks {
171 var validVerifications []*Verification
172 for _, v := range supLinkToVerifications(supLink, validators, target.Hash, target.Height) {
173 if validate(v) == nil && c.verifyVerification(v, validators[v.PubKey].Order, true) == nil {
174 validVerifications = append(validVerifications, v)
178 checkpoints, err := c.addVerificationToCheckpoint(target, validators, validVerifications...)
183 affectedCheckpoints = append(affectedCheckpoints, checkpoints...)
185 return affectedCheckpoints, nil
188 func (c *Casper) applyMyVerification(target *state.Checkpoint, block *types.Block, validators map[string]*state.Validator) (*Verification, error) {
189 v, err := c.myVerification(target, validators)
198 block.SupLinks.AddSupLink(v.SourceHeight, v.SourceHash, v.Signature, validators[v.PubKey].Order)
199 return v, c.store.SaveBlockHeader(&block.BlockHeader)
202 func (c *Casper) myVerification(target *state.Checkpoint, validators map[string]*state.Validator) (*Verification, error) {
203 if target.Height%consensus.ActiveNetParams.BlocksOfEpoch != 0 {
207 pubKey := config.CommonConfig.PrivateKey().XPub().String()
208 if _, ok := validators[pubKey]; !ok {
212 validatorOrder := validators[pubKey].Order
213 if target.ContainsVerification(validatorOrder, nil) {
217 if source := c.lastJustifiedCheckpoint(target); source != nil {
219 SourceHash: source.Hash,
220 TargetHash: target.Hash,
221 SourceHeight: source.Height,
222 TargetHeight: target.Height,
226 prvKey := config.CommonConfig.PrivateKey()
227 if err := v.Sign(*prvKey); err != nil {
231 if err := c.verifyVerification(v, validatorOrder, false); err != nil {
240 func processVeto(input *types.VetoInput, checkpoint *state.Checkpoint) error {
241 pubKey := hex.EncodeToString(input.Vote)
242 voteNum := checkpoint.Votes[pubKey]
243 voteNum, ok := checked.SubUint64(voteNum, input.Amount)
245 return checked.ErrOverflow
248 checkpoint.Votes[pubKey] = voteNum
252 func processVote(output *types.TxOutput, checkpoint *state.Checkpoint) error {
253 voteOutput := output.TypedOutput.(*types.VoteOutput)
254 pubKey := hex.EncodeToString(voteOutput.Vote)
255 voteNum := checkpoint.Votes[pubKey]
256 voteNum, ok := checked.AddUint64(voteNum, output.Amount)
258 return checked.ErrOverflow
261 checkpoint.Votes[pubKey] = voteNum
265 func (c *Casper) lastJustifiedCheckpoint(branch *state.Checkpoint) *state.Checkpoint {
266 parent := branch.Parent
268 switch parent.Status {
269 case state.Finalized:
271 case state.Justified:
274 parent = parent.Parent
279 func (c *Casper) saveCheckpoints(checkpoints []*state.Checkpoint) error {
280 checkpointSet := make(map[bc.Hash]*state.Checkpoint)
281 for _, c := range checkpoints {
282 checkpointSet[c.Hash] = c
285 var result []*state.Checkpoint
286 for _, c := range checkpointSet {
287 result = append(result, c)
290 return c.store.SaveCheckpoints(result)
293 func supLinkToVerifications(supLink *types.SupLink, validators map[string]*state.Validator, targetHash bc.Hash, targetHeight uint64) []*Verification {
294 validatorList := make([]*state.Validator, len(validators))
295 for _, validator := range validators {
296 validatorList[validator.Order] = validator
299 var result []*Verification
300 for i := 0; i < len(validators); i++ {
301 signature := supLink.Signatures[i]
302 if len(signature) == 0 {
306 result = append(result, &Verification{
307 SourceHash: supLink.SourceHash,
308 TargetHash: targetHash,
309 SourceHeight: supLink.SourceHeight,
310 TargetHeight: targetHeight,
311 Signature: signature,
312 PubKey: validatorList[i].PubKey,