Skip to content

Commit

Permalink
Implement block reward contract feature
Browse files Browse the repository at this point in the history
  • Loading branch information
k1rill-fedoseev committed Jun 13, 2020
1 parent d205bdb commit 0e922bd
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
38 changes: 38 additions & 0 deletions core/state_processor.go
Expand Up @@ -17,13 +17,19 @@
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"
"github.com/ethereum/go-ethereum/core/state"
"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"
)

Expand Down Expand Up @@ -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())

Expand Down Expand Up @@ -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])
}
}
5 changes: 5 additions & 0 deletions miner/worker.go
Expand Up @@ -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
Expand Down
14 changes: 10 additions & 4 deletions params/config.go
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 0e922bd

Please sign in to comment.