forked from erigontech/erigon
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathblock_building.go
More file actions
126 lines (105 loc) · 3.9 KB
/
block_building.go
File metadata and controls
126 lines (105 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright 2024 The Erigon Authors
// This file is part of Erigon.
//
// Erigon is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Erigon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Erigon. If not, see <http://www.gnu.org/licenses/>.
package execmodule
import (
"context"
"reflect"
"github.com/holiman/uint256"
"github.com/erigontech/erigon/common"
"github.com/erigontech/erigon/execution/builder"
"github.com/erigontech/erigon/execution/engineapi/engine_helpers"
"github.com/erigontech/erigon/execution/types"
"github.com/erigontech/erigon/rpc"
)
func (e *ExecModule) checkWithdrawalsPresence(time uint64, withdrawals []*types.Withdrawal) error {
if !e.config.IsShanghai(time) && withdrawals != nil {
return &rpc.InvalidParamsError{Message: "withdrawals before shanghai"}
}
if e.config.IsShanghai(time) && withdrawals == nil {
return &rpc.InvalidParamsError{Message: "missing withdrawals list"}
}
return nil
}
func (e *ExecModule) evictOldBuilders() {
ids := common.SortedKeys(e.builders)
// remove old builders so that at most MaxBuilders - 1 remain
for i := 0; i <= len(e.builders)-engine_helpers.MaxBuilders; i++ {
delete(e.builders, ids[i])
}
}
func (e *ExecModule) AssembleBlock(ctx context.Context, params *builder.Parameters) (AssembleBlockResult, error) {
if !e.semaphore.TryAcquire(1) {
return AssembleBlockResult{Busy: true}, nil
}
defer e.semaphore.Release(1)
if err := e.checkWithdrawalsPresence(params.Timestamp, params.Withdrawals); err != nil {
return AssembleBlockResult{}, err
}
// First check if we're already building a block with the requested parameters
if e.lastParameters != nil {
params.PayloadId = e.lastParameters.PayloadId
if reflect.DeepEqual(e.lastParameters, params) {
e.logger.Info("[ForkChoiceUpdated] duplicate build request")
return AssembleBlockResult{PayloadID: e.lastParameters.PayloadId}, nil
}
}
// Initiate payload building
e.evictOldBuilders()
e.nextPayloadId++
params.PayloadId = e.nextPayloadId
e.lastParameters = params
e.builders[e.nextPayloadId] = builder.NewBlockBuilder(e.builderFunc, params, e.config.SecondsPerSlot()/4)
e.logger.Info("[ForkChoiceUpdated] BlockBuilder added", "payload", e.nextPayloadId)
return AssembleBlockResult{PayloadID: e.nextPayloadId}, nil
}
// blockValue computes the expected value received by the fee recipient in wei.
func blockValue(br *types.BlockWithReceipts, baseFee *uint256.Int) *uint256.Int {
blockValue := uint256.NewInt(0)
txs := br.Block.Transactions()
var gas, txValue uint256.Int
for i := range txs {
gas.SetUint64(br.Receipts[i].GasUsed)
effectiveTip := txs[i].GetEffectiveGasTip(baseFee)
txValue.Mul(&gas, &effectiveTip)
blockValue.Add(blockValue, &txValue)
}
return blockValue
}
func (e *ExecModule) GetAssembledBlock(_ context.Context, payloadID uint64) (AssembledBlockResult, error) {
if !e.semaphore.TryAcquire(1) {
return AssembledBlockResult{Busy: true}, nil
}
defer e.semaphore.Release(1)
bldr, ok := e.builders[payloadID]
if !ok {
return AssembledBlockResult{}, nil
}
blockWithReceipts, err := bldr.Stop()
if err != nil {
e.logger.Error("Failed to build PoS block", "err", err)
return AssembledBlockResult{}, err
}
if blockWithReceipts == nil {
return AssembledBlockResult{}, nil
}
header := blockWithReceipts.Block.Header()
baseFee := header.BaseFee
value := blockValue(blockWithReceipts, baseFee)
return AssembledBlockResult{
Block: blockWithReceipts,
BlockValue: value,
}, nil
}