Implement block reward contract feature

This commit is contained in:
Kirill Fedoseev 2020-06-13 16:24:42 +03:00
parent d205bdbda7
commit 0e922bd841
3 changed files with 53 additions and 4 deletions

View File

@ -17,6 +17,11 @@
package core
import (
"math"
"math/big"
"strings"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc"
@ -24,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
)
@ -87,6 +93,11 @@ func (p *StateProcessor) Process(block *types.Block, statedb, privateState *stat
allLogs = append(allLogs, privateReceipt.Logs...)
}
}
if p.config.BlockReward != nil {
CallBlockReward(statedb, p.bc, header, p.config)
}
// Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles())
@ -171,3 +182,30 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common
return receipt, privateReceipt, err
}
func CallBlockReward(state *state.StateDB, bc *BlockChain, header *types.Header, config *params.ChainConfig) {
var from = common.HexToAddress("0x0")
var to common.Address = config.BlockReward.Contract
var bigZero = big.NewInt(0)
var gas uint64 = math.MaxUint64
log.Trace("Call to block reward contract", "address", to)
abi, _ := abi.JSON(strings.NewReader(`[{"type":"function","name":"reward","constant":false,"inputs":[{"name":"benefactors","type":"address[]"},{"name":"kind","type":"uint16[]"}],"outputs":[{"name":"receivers","type":"address[]"},{"name":"values","type":"uint256[]"}]}]`))
calldata, _ := abi.Pack("reward", [0]common.Address{}, [0]uint16{})
msg := types.NewMessage(from, &to, 0, bigZero, gas, bigZero, calldata, false)
evmContext := NewEVMContext(msg, header, bc, nil)
// Create a new environment which holds all relevant information
// about the transaction and calling mechanisms.
evm := vm.NewEVM(evmContext, state, state, config, vm.Config{})
gaspool := new(GasPool).AddGas(gas)
ret, _, _, _ := NewStateTransition(evm, msg, gaspool).TransitionDb()
receivers := make([]common.Address, 0, 1)
values := make([]*big.Int, 0, 1)
_ = abi.Unpack(&[]interface{}{&receivers, &values}, "reward", ret)
state.SetNonce(from, 0)
for i, receiver := range receivers {
log.Trace("Minting coins", "receiver", receiver, "values", *values[i])
state.AddBalance(receiver, values[i])
}
}

View File

@ -1048,6 +1048,11 @@ func (w *worker) commit(uncles []*types.Header, interval func(), update bool, st
s := w.current.state.Copy()
ps := w.current.privateState.Copy()
if w.chainConfig.BlockReward != nil {
core.CallBlockReward(s, w.chain, w.current.header, w.chainConfig)
}
block, err := w.engine.FinalizeAndAssemble(w.chain, w.current.header, s, w.current.txs, uncles, w.current.receipts)
if err != nil {
return err

View File

@ -214,19 +214,19 @@ var (
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, false, 32, 32, big.NewInt(0), big.NewInt(0), nil}
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, false, 32, 32, big.NewInt(0), big.NewInt(0), nil, nil}
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
// and accepted by the Ethereum core developers into the Clique consensus.
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil, false, 32, 32, big.NewInt(0), big.NewInt(0), nil}
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil, false, 32, 32, big.NewInt(0), big.NewInt(0), nil, nil}
TestChainConfig = &ChainConfig{big.NewInt(10), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, false, 32, 32, big.NewInt(0), big.NewInt(0), nil}
TestChainConfig = &ChainConfig{big.NewInt(10), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, false, 32, 32, big.NewInt(0), big.NewInt(0), nil, nil}
TestRules = TestChainConfig.Rules(new(big.Int))
QuorumTestChainConfig = &ChainConfig{big.NewInt(10), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, true, 64, 32, big.NewInt(0), big.NewInt(0), nil}
QuorumTestChainConfig = &ChainConfig{big.NewInt(10), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, true, 64, 32, big.NewInt(0), big.NewInt(0), nil, nil}
)
// TrustedCheckpoint represents a set of post-processed trie roots (CHT and
@ -318,6 +318,12 @@ type ChainConfig struct {
// to track multiple changes to maxCodeSize
MaxCodeSizeConfig []MaxCodeConfigStruct `json:"maxCodeSizeConfig,omitempty"`
// Quorum
BlockReward *BlockRewardConfig `json:"blockRewardConfig,omitempty"`
}
type BlockRewardConfig struct {
Contract common.Address `json:"contract,omitempty"` // Block reward contract address
}
// EthashConfig is the consensus engine configs for proof-of-work based sealing.