Skip to content

Commit b8fa40e

Browse files
authored
Merge pull request #21 from ethpandaops/electra-support
electra support
2 parents 281083d + 0061b99 commit b8fa40e

File tree

70 files changed

+6867
-270
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+6867
-270
lines changed

go.mod

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ require (
2121
github.com/prometheus/client_golang v1.20.5
2222
github.com/protolambda/zrnt v0.32.3
2323
github.com/protolambda/ztyp v0.2.2
24+
github.com/prysmaticlabs/go-bitfield v0.0.0-20240618144021-706c95b2dd15
2425
github.com/rs/zerolog v1.33.0
2526
github.com/sirupsen/logrus v1.9.3
2627
github.com/spf13/cobra v1.8.1
@@ -85,7 +86,6 @@ require (
8586
github.com/prometheus/common v0.55.0 // indirect
8687
github.com/prometheus/procfs v0.15.1 // indirect
8788
github.com/protolambda/bls12-381-util v0.1.0 // indirect
88-
github.com/prysmaticlabs/go-bitfield v0.0.0-20240618144021-706c95b2dd15 // indirect
8989
github.com/r3labs/sse/v2 v2.10.0 // indirect
9090
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
9191
github.com/sethvargo/go-retry v0.3.0 // indirect
@@ -120,3 +120,7 @@ require (
120120
modernc.org/sqlite v1.34.1 // indirect
121121
rsc.io/tmplfunc v0.0.3 // indirect
122122
)
123+
124+
replace github.com/attestantio/go-eth2-client => github.com/attestantio/go-eth2-client v0.0.0-20241006200801-8fa702e3a895
125+
126+
replace github.com/ethereum/go-ethereum => github.com/lightclient/go-ethereum v0.0.0-20241202183034-866f8c3515d2

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo
88
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
99
github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI=
1010
github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI=
11-
github.com/attestantio/go-eth2-client v0.21.11 h1:0ZYP69O8rJz41055WOf3n1C1NA4jNh2iME/NuTVfgmQ=
12-
github.com/attestantio/go-eth2-client v0.21.11/go.mod h1:d7ZPNrMX8jLfIgML5u7QZxFo2AukLM+5m08iMaLdqb8=
11+
github.com/attestantio/go-eth2-client v0.0.0-20241006200801-8fa702e3a895 h1:SCPPFhrZXcr4VbQWy1EwBZyHEIL0rTpL8itkWwfY4pM=
12+
github.com/attestantio/go-eth2-client v0.0.0-20241006200801-8fa702e3a895/go.mod h1:vy5jU/uDZ2+RcVzq5BfnG+bQ3/6uu9DGwCrGsPtjJ1A=
1313
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
1414
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
1515
github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE=
@@ -58,8 +58,6 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
5858
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
5959
github.com/ethereum/c-kzg-4844 v1.0.2 h1:8tV84BCEiPeOkiVgW9mpYBeBUir2bkCNVqxPwwVeO+s=
6060
github.com/ethereum/c-kzg-4844 v1.0.2/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0=
61-
github.com/ethereum/go-ethereum v1.14.12 h1:8hl57x77HSUo+cXExrURjU/w1VhL+ShCTJrTwcCQSe4=
62-
github.com/ethereum/go-ethereum v1.14.12/go.mod h1:RAC2gVMWJ6FkxSPESfbshrcKpIokgQKsVKmAuqdekDY=
6361
github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A=
6462
github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk=
6563
github.com/ethpandaops/ethwallclock v0.3.0 h1:xF5fwtBf+bHFHZKBnwiPFEuelW3sMM7SD3ZNFq1lJY4=
@@ -180,6 +178,8 @@ github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
180178
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
181179
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
182180
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
181+
github.com/lightclient/go-ethereum v0.0.0-20241202183034-866f8c3515d2 h1:E6i8cKFlRnrvPVdcUJ/v64SKbRs1+JPciDWCwQZCSGg=
182+
github.com/lightclient/go-ethereum v0.0.0-20241202183034-866f8c3515d2/go.mod h1:ZmZcHTeyZmlgwxeJPCvDLRneKZNELdbqOY9XzZwO9Gg=
183183
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
184184
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
185185
github.com/mashingan/smapping v0.1.19 h1:SsEtuPn2UcM1croIupPtGLgWgpYRuS0rSQMvKD9g2BQ=

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func main() {
3434
select {
3535
case <-runChan:
3636
// graceful shutdown completed
37-
case <-time.After(5 * time.Second):
37+
case <-time.After(30 * time.Second):
3838
log.Println("Graceful shutdown timed out")
3939
}
4040
}

pkg/coordinator/clients/consensus/chainspec.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type ChainSpec struct {
2727
CappellaForkEpoch uint64 `yaml:"CAPELLA_FORK_EPOCH"`
2828
SecondsPerSlot time.Duration `yaml:"SECONDS_PER_SLOT"`
2929
SlotsPerEpoch uint64 `yaml:"SLOTS_PER_EPOCH"`
30+
MaxCommitteesPerSlot uint64 `yaml:"MAX_COMMITTEES_PER_SLOT"`
3031
}
3132

3233
func (chain *ChainSpec) CheckMismatch(chain2 *ChainSpec) []string {

pkg/coordinator/clients/execution/block.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type Block struct {
1717
blockChan chan bool
1818
block *types.Block
1919
seenMutex sync.RWMutex
20+
seenChan chan bool
2021
seenMap map[uint16]*Client
2122
}
2223

@@ -40,6 +41,41 @@ func (block *Block) SetSeenBy(client *Client) {
4041
block.seenMutex.Lock()
4142
defer block.seenMutex.Unlock()
4243
block.seenMap[client.clientIdx] = client
44+
45+
if block.seenChan != nil {
46+
close(block.seenChan)
47+
}
48+
}
49+
50+
func (block *Block) AwaitSeenBy(ctx context.Context, client *Client) bool {
51+
if ctx == nil {
52+
ctx = context.Background()
53+
}
54+
55+
for {
56+
seen, seenChan := block.checkSeenBy(client)
57+
if seen {
58+
return true
59+
}
60+
61+
select {
62+
case <-seenChan:
63+
case <-ctx.Done():
64+
return false
65+
}
66+
}
67+
}
68+
69+
func (block *Block) checkSeenBy(client *Client) (seen bool, seenChan chan bool) {
70+
block.seenMutex.RLock()
71+
defer block.seenMutex.RUnlock()
72+
73+
_, ok := block.seenMap[client.clientIdx]
74+
if !ok && block.seenChan == nil {
75+
block.seenChan = make(chan bool)
76+
}
77+
78+
return ok, block.seenChan
4379
}
4480

4581
func (block *Block) GetBlock() *types.Block {

pkg/coordinator/clients/execution/pool.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package execution
33
import (
44
"context"
55
"fmt"
6+
"math/rand"
67
"sync"
78
"time"
89

@@ -86,7 +87,7 @@ func (pool *Pool) GetAllEndpoints() []*Client {
8687
}
8788

8889
func (pool *Pool) GetReadyEndpoint(clientType ClientType) *Client {
89-
readyClients := pool.GetReadyEndpoints()
90+
readyClients := pool.GetReadyEndpoints(true)
9091
selectedClient := pool.runClientScheduler(readyClients, clientType)
9192

9293
return selectedClient
@@ -107,7 +108,7 @@ func (pool *Pool) AwaitReadyEndpoint(ctx context.Context, clientType ClientType)
107108
}
108109
}
109110

110-
func (pool *Pool) GetReadyEndpoints() []*Client {
111+
func (pool *Pool) GetReadyEndpoints(shuffle bool) []*Client {
111112
canonicalFork := pool.GetCanonicalFork(-1)
112113
if canonicalFork == nil {
113114
return nil
@@ -118,6 +119,17 @@ func (pool *Pool) GetReadyEndpoints() []*Client {
118119
return nil
119120
}
120121

122+
if shuffle {
123+
shuffledClients := make([]*Client, len(readyClients))
124+
perm := rand.Perm(len(readyClients))
125+
126+
for i, v := range perm {
127+
shuffledClients[v] = readyClients[i]
128+
}
129+
130+
return shuffledClients
131+
}
132+
121133
return readyClients
122134
}
123135

pkg/coordinator/clients/execution/rpc/executionapi.go

Lines changed: 111 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ package rpc
22

33
import (
44
"context"
5+
"fmt"
56
"math/big"
7+
"time"
8+
9+
"github.com/ethereum/go-ethereum"
610

711
"github.com/ethereum/go-ethereum/common"
812
"github.com/ethereum/go-ethereum/core/types"
@@ -11,21 +15,28 @@ import (
1115
)
1216

1317
type ExecutionClient struct {
14-
name string
15-
endpoint string
16-
headers map[string]string
17-
rpcClient *rpc.Client
18-
ethClient *ethclient.Client
18+
name string
19+
endpoint string
20+
headers map[string]string
21+
rpcClient *rpc.Client
22+
ethClient *ethclient.Client
23+
concurrencyLimit int
24+
requestTimeout time.Duration
25+
concurrencyChan chan struct{}
1926
}
2027

2128
// NewExecutionClient is used to create a new execution client
2229
func NewExecutionClient(name, url string, headers map[string]string) (*ExecutionClient, error) {
2330
client := &ExecutionClient{
24-
name: name,
25-
endpoint: url,
26-
headers: headers,
31+
name: name,
32+
endpoint: url,
33+
headers: headers,
34+
concurrencyLimit: 50,
35+
requestTimeout: 30 * time.Second,
2736
}
2837

38+
client.concurrencyChan = make(chan struct{}, client.concurrencyLimit)
39+
2940
return client, nil
3041
}
3142

@@ -49,6 +60,17 @@ func (ec *ExecutionClient) Initialize(ctx context.Context) error {
4960
return nil
5061
}
5162

63+
func (ec *ExecutionClient) enforceConcurrencyLimit(ctx context.Context) func() {
64+
select {
65+
case <-ctx.Done():
66+
return func() {}
67+
case ec.concurrencyChan <- struct{}{}:
68+
return func() {
69+
<-ec.concurrencyChan
70+
}
71+
}
72+
}
73+
5274
func (ec *ExecutionClient) GetEthClient() *ethclient.Client {
5375
return ec.ethClient
5476
}
@@ -77,7 +99,7 @@ func (ec *ExecutionClient) GetNodeSyncing(ctx context.Context) (*SyncStatus, err
7799
return nil, err
78100
}
79101

80-
if status == nil && err == nil {
102+
if status == nil {
81103
// Not syncing
82104
ss := &SyncStatus{}
83105
ss.IsSyncing = false
@@ -94,7 +116,10 @@ func (ec *ExecutionClient) GetNodeSyncing(ctx context.Context) (*SyncStatus, err
94116
}
95117

96118
func (ec *ExecutionClient) GetLatestBlock(ctx context.Context) (*types.Block, error) {
97-
block, err := ec.ethClient.BlockByNumber(ctx, nil)
119+
reqCtx, reqCtxCancel := context.WithTimeout(ctx, ec.requestTimeout)
120+
defer reqCtxCancel()
121+
122+
block, err := ec.ethClient.BlockByNumber(reqCtx, nil)
98123
if err != nil {
99124
return nil, err
100125
}
@@ -103,7 +128,10 @@ func (ec *ExecutionClient) GetLatestBlock(ctx context.Context) (*types.Block, er
103128
}
104129

105130
func (ec *ExecutionClient) GetBlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
106-
block, err := ec.ethClient.BlockByHash(ctx, hash)
131+
reqCtx, reqCtxCancel := context.WithTimeout(ctx, ec.requestTimeout)
132+
defer reqCtxCancel()
133+
134+
block, err := ec.ethClient.BlockByHash(reqCtx, hash)
107135
if err != nil {
108136
return nil, err
109137
}
@@ -112,17 +140,85 @@ func (ec *ExecutionClient) GetBlockByHash(ctx context.Context, hash common.Hash)
112140
}
113141

114142
func (ec *ExecutionClient) GetNonceAt(ctx context.Context, wallet common.Address, blockNumber *big.Int) (uint64, error) {
115-
return ec.ethClient.NonceAt(ctx, wallet, blockNumber)
143+
closeFn := ec.enforceConcurrencyLimit(ctx)
144+
if closeFn == nil {
145+
return 0, fmt.Errorf("client busy")
146+
}
147+
148+
defer closeFn()
149+
150+
reqCtx, reqCtxCancel := context.WithTimeout(ctx, ec.requestTimeout)
151+
defer reqCtxCancel()
152+
153+
return ec.ethClient.NonceAt(reqCtx, wallet, blockNumber)
116154
}
117155

118156
func (ec *ExecutionClient) GetBalanceAt(ctx context.Context, wallet common.Address, blockNumber *big.Int) (*big.Int, error) {
119-
return ec.ethClient.BalanceAt(ctx, wallet, blockNumber)
157+
closeFn := ec.enforceConcurrencyLimit(ctx)
158+
if closeFn == nil {
159+
return nil, fmt.Errorf("client busy")
160+
}
161+
162+
defer closeFn()
163+
164+
reqCtx, reqCtxCancel := context.WithTimeout(ctx, ec.requestTimeout)
165+
defer reqCtxCancel()
166+
167+
return ec.ethClient.BalanceAt(reqCtx, wallet, blockNumber)
120168
}
121169

122170
func (ec *ExecutionClient) GetTransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
123-
return ec.ethClient.TransactionReceipt(ctx, txHash)
171+
closeFn := ec.enforceConcurrencyLimit(ctx)
172+
if closeFn == nil {
173+
return nil, fmt.Errorf("client busy")
174+
}
175+
176+
defer closeFn()
177+
178+
reqCtx, reqCtxCancel := context.WithTimeout(ctx, ec.requestTimeout)
179+
defer reqCtxCancel()
180+
181+
return ec.ethClient.TransactionReceipt(reqCtx, txHash)
182+
}
183+
184+
func (ec *ExecutionClient) GetBlockReceipts(ctx context.Context, blockHash common.Hash) ([]*types.Receipt, error) {
185+
closeFn := ec.enforceConcurrencyLimit(ctx)
186+
if closeFn == nil {
187+
return nil, fmt.Errorf("client busy")
188+
}
189+
190+
defer closeFn()
191+
192+
reqCtx, reqCtxCancel := context.WithTimeout(ctx, ec.requestTimeout)
193+
defer reqCtxCancel()
194+
195+
return ec.ethClient.BlockReceipts(reqCtx, rpc.BlockNumberOrHash{
196+
BlockHash: &blockHash,
197+
})
124198
}
125199

126200
func (ec *ExecutionClient) SendTransaction(ctx context.Context, tx *types.Transaction) error {
127-
return ec.ethClient.SendTransaction(ctx, tx)
201+
closeFn := ec.enforceConcurrencyLimit(ctx)
202+
if closeFn == nil {
203+
return fmt.Errorf("client busy")
204+
}
205+
206+
defer closeFn()
207+
208+
reqCtx, reqCtxCancel := context.WithTimeout(ctx, ec.requestTimeout)
209+
defer reqCtxCancel()
210+
211+
return ec.ethClient.SendTransaction(reqCtx, tx)
212+
}
213+
214+
//nolint:gocritic // ignore
215+
func (ec *ExecutionClient) GetEthCall(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
216+
closeFn := ec.enforceConcurrencyLimit(ctx)
217+
if closeFn == nil {
218+
return nil, fmt.Errorf("client busy")
219+
}
220+
221+
defer closeFn()
222+
223+
return ec.ethClient.CallContract(ctx, msg, blockNumber)
128224
}

0 commit comments

Comments
 (0)