Block Lifecycle
Previous has introduced the concept of block cycle in tripod
in detail. By customizing the block cycle, we can implement many deep functions, such as consensus algorithms. Below we use
Take pow consensus as an example, the original code address here
- Init blockchain,build a genesis block.
func (p *Pow) InitChain() error {
// build a genesis block and append chain.
chain := p.env.Chain
gensisBlock := &types.Block{
Header: &types.Header{},
}
err := chain.SetGenesis(gensisBlock)
if err != nil {
return err
}
// Start a gorotine to pull data from other nodes in the P2P network in real time
go func() {
for {
msg, err := p.env.P2pNetwork.SubP2P(StartBlockTopic)
if err != nil {
logrus.Error("subscribe message from P2P error: ", err)
continue
}
p.msgChan <- msg
}
}()
return nil
}
- Block starts,build a new block
func (p *Pow) StartBlock(block *Block) error {
pool := p.env.Pool
// If a block from another node is received before the local node produces a block, the mining will be skipped after verification and the block will be directly stored in the chain.
// If there is none or the block is invalid, the local node starts mining.
if p.UseBlocksFromP2P(block) {
logrus.Infof("--------USE P2P block(%s)", block.Hash.String())
return nil
}
// Pack transactions from txpool.
txns, err := pool.Pack(p.packLimit)
if err != nil {
return err
}
......
// Start to mining.
nonce, hash, err := spow.Run(block, p.target, p.targetBits)
if err != nil {
return err
}
......
// After mining, the block is broadcast to the P2P network.
return p.env.P2pNetwork.PubP2P(StartBlockTopic, rawBlockByt)
}
- End block
func (*Pow) EndBlock(block *Block) error {
chain := p.env.Chain
pool := p.env.Pool
// Execute the transactions of the block.
err := p.env.Execute(block)
if err != nil {
return err
}
// Store blocks in the chain for persistence.
err = chain.AppendBlock(block)
if err != nil {
return err
}
return pool.Reset(block)
}
- Final consensus, finalizing the block:
Since the pow consensus generally does not require the finalization stage of the final consensus, because they have the longest sub-chain or the heaviest sub-chain to prove the computing power. So here we don't need to implement
FinalizeBlock()
.
func (*Pow) FinalizeBlock(_ *Block) error {
return nil
}
So far, a pow consensus mechanism based on sha256 is completed.