X-Git-Url: http://git.osdn.net/view?p=bytom%2Fvapor.git;a=blobdiff_plain;f=proposal%2Fproposal.go;h=a4c51e43870ce6b92f7a6d6cca7a4977523a5dca;hp=befa5596dcfe75bb3adafbf2a713fce2189f1c81;hb=695ef3e26fc9e184258b9b68a8249dc44b24e7e0;hpb=94ffe408f68d354070374ef01b5c1578b79d2cd9 diff --git a/proposal/proposal.go b/proposal/proposal.go index befa5596..a4c51e43 100644 --- a/proposal/proposal.go +++ b/proposal/proposal.go @@ -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