OSDN Git Service

try to fix ban peer bug (#273)
[bytom/vapor.git] / proposal / proposal.go
index befa559..a4c51e4 100644 (file)
@@ -24,10 +24,8 @@ const logModule = "mining"
 // createCoinbaseTx returns a coinbase transaction paying an appropriate subsidy
 // based on the passed block height to the provided address.  When the address
 // is nil, the coinbase transaction will instead be redeemable by anyone.
-func createCoinbaseTx(accountManager *account.Manager, amount uint64, blockHeight uint64) (tx *types.Tx, err error) {
-       amount += consensus.BlockSubsidy(blockHeight)
+func createCoinbaseTx(accountManager *account.Manager, blockHeight uint64) (tx *types.Tx, err error) {
        arbitrary := append([]byte{0x00}, []byte(strconv.FormatUint(blockHeight, 10))...)
-
        var script []byte
        if accountManager == nil {
                script, err = vmutil.DefaultCoinbaseProgram()
@@ -39,7 +37,7 @@ func createCoinbaseTx(accountManager *account.Manager, amount uint64, blockHeigh
                return nil, err
        }
 
-       if len(arbitrary) > consensus.CoinbaseArbitrarySizeLimit {
+       if len(arbitrary) > consensus.ActiveNetParams.CoinbaseArbitrarySizeLimit {
                return nil, validation.ErrCoinbaseArbitraryOversize
        }
 
@@ -47,19 +45,14 @@ func createCoinbaseTx(accountManager *account.Manager, amount uint64, blockHeigh
        if err = builder.AddInput(types.NewCoinbaseInput(arbitrary), &txbuilder.SigningInstruction{}); err != nil {
                return nil, err
        }
-       if err = builder.AddOutput(types.NewIntraChainOutput(*consensus.BTMAssetID, amount, script)); err != nil {
-               return nil, err
-       }
-       _, txData, err := builder.Build()
-       if err != nil {
+       if err = builder.AddOutput(types.NewIntraChainOutput(*consensus.BTMAssetID, 0, script)); err != nil {
                return nil, err
        }
 
-       byteData, err := txData.MarshalText()
+       _, txData, err := builder.Build()
        if err != nil {
                return nil, err
        }
-       txData.SerializedSize = uint64(len(byteData))
 
        tx = &types.Tx{
                TxData: *txData,
@@ -68,6 +61,22 @@ func createCoinbaseTx(accountManager *account.Manager, amount uint64, blockHeigh
        return tx, nil
 }
 
+// restructCoinbaseTx build coinbase transaction with aggregate outputs when it achieved the specified block height
+func restructCoinbaseTx(tx *types.Tx, rewards []state.CoinbaseReward) error {
+       for _, r := range rewards {
+               tx.Outputs = append(tx.Outputs, types.NewIntraChainOutput(*consensus.BTMAssetID, r.Amount, r.ControlProgram))
+       }
+
+       byteData, err := tx.TxData.MarshalText()
+       if err != nil {
+               return err
+       }
+
+       tx.TxData.SerializedSize = uint64(len(byteData))
+       tx.Tx = types.MapTx(&tx.TxData)
+       return nil
+}
+
 // NewBlockTemplate returns a new block template that is ready to be solved
 func NewBlockTemplate(c *protocol.Chain, txPool *protocol.TxPool, accountManager *account.Manager, timestamp uint64) (b *types.Block, err error) {
        view := state.NewUtxoViewpoint()
@@ -77,7 +86,6 @@ func NewBlockTemplate(c *protocol.Chain, txPool *protocol.TxPool, accountManager
        }
        txEntries := []*bc.Tx{nil}
        gasUsed := uint64(0)
-       txFee := uint64(0)
 
        // get preblock info for generate next block
        preBlockHeader := c.BestBlockHeader()
@@ -91,7 +99,7 @@ func NewBlockTemplate(c *protocol.Chain, txPool *protocol.TxPool, accountManager
                        PreviousBlockHash: preBlockHash,
                        Timestamp:         timestamp,
                        BlockCommitment:   types.BlockCommitment{},
-                       BlockWitness:      types.BlockWitness{Witness: make([][]byte, consensus.NumOfConsensusNode)},
+                       BlockWitness:      types.BlockWitness{Witness: make([][]byte, consensus.ActiveNetParams.NumOfConsensusNode)},
                },
        }
        bcBlock := &bc.Block{BlockHeader: &bc.BlockHeader{Height: nextBlockHeight}}
@@ -125,7 +133,7 @@ func NewBlockTemplate(c *protocol.Chain, txPool *protocol.TxPool, accountManager
                        continue
                }
 
-               if gasUsed+uint64(gasStatus.GasUsed) > consensus.MaxBlockGas {
+               if gasUsed+uint64(gasStatus.GasUsed) > consensus.ActiveNetParams.MaxBlockGas {
                        break
                }
 
@@ -141,21 +149,38 @@ func NewBlockTemplate(c *protocol.Chain, txPool *protocol.TxPool, accountManager
                b.Transactions = append(b.Transactions, txDesc.Tx)
                txEntries = append(txEntries, tx)
                gasUsed += uint64(gasStatus.GasUsed)
-               txFee += txDesc.Fee
-
-               if gasUsed == consensus.MaxBlockGas {
+               if gasUsed == consensus.ActiveNetParams.MaxBlockGas {
                        break
                }
 
        }
 
-       // creater coinbase transaction
-       b.Transactions[0], err = createCoinbaseTx(accountManager, txFee, nextBlockHeight)
+       // create coinbase transaction
+       b.Transactions[0], err = createCoinbaseTx(accountManager, nextBlockHeight)
        if err != nil {
                return nil, errors.Wrap(err, "fail on createCoinbaseTx")
        }
-       txEntries[0] = b.Transactions[0].Tx
 
+       consensusResult, err := c.GetConsensusResultByHash(&preBlockHash)
+       if err != nil {
+               return nil, err
+       }
+
+       if err := consensusResult.AttachCoinbaseReward(b); err != nil {
+               return nil, err
+       }
+
+       rewards, err := consensusResult.GetCoinbaseRewards(nextBlockHeight)
+       if err != nil {
+               return nil, err
+       }
+
+       // restruct coinbase transaction
+       if err = restructCoinbaseTx(b.Transactions[0], rewards); err != nil {
+               return nil, errors.Wrap(err, "fail on createCoinbaseTx")
+       }
+
+       txEntries[0] = b.Transactions[0].Tx
        b.BlockHeader.BlockCommitment.TransactionsMerkleRoot, err = types.TxMerkleRoot(txEntries)
        if err != nil {
                return nil, err