github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/test/block_test_util.go (about)

     1  package test
     2  
     3  import (
     4  	"github.com/bytom/bytom/protocol"
     5  	"github.com/bytom/bytom/protocol/bc"
     6  	"github.com/bytom/bytom/protocol/bc/types"
     7  	"github.com/bytom/bytom/protocol/validation"
     8  	"github.com/bytom/bytom/protocol/vm"
     9  )
    10  
    11  // NewBlock create block according to the current status of chain
    12  func NewBlock(chain *protocol.Chain, txs []*types.Tx, controlProgram []byte) (*types.Block, error) {
    13  	gasUsed := uint64(0)
    14  	txsFee := uint64(0)
    15  
    16  	preBlockHeader := chain.BestBlockHeader()
    17  
    18  	b := &types.Block{
    19  		BlockHeader: types.BlockHeader{
    20  			Version:           1,
    21  			Height:            preBlockHeader.Height + 1,
    22  			PreviousBlockHash: preBlockHeader.Hash(),
    23  			Timestamp:         preBlockHeader.Timestamp + 10000,
    24  			BlockCommitment:   types.BlockCommitment{},
    25  		},
    26  		Transactions: []*types.Tx{nil},
    27  	}
    28  
    29  	bcBlock := &bc.Block{BlockHeader: &bc.BlockHeader{Height: preBlockHeader.Height + 1}}
    30  	for _, tx := range txs {
    31  		gasStatus, err := validation.ValidateTx(tx.Tx, bcBlock, chain.ProgramConverter)
    32  		if err != nil {
    33  			continue
    34  		}
    35  
    36  		b.Transactions = append(b.Transactions, tx)
    37  		gasUsed += uint64(gasStatus.GasUsed)
    38  		txsFee += txFee(tx)
    39  	}
    40  
    41  	coinbaseTx, err := CreateCoinbaseTx(controlProgram, preBlockHeader.Height+1, txsFee)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  
    46  	b.Transactions[0] = coinbaseTx
    47  	if len(txs) > 0 {
    48  		b.Transactions = append(b.Transactions, txs...)
    49  	}
    50  
    51  	txEntries := []*bc.Tx{nil}
    52  	txEntries[0] = coinbaseTx.Tx
    53  	for _, tx := range txs {
    54  		txEntries = append(txEntries, tx.Tx)
    55  	}
    56  	b.TransactionsMerkleRoot, err = types.TxMerkleRoot(txEntries)
    57  	return b, err
    58  }
    59  
    60  // ReplaceCoinbase replace the coinbase tx of block with coinbaseTx
    61  func ReplaceCoinbase(block *types.Block, coinbaseTx *types.Tx) (err error) {
    62  	block.Transactions[0] = coinbaseTx
    63  	txEntires := []*bc.Tx{coinbaseTx.Tx}
    64  	for i := 1; i < len(block.Transactions); i++ {
    65  		txEntires = append(txEntires, block.Transactions[i].Tx)
    66  	}
    67  
    68  	block.TransactionsMerkleRoot, err = types.TxMerkleRoot(txEntires)
    69  	return
    70  }
    71  
    72  // AppendBlocks append empty blocks to chain, mainly used to mature the coinbase tx
    73  func AppendBlocks(chain *protocol.Chain, num uint64) error {
    74  	for i := uint64(0); i < num; i++ {
    75  		block, err := NewBlock(chain, nil, []byte{byte(vm.OP_TRUE)})
    76  		if err != nil {
    77  			return err
    78  		}
    79  		if _, err := chain.ProcessBlock(block); err != nil {
    80  			return err
    81  		}
    82  	}
    83  	return nil
    84  }