diff --git a/.gitmodules b/.gitmodules index 03d628bc9a..bbb3459091 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,4 +3,5 @@ url = https://github.com/ethereum/tests [submodule "genesis"] path = genesis - url = https://github.com/Ankr-network/bas-genesis-config.git + url = https://github.com/node-real/semita-bas-genesis-config + branch = semita_base diff --git a/consensus/consensus.go b/consensus/consensus.go index dadbc48418..2fdb696e80 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -145,4 +145,6 @@ type PoSA interface { EnoughDistance(chain ChainReader, header *types.Header) bool IsLocalBlock(header *types.Header) bool AllowLightProcess(chain ChainReader, currentHeader *types.Header) bool + + BlockRewards(blockNumber *big.Int) *big.Int } diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go index 54aa6f2bcf..fd16b66060 100644 --- a/consensus/parlia/parlia.go +++ b/consensus/parlia/parlia.go @@ -1051,41 +1051,50 @@ func (p *Parlia) getCurrentValidators(blockHash common.Hash) ([]common.Address, } return valz, nil } +func (p *Parlia) BlockRewards(blockNumber *big.Int) *big.Int { + if rules := p.chainConfig.Rules(blockNumber); rules.HasBlockRewards { + blockRewards := p.chainConfig.Parlia.BlockRewards + if blockRewards != nil && blockRewards.Cmp(common.Big0) > 0 { + return blockRewards + } + } + return nil +} // slash spoiled validators func (p *Parlia) distributeIncoming(val common.Address, state *state.StateDB, header *types.Header, chain core.ChainContext, txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool) error { coinbase := header.Coinbase balance := state.GetBalance(consensus.SystemAddress) - if balance.Cmp(common.Big0) <= 0 { - return nil - } state.SetBalance(consensus.SystemAddress, big.NewInt(0)) state.AddBalance(coinbase, balance) - if rules := p.chainConfig.Rules(header.Number); rules.HasBlockRewards { - blockRewards := p.chainConfig.Parlia.BlockRewards - // if we have enabled block rewards and rewards are greater than 0 then - if blockRewards != nil && blockRewards.Cmp(common.Big0) > 0 { - state.AddBalance(coinbase, blockRewards) - } - } - - doDistributeSysReward := state.GetBalance(common.HexToAddress(systemcontract.SystemRewardContract)).Cmp(maxSystemBalance) < 0 - if doDistributeSysReward { - var rewards = new(big.Int) - rewards = rewards.Rsh(balance, systemRewardPercent) - if rewards.Cmp(common.Big0) > 0 { - err := p.distributeToSystem(rewards, state, header, chain, txs, receipts, receivedTxs, usedGas, mining) - if err != nil { - return err + /* if balance.Cmp(common.Big0) > 0 { + doDistributeSysReward := state.GetBalance(common.HexToAddress(systemcontract.SystemRewardContract)).Cmp(maxSystemBalance) < 0 + if doDistributeSysReward { + var SysRewards = new(big.Int) + SysRewards = SysRewards.Rsh(balance, systemRewardPercent) + if SysRewards.Cmp(common.Big0) > 0 { + err := p.distributeToSystem(SysRewards, state, header, chain, txs, receipts, receivedTxs, usedGas, mining) + if err != nil { + return err + } + log.Trace("distribute to system reward pool", "block hash", header.Hash(), "amount", SysRewards) + balance = balance.Sub(balance, SysRewards) } - log.Trace("distribute to system reward pool", "block hash", header.Hash(), "amount", rewards) - balance = balance.Sub(balance, rewards) } + }*/ + rewards := big.NewInt(0).Abs(balance) + blockRewards := p.BlockRewards(header.Number) + if blockRewards != nil { + rewards = rewards.Add(rewards, blockRewards) + state.AddBalance(coinbase, blockRewards) + } + if rewards.Cmp(common.Big0) <= 0 { + return nil } - log.Trace("distribute to validator contract", "block hash", header.Hash(), "amount", balance) - return p.distributeToValidator(balance, val, state, header, chain, txs, receipts, receivedTxs, usedGas, mining) + log.Trace("distribute to validator contract", "block hash", header.Hash(), "amount", rewards) + return p.distributeToValidator(rewards, val, state, header, chain, txs, receipts, receivedTxs, usedGas, mining) } // slash spoiled validators diff --git a/eth/state_accessor.go b/eth/state_accessor.go index 24a0e776f6..16b97d4702 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -23,6 +23,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/systemcontract" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" @@ -201,6 +202,12 @@ func (eth *Ethereum) stateAtTransaction(block *types.Block, txIndex int, reexec statedb.SetBalance(consensus.SystemAddress, big.NewInt(0)) statedb.AddBalance(context.Coinbase, balance) } + if idx == len(block.Transactions())-1 && tx.To().Hex() == systemcontract.ValidatorContract { + blockRewards := posa.BlockRewards(block.Header().Number) + if blockRewards != nil { + statedb.AddBalance(context.Coinbase, blockRewards) + } + } } statedb.Prepare(tx.Hash(), block.Hash(), idx) if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil { diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 8ee2c22ffd..8df152fd0c 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/gopool" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common/systemcontract" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" @@ -281,6 +282,7 @@ func (api *API) traceChain(ctx context.Context, start, end *types.Block, config BlockHash: task.block.Hash(), TxIndex: i, TxHash: tx.Hash(), + TxCount: len(task.block.Transactions()), } res, err := api.traceTx(localctx, msg, txctx, blockCtx, task.statedb, config) if err != nil { @@ -540,7 +542,15 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config statedb.SetBalance(consensus.SystemAddress, big.NewInt(0)) statedb.AddBalance(vmctx.Coinbase, balance) } + if i == len(block.Transactions())-1 && tx.To().Hex() == systemcontract.ValidatorContract { + blockRewards := posa.BlockRewards(block.Header().Number) + if blockRewards != nil { + statedb.AddBalance(vmctx.Coinbase, blockRewards) + } + } + } + } statedb.Prepare(tx.Hash(), block.Hash(), i) @@ -621,6 +631,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac BlockHash: blockHash, TxIndex: task.index, TxHash: txs[task.index].Hash(), + TxCount: len(txs), } res, err := api.traceTx(ctx, msg, txctx, blockCtx, task.statedb, config) if err != nil { @@ -640,7 +651,6 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac // Generate the next state snapshot fast without tracing msg, _ := tx.AsMessage(signer) - if posa, ok := api.backend.Engine().(consensus.PoSA); ok { if isSystem, _ := posa.IsSystemTransaction(tx, block.Header()); isSystem { balance := statedb.GetBalance(consensus.SystemAddress) @@ -648,6 +658,12 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac statedb.SetBalance(consensus.SystemAddress, big.NewInt(0)) statedb.AddBalance(block.Header().Coinbase, balance) } + if i == len(txs)-1 && tx.To().Hex() == systemcontract.ValidatorContract { + blockRewards := posa.BlockRewards(block.Header().Number) + if blockRewards != nil { + statedb.AddBalance(block.Header().Coinbase, blockRewards) + } + } } } @@ -772,6 +788,12 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block statedb.SetBalance(consensus.SystemAddress, big.NewInt(0)) statedb.AddBalance(vmctx.Coinbase, balance) } + if i == len(block.Transactions())-1 && tx.To().Hex() == systemcontract.ValidatorContract { + blockRewards := posa.BlockRewards(block.Header().Number) + if blockRewards != nil { + statedb.AddBalance(vmctx.Coinbase, blockRewards) + } + } } } statedb.Prepare(tx.Hash(), block.Hash(), i) @@ -836,6 +858,7 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config * BlockHash: blockHash, TxIndex: int(index), TxHash: hash, + TxCount: len(block.Transactions()), } return api.traceTx(ctx, msg, txctx, vmctx, statedb, config) } @@ -938,6 +961,13 @@ func (api *API) traceTx(ctx context.Context, message core.Message, txctx *Contex statedb.SetBalance(consensus.SystemAddress, big.NewInt(0)) statedb.AddBalance(vmctx.Coinbase, balance) } + if txctx.TxIndex == txctx.TxCount-1 && message.To().Hex() == systemcontract.ValidatorContract { + blockRewards := posa.BlockRewards(vmctx.BlockNumber) + if blockRewards != nil { + statedb.AddBalance(vmctx.Coinbase, blockRewards) + } + } + } // Call Prepare to clear out the statedb access list diff --git a/eth/tracers/tracers.go b/eth/tracers/tracers.go index e7073e7d2e..e8fdc08f16 100644 --- a/eth/tracers/tracers.go +++ b/eth/tracers/tracers.go @@ -31,6 +31,7 @@ type Context struct { BlockHash common.Hash // Hash of the block the tx is contained within (zero if dangling tx or call) TxIndex int // Index of the transaction within a block (zero if dangling tx or call) TxHash common.Hash // Hash of the transaction being traced (zero if dangling call) + TxCount int } // Tracer interface extends vm.EVMLogger and additionally diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 371e7bbf36..1a02ec5efa 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -36,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/common/gopool" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/common/systemcontract" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/clique" "github.com/ethereum/go-ethereum/core" @@ -1197,7 +1198,7 @@ func (s *PublicBlockChainAPI) replay(ctx context.Context, block *types.Block, ac // Recompute transactions. signer := types.MakeSigner(s.b.ChainConfig(), block.Number()) - for _, tx := range block.Transactions() { + for i, tx := range block.Transactions() { // Skip data empty tx and to is one of the interested accounts tx. skip := false if len(tx.Data()) == 0 { @@ -1233,6 +1234,12 @@ func (s *PublicBlockChainAPI) replay(ctx context.Context, block *types.Block, ac statedb.SetBalance(consensus.SystemAddress, big.NewInt(0)) statedb.AddBalance(block.Header().Coinbase, balance) } + if i == len(block.Transactions())-1 && tx.To().Hex() == systemcontract.ValidatorContract { + blockRewards := posa.BlockRewards(block.Header().Number) + if blockRewards != nil { + statedb.AddBalance(context.Coinbase, blockRewards) + } + } } }