OSDN Git Service

edit the config for prod (#1174)
[bytom/bytom.git] / test / block_test_util.go
1 package test
2
3 import (
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"
10 )
11
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) {
14         gasUsed := uint64(0)
15         txsFee := uint64(0)
16         txEntries := []*bc.Tx{nil}
17         txStatus := bc.NewTransactionStatus()
18         txStatus.SetStatus(0, false)
19
20         preBlockHeader := chain.BestBlockHeader()
21         preBlockHash := preBlockHeader.Hash()
22         nextBits, err := chain.CalcNextBits(&preBlockHash)
23         if err != nil {
24                 return nil, err
25         }
26
27         b := &types.Block{
28                 BlockHeader: types.BlockHeader{
29                         Version:           1,
30                         Height:            preBlockHeader.Height + 1,
31                         PreviousBlockHash: preBlockHeader.Hash(),
32                         Timestamp:         preBlockHeader.Timestamp + 1,
33                         BlockCommitment:   types.BlockCommitment{},
34                         Bits:              nextBits,
35                 },
36                 Transactions: []*types.Tx{nil},
37         }
38
39         bcBlock := &bc.Block{BlockHeader: &bc.BlockHeader{Height: preBlockHeader.Height + 1}}
40         for _, tx := range txs {
41                 gasOnlyTx := false
42                 gasStatus, err := validation.ValidateTx(tx.Tx, bcBlock)
43                 if err != nil {
44                         if !gasStatus.GasValid {
45                                 continue
46                         }
47                         gasOnlyTx = true
48                 }
49
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)
54                 txsFee += txFee(tx)
55         }
56
57         coinbaseTx, err := CreateCoinbaseTx(controlProgram, preBlockHeader.Height+1, txsFee)
58         if err != nil {
59                 return nil, err
60         }
61
62         b.Transactions[0] = coinbaseTx
63         txEntries[0] = coinbaseTx.Tx
64         b.TransactionsMerkleRoot, err = bc.TxMerkleRoot(txEntries)
65         if err != nil {
66                 return nil, err
67         }
68
69         b.TransactionStatusHash, err = bc.TxStatusMerkleRoot(txStatus.VerifyStatus)
70         return b, err
71 }
72
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)
79         }
80
81         block.TransactionsMerkleRoot, err = bc.TxMerkleRoot(txEntires)
82         return
83 }
84
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)})
89                 if err != nil {
90                         return err
91                 }
92                 if err := SolveAndUpdate(chain, block); err != nil {
93                         return err
94                 }
95         }
96         return nil
97 }
98
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)
102         if err != nil {
103                 return err
104         }
105         Solve(seed, block)
106         _, err = chain.ProcessBlock(block)
107         return err
108 }
109
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{})
114 }