1
1
import { phase0 , ssz } from "@lodestar/types" ;
2
2
import { ChainForkConfig } from "@lodestar/config" ;
3
- import { BeaconStateAllForks , becomesNewEth1Data } from "@lodestar/state-transition" ;
3
+ import {
4
+ BeaconStateAllForks ,
5
+ CachedBeaconStateAllForks ,
6
+ CachedBeaconStateElectra ,
7
+ becomesNewEth1Data ,
8
+ } from "@lodestar/state-transition" ;
4
9
import { ErrorAborted , TimeoutError , fromHex , Logger , isErrorAborted , sleep } from "@lodestar/utils" ;
5
10
6
11
import { IBeaconDb } from "../db/index.js" ;
@@ -67,6 +72,8 @@ export class Eth1DepositDataTracker {
67
72
/** Dynamically adjusted batch size to fetch deposit logs */
68
73
private eth1GetLogsBatchSizeDynamic = MAX_BLOCKS_PER_LOG_QUERY ;
69
74
private readonly forcedEth1DataVote : phase0 . Eth1Data | null ;
75
+ /** To stop `runAutoUpdate()` in addition to AbortSignal */
76
+ private stopPolling : boolean ;
70
77
71
78
constructor (
72
79
opts : Eth1Options ,
@@ -81,6 +88,8 @@ export class Eth1DepositDataTracker {
81
88
this . depositsCache = new Eth1DepositsCache ( opts , config , db ) ;
82
89
this . eth1DataCache = new Eth1DataCache ( config , db ) ;
83
90
this . eth1FollowDistance = config . ETH1_FOLLOW_DISTANCE ;
91
+ // TODO Electra: fix scenario where node starts post-Electra and `stopPolling` will always be false
92
+ this . stopPolling = false ;
84
93
85
94
this . forcedEth1DataVote = opts . forcedEth1DataVote
86
95
? ssz . phase0 . Eth1Data . deserialize ( fromHex ( opts . forcedEth1DataVote ) )
@@ -109,10 +118,22 @@ export class Eth1DepositDataTracker {
109
118
}
110
119
}
111
120
121
+ // TODO Electra: Figure out how an elegant way to stop eth1data polling
122
+ stopPollingEth1Data ( ) : void {
123
+ this . stopPolling = true ;
124
+ }
125
+
112
126
/**
113
127
* Return eth1Data and deposits ready for block production for a given state
114
128
*/
115
- async getEth1DataAndDeposits ( state : BeaconStateAllForks ) : Promise < Eth1DataAndDeposits > {
129
+ async getEth1DataAndDeposits ( state : CachedBeaconStateAllForks ) : Promise < Eth1DataAndDeposits > {
130
+ if (
131
+ state . epochCtx . isAfterElectra ( ) &&
132
+ state . eth1DepositIndex >= ( state as CachedBeaconStateElectra ) . depositReceiptsStartIndex
133
+ ) {
134
+ // No need to poll eth1Data since Electra deprecates the mechanism after depositReceiptsStartIndex is reached
135
+ return { eth1Data : state . eth1Data , deposits : [ ] } ;
136
+ }
116
137
const eth1Data = this . forcedEth1DataVote ?? ( await this . getEth1Data ( state ) ) ;
117
138
const deposits = await this . getDeposits ( state , eth1Data ) ;
118
139
return { eth1Data, deposits} ;
@@ -141,7 +162,10 @@ export class Eth1DepositDataTracker {
141
162
* Returns deposits to be included for a given state and eth1Data vote.
142
163
* Requires internal caches to be updated regularly to return good results
143
164
*/
144
- private async getDeposits ( state : BeaconStateAllForks , eth1DataVote : phase0 . Eth1Data ) : Promise < phase0 . Deposit [ ] > {
165
+ private async getDeposits (
166
+ state : CachedBeaconStateAllForks ,
167
+ eth1DataVote : phase0 . Eth1Data
168
+ ) : Promise < phase0 . Deposit [ ] > {
145
169
// No new deposits have to be included, continue
146
170
if ( eth1DataVote . depositCount === state . eth1DepositIndex ) {
147
171
return [ ] ;
@@ -162,7 +186,7 @@ export class Eth1DepositDataTracker {
162
186
private async runAutoUpdate ( ) : Promise < void > {
163
187
let lastRunMs = 0 ;
164
188
165
- while ( ! this . signal . aborted ) {
189
+ while ( ! this . signal . aborted && ! this . stopPolling ) {
166
190
lastRunMs = Date . now ( ) ;
167
191
168
192
try {
0 commit comments