4 "github.com/bytom/mining/tensority"
5 "github.com/bytom/protocol"
6 "github.com/bytom/protocol/bc"
7 "github.com/bytom/protocol/bc/types"
8 "github.com/bytom/protocol/validation"
9 "github.com/bytom/protocol/vm"
12 // NewBlock create block according to the current status of chain
13 func NewBlock(chain *protocol.Chain, txs []*types.Tx, controlProgram []byte) (*types.Block, error) {
16 txEntries := []*bc.Tx{nil}
17 txStatus := bc.NewTransactionStatus()
18 txStatus.SetStatus(0, false)
20 preBlockHeader := chain.BestBlockHeader()
21 preBlockHash := preBlockHeader.Hash()
22 nextBits, err := chain.CalcNextBits(&preBlockHash)
28 BlockHeader: types.BlockHeader{
30 Height: preBlockHeader.Height + 1,
31 PreviousBlockHash: preBlockHeader.Hash(),
32 Timestamp: preBlockHeader.Timestamp + 1,
33 BlockCommitment: types.BlockCommitment{},
36 Transactions: []*types.Tx{nil},
39 bcBlock := &bc.Block{BlockHeader: &bc.BlockHeader{Height: preBlockHeader.Height + 1}}
40 for _, tx := range txs {
42 gasStatus, err := validation.ValidateTx(tx.Tx, bcBlock)
44 if !gasStatus.GasValid {
50 txStatus.SetStatus(len(b.Transactions), gasOnlyTx)
51 b.Transactions = append(b.Transactions, tx)
52 txEntries = append(txEntries, tx.Tx)
53 gasUsed += uint64(gasStatus.GasUsed)
57 coinbaseTx, err := CreateCoinbaseTx(controlProgram, preBlockHeader.Height+1, txsFee)
62 b.Transactions[0] = coinbaseTx
63 txEntries[0] = coinbaseTx.Tx
64 b.TransactionsMerkleRoot, err = bc.TxMerkleRoot(txEntries)
69 b.TransactionStatusHash, err = bc.TxStatusMerkleRoot(txStatus.VerifyStatus)
73 // ReplaceCoinbase replace the coinbase tx of block with coinbaseTx
74 func ReplaceCoinbase(block *types.Block, coinbaseTx *types.Tx) (err error) {
75 block.Transactions[0] = coinbaseTx
76 txEntires := []*bc.Tx{coinbaseTx.Tx}
77 for i := 1; i < len(block.Transactions); i++ {
78 txEntires = append(txEntires, block.Transactions[i].Tx)
81 block.TransactionsMerkleRoot, err = bc.TxMerkleRoot(txEntires)
85 // AppendBlocks append empty blocks to chain, mainly used to mature the coinbase tx
86 func AppendBlocks(chain *protocol.Chain, num uint64) error {
87 for i := uint64(0); i < num; i++ {
88 block, err := NewBlock(chain, nil, []byte{byte(vm.OP_TRUE)})
92 if err := SolveAndUpdate(chain, block); err != nil {
99 // SolveAndUpdate solve difficulty and update chain status
100 func SolveAndUpdate(chain *protocol.Chain, block *types.Block) error {
101 seed, err := chain.CalcNextSeed(&block.PreviousBlockHash)
106 _, err = chain.ProcessBlock(block)
110 // Solve simulate solve difficulty by add result to cache
111 func Solve(seed *bc.Hash, block *types.Block) {
112 hash := block.BlockHeader.Hash()
113 tensority.AIHash.AddCache(&hash, seed, &bc.Hash{})