github.com/codingfuture/orig-energi3@v0.8.4/energi/consensus/reward.go (about)

     1  // Copyright 2019 The Energi Core Authors
     2  // This file is part of the Energi Core library.
     3  //
     4  // The Energi Core library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The Energi Core library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the Energi Core library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package consensus
    18  
    19  import (
    20  	"math/big"
    21  
    22  	"github.com/ethereum/go-ethereum/common"
    23  	"github.com/ethereum/go-ethereum/common/math"
    24  	"github.com/ethereum/go-ethereum/core"
    25  	"github.com/ethereum/go-ethereum/core/state"
    26  	"github.com/ethereum/go-ethereum/core/types"
    27  	"github.com/ethereum/go-ethereum/log"
    28  
    29  	energi_params "energi.world/core/gen3/energi/params"
    30  )
    31  
    32  var (
    33  	BigBalance = new(big.Int).Div(math.MaxBig256, big.NewInt(2))
    34  )
    35  
    36  func (e *Energi) processBlockRewards(
    37  	chain ChainReader,
    38  	header *types.Header,
    39  	statedb *state.StateDB,
    40  	txs types.Transactions,
    41  	receipts types.Receipts,
    42  ) (types.Transactions, types.Receipts, error) {
    43  	systemFaucet := e.systemFaucet
    44  
    45  	// Temporary balance setup & clean up
    46  	statedb.SetBalance(systemFaucet, BigBalance)
    47  	defer statedb.SetBalance(systemFaucet, common.Big0)
    48  
    49  	// Common get reward call
    50  	getRewardData, err := e.rewardAbi.Pack("getReward", header.Number)
    51  	if err != nil {
    52  		log.Error("Fail to prepare getReward() call", "err", err)
    53  		return nil, nil, err
    54  	}
    55  
    56  	rewardData, err := e.rewardAbi.Pack("reward")
    57  	if err != nil {
    58  		log.Error("Fail to prepare reward() call", "err", err)
    59  		return nil, nil, err
    60  	}
    61  
    62  	// GetReward()
    63  	//====================================
    64  	msg := types.NewMessage(
    65  		systemFaucet,
    66  		&energi_params.Energi_BlockReward,
    67  		0,
    68  		common.Big0,
    69  		e.callGas,
    70  		common.Big0,
    71  		getRewardData,
    72  		false,
    73  	)
    74  	rev_id := statedb.Snapshot()
    75  	evm := e.createEVM(msg, chain, header, statedb)
    76  	gp := core.GasPool(msg.Gas())
    77  	output, gas1, _, err := core.ApplyMessage(evm, msg, &gp)
    78  	statedb.RevertToSnapshot(rev_id)
    79  	if err != nil {
    80  		log.Error("Failed in getReward() call", "err", err)
    81  		return nil, nil, err
    82  	}
    83  
    84  	//
    85  	total_reward := big.NewInt(0)
    86  	err = e.rewardAbi.Unpack(&total_reward, "getReward", output)
    87  	if err != nil {
    88  		log.Error("Failed to unpack getReward() call", "err", err)
    89  		return nil, nil, err
    90  	}
    91  
    92  	// Reward
    93  	//====================================
    94  	tx := types.NewTransaction(
    95  		statedb.GetNonce(systemFaucet),
    96  		energi_params.Energi_BlockReward,
    97  		total_reward,
    98  		e.xferGas,
    99  		common.Big0,
   100  		rewardData)
   101  	tx = tx.WithConsensusSender(systemFaucet)
   102  
   103  	statedb.Prepare(tx.Hash(), header.Hash(), len(txs))
   104  
   105  	msg, err = tx.AsMessage(&ConsensusSigner{})
   106  	if err != nil {
   107  		log.Error("Failed in BlockReward AsMessage()", "err", err)
   108  		return nil, nil, err
   109  	}
   110  
   111  	evm = e.createEVM(msg, chain, header, statedb)
   112  	gp = core.GasPool(msg.Gas())
   113  	_, gas2, failed, err := core.ApplyMessage(evm, msg, &gp)
   114  	if err != nil {
   115  		log.Error("Failed in reward() call", "err", err)
   116  		return nil, nil, err
   117  	}
   118  
   119  	root := statedb.IntermediateRoot(chain.Config().IsEIP158(header.Number))
   120  	receipt := types.NewReceipt(root.Bytes(), failed, header.GasUsed)
   121  	receipt.TxHash = tx.Hash()
   122  	receipt.GasUsed = gas2
   123  	receipt.Logs = statedb.GetLogs(tx.Hash())
   124  	receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
   125  
   126  	log.Trace("Block reward", "reward", total_reward, "gas", gas1+gas2)
   127  
   128  	return append(txs, tx), append(receipts, receipt), nil
   129  }