mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
blockValue should use gasUsed rather than gasLimit (#6875)
Fees going to the gas fee recipient should be based on the actual gas used (available in the receipt) rather than the gas limit in a transaction. This fixes Hive test "GetPayloadV2 Block Value". Also `engine_getPayloadBodiesByRangeV1` params should be encoded as hex strings.
This commit is contained in:
parent
add5f80f43
commit
58fcc04575
@ -489,7 +489,7 @@ func NewBackend(stack *node.Node, config *ethconfig.Config, logger log.Logger) (
|
||||
}
|
||||
|
||||
// proof-of-stake mining
|
||||
assembleBlockPOS := func(param *core.BlockBuilderParameters, interrupt *int32) (*types.Block, error) {
|
||||
assembleBlockPOS := func(param *core.BlockBuilderParameters, interrupt *int32) (*types.BlockWithReceipts, error) {
|
||||
miningStatePos := stagedsync.NewProposingState(&config.Miner)
|
||||
miningStatePos.MiningConfig.Etherbase = param.SuggestedFeeRecipient
|
||||
proposingSync := stagedsync.New(
|
||||
|
@ -85,7 +85,7 @@ type EngineAPI interface {
|
||||
GetPayloadV2(ctx context.Context, payloadID hexutil.Bytes) (*GetPayloadV2Response, error)
|
||||
ExchangeTransitionConfigurationV1(ctx context.Context, transitionConfiguration *TransitionConfiguration) (*TransitionConfiguration, error)
|
||||
GetPayloadBodiesByHashV1(ctx context.Context, hashes []common.Hash) ([]*ExecutionPayloadBodyV1, error)
|
||||
GetPayloadBodiesByRangeV1(ctx context.Context, start uint64, count uint64) ([]*ExecutionPayloadBodyV1, error)
|
||||
GetPayloadBodiesByRangeV1(ctx context.Context, start, count hexutil.Uint64) ([]*ExecutionPayloadBodyV1, error)
|
||||
}
|
||||
|
||||
// EngineImpl is implementation of the EngineAPI interface
|
||||
@ -384,7 +384,7 @@ func (e *EngineImpl) GetPayloadBodiesByHashV1(ctx context.Context, hashes []comm
|
||||
return convertExecutionPayloadV1(apiRes), nil
|
||||
}
|
||||
|
||||
func (e *EngineImpl) GetPayloadBodiesByRangeV1(ctx context.Context, start uint64, count uint64) ([]*ExecutionPayloadBodyV1, error) {
|
||||
func (e *EngineImpl) GetPayloadBodiesByRangeV1(ctx context.Context, start, count hexutil.Uint64) ([]*ExecutionPayloadBodyV1, error) {
|
||||
if start == 0 || count == 0 {
|
||||
return nil, &rpc.InvalidParamsError{Message: fmt.Sprintf("invalid start or count, start: %v count: %v", start, count)}
|
||||
}
|
||||
@ -392,7 +392,7 @@ func (e *EngineImpl) GetPayloadBodiesByRangeV1(ctx context.Context, start uint64
|
||||
return nil, &privateapi.TooLargeRequestErr
|
||||
}
|
||||
|
||||
apiRes, err := e.api.EngineGetPayloadBodiesByRangeV1(ctx, &remote.EngineGetPayloadBodiesByRangeV1Request{Start: start, Count: count})
|
||||
apiRes, err := e.api.EngineGetPayloadBodiesByRangeV1(ctx, &remote.EngineGetPayloadBodiesByRangeV1Request{Start: uint64(start), Count: uint64(count)})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1782,3 +1782,8 @@ func DecodeOnlyTxMetadataFromBody(payload []byte) (baseTxId uint64, txAmount uin
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type BlockWithReceipts struct {
|
||||
Block *Block
|
||||
Receipts Receipts
|
||||
}
|
||||
|
@ -514,7 +514,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere
|
||||
}
|
||||
|
||||
// proof-of-stake mining
|
||||
assembleBlockPOS := func(param *core.BlockBuilderParameters, interrupt *int32) (*types.Block, error) {
|
||||
assembleBlockPOS := func(param *core.BlockBuilderParameters, interrupt *int32) (*types.BlockWithReceipts, error) {
|
||||
miningStatePos := stagedsync.NewProposingState(&config.Miner)
|
||||
miningStatePos.MiningConfig.Etherbase = param.SuggestedFeeRecipient
|
||||
proposingSync := stagedsync.New(
|
||||
|
@ -38,7 +38,7 @@ type MiningState struct {
|
||||
MiningConfig *params.MiningConfig
|
||||
PendingResultCh chan *types.Block
|
||||
MiningResultCh chan *types.Block
|
||||
MiningResultPOSCh chan *types.Block
|
||||
MiningResultPOSCh chan *types.BlockWithReceipts
|
||||
MiningBlock *MiningBlock
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ func NewProposingState(cfg *params.MiningConfig) MiningState {
|
||||
MiningConfig: cfg,
|
||||
PendingResultCh: make(chan *types.Block, 1),
|
||||
MiningResultCh: make(chan *types.Block, 1),
|
||||
MiningResultPOSCh: make(chan *types.Block, 1),
|
||||
MiningResultPOSCh: make(chan *types.BlockWithReceipts, 1),
|
||||
MiningBlock: &MiningBlock{},
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ func SpawnMiningFinishStage(s *StageState, tx kv.RwTx, cfg MiningFinishCfg, quit
|
||||
//}
|
||||
|
||||
block := types.NewBlock(current.Header, current.Txs, current.Uncles, current.Receipts, current.Withdrawals)
|
||||
blockWithReceipts := &types.BlockWithReceipts{Block: block, Receipts: current.Receipts}
|
||||
*current = MiningBlock{} // hack to clean global data
|
||||
|
||||
//sealHash := engine.SealHash(block.Header())
|
||||
@ -56,7 +57,7 @@ func SpawnMiningFinishStage(s *StageState, tx kv.RwTx, cfg MiningFinishCfg, quit
|
||||
//prev = sealHash
|
||||
|
||||
if cfg.miningState.MiningResultPOSCh != nil {
|
||||
cfg.miningState.MiningResultPOSCh <- block
|
||||
cfg.miningState.MiningResultPOSCh <- blockWithReceipts
|
||||
return nil
|
||||
}
|
||||
// Tests may set pre-calculated nonce
|
||||
|
@ -517,11 +517,12 @@ func (s *EthBackendServer) getQuickPayloadStatusIfPossible(blockHash libcommon.H
|
||||
}
|
||||
|
||||
// The expected value to be received by the feeRecipient in wei
|
||||
func blockValue(block *types.Block, baseFee *uint256.Int) *uint256.Int {
|
||||
func blockValue(br *types.BlockWithReceipts, baseFee *uint256.Int) *uint256.Int {
|
||||
blockValue := uint256.NewInt(0)
|
||||
for _, tx := range block.Transactions() {
|
||||
gas := new(uint256.Int).SetUint64(tx.GetGas())
|
||||
effectiveTip := tx.GetEffectiveGasTip(baseFee)
|
||||
txs := br.Block.Transactions()
|
||||
for i := range txs {
|
||||
gas := new(uint256.Int).SetUint64(br.Receipts[i].GasUsed)
|
||||
effectiveTip := txs[i].GetEffectiveGasTip(baseFee)
|
||||
txValue := new(uint256.Int).Mul(gas, effectiveTip)
|
||||
blockValue.Add(blockValue, txValue)
|
||||
}
|
||||
@ -549,11 +550,12 @@ func (s *EthBackendServer) EngineGetPayload(ctx context.Context, req *remote.Eng
|
||||
return nil, &UnknownPayloadErr
|
||||
}
|
||||
|
||||
block, err := builder.Stop()
|
||||
blockWithReceipts, err := builder.Stop()
|
||||
if err != nil {
|
||||
log.Error("Failed to build PoS block", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
block := blockWithReceipts.Block
|
||||
|
||||
baseFee := new(uint256.Int)
|
||||
baseFee.SetFromBig(block.Header().BaseFee)
|
||||
@ -585,7 +587,7 @@ func (s *EthBackendServer) EngineGetPayload(ctx context.Context, req *remote.Eng
|
||||
payload.Withdrawals = ConvertWithdrawalsToRpc(block.Withdrawals())
|
||||
}
|
||||
|
||||
blockValue := blockValue(block, baseFee)
|
||||
blockValue := blockValue(blockWithReceipts, baseFee)
|
||||
return &remote.EngineGetPayloadResponse{
|
||||
ExecutionPayload: payload,
|
||||
BlockValue: gointerfaces.ConvertUint256IntToH256(blockValue),
|
||||
|
@ -5,60 +5,65 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
|
||||
"github.com/ledgerwatch/erigon/core"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
)
|
||||
|
||||
type BlockBuilderFunc func(param *core.BlockBuilderParameters, interrupt *int32) (*types.Block, error)
|
||||
type BlockBuilderFunc func(param *core.BlockBuilderParameters, interrupt *int32) (*types.BlockWithReceipts, error)
|
||||
|
||||
// BlockBuilder wraps a goroutine that builds Proof-of-Stake payloads (PoS "mining")
|
||||
type BlockBuilder struct {
|
||||
interrupt int32
|
||||
syncCond *sync.Cond
|
||||
block *types.Block
|
||||
result *types.BlockWithReceipts
|
||||
err error
|
||||
}
|
||||
|
||||
func NewBlockBuilder(build BlockBuilderFunc, param *core.BlockBuilderParameters) *BlockBuilder {
|
||||
b := new(BlockBuilder)
|
||||
b.syncCond = sync.NewCond(new(sync.Mutex))
|
||||
builder := new(BlockBuilder)
|
||||
builder.syncCond = sync.NewCond(new(sync.Mutex))
|
||||
|
||||
go func() {
|
||||
log.Info("Building block...")
|
||||
t := time.Now()
|
||||
block, err := build(param, &b.interrupt)
|
||||
result, err := build(param, &builder.interrupt)
|
||||
if err != nil {
|
||||
log.Warn("Failed to build a block", "err", err)
|
||||
} else {
|
||||
block := result.Block
|
||||
log.Info("Built block", "hash", block.Hash(), "height", block.NumberU64(), "txs", len(block.Transactions()), "gas used %", 100*float64(block.GasUsed())/float64(block.GasLimit()), "time", time.Since(t))
|
||||
}
|
||||
|
||||
b.syncCond.L.Lock()
|
||||
defer b.syncCond.L.Unlock()
|
||||
b.block = block
|
||||
b.err = err
|
||||
b.syncCond.Broadcast()
|
||||
builder.syncCond.L.Lock()
|
||||
defer builder.syncCond.L.Unlock()
|
||||
builder.result = result
|
||||
builder.err = err
|
||||
builder.syncCond.Broadcast()
|
||||
}()
|
||||
|
||||
return b
|
||||
return builder
|
||||
}
|
||||
|
||||
func (b *BlockBuilder) Stop() (*types.Block, error) {
|
||||
func (b *BlockBuilder) Stop() (*types.BlockWithReceipts, error) {
|
||||
atomic.StoreInt32(&b.interrupt, 1)
|
||||
|
||||
b.syncCond.L.Lock()
|
||||
defer b.syncCond.L.Unlock()
|
||||
for b.block == nil && b.err == nil {
|
||||
for b.result == nil && b.err == nil {
|
||||
b.syncCond.Wait()
|
||||
}
|
||||
|
||||
return b.block, b.err
|
||||
return b.result, b.err
|
||||
}
|
||||
|
||||
func (b *BlockBuilder) Block() *types.Block {
|
||||
b.syncCond.L.Lock()
|
||||
defer b.syncCond.L.Unlock()
|
||||
|
||||
return b.block
|
||||
if b.result == nil {
|
||||
return nil
|
||||
}
|
||||
return b.result.Block
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user