99 "github.com/ethereum/go-ethereum/accounts/abi/bind"
1010 "github.com/rocket-pool/smartnode/bindings/megapool"
1111 "github.com/rocket-pool/smartnode/bindings/rocketpool"
12- "github.com/rocket-pool/smartnode/bindings/types"
1312 "github.com/rocket-pool/smartnode/bindings/utils/eth"
1413 "github.com/urfave/cli"
1514
@@ -19,8 +18,6 @@ import (
1918 rpgas "github.com/rocket-pool/smartnode/shared/services/gas"
2019 "github.com/rocket-pool/smartnode/shared/services/state"
2120 "github.com/rocket-pool/smartnode/shared/services/wallet"
22- apitypes "github.com/rocket-pool/smartnode/shared/types/api"
23- "github.com/rocket-pool/smartnode/shared/types/eth2"
2421 "github.com/rocket-pool/smartnode/shared/utils/api"
2522 "github.com/rocket-pool/smartnode/shared/utils/log"
2623)
@@ -119,58 +116,56 @@ func (t *notifyFinalBalance) run(state *state.NetworkState) error {
119116 return err
120117 }
121118
122- // Check if the megapool is deployed
123- deployed , err := megapool .GetMegapoolDeployed (t .rp , nodeAccount .Address , opts )
124- if err != nil {
125- return err
119+ nodeDetails , exists := state .NodeDetailsByAddress [nodeAccount .Address ]
120+ if ! exists {
121+ return fmt .Errorf ("node account %s not found in state" , nodeAccount .Address .Hex ())
126122 }
127- if ! deployed {
123+
124+ if ! nodeDetails .MegapoolDeployed {
128125 return nil
129126 }
130127
131- // Get the megapool address
132- megapoolAddress , err := megapool .GetMegapoolExpectedAddress (t .rp , nodeAccount .Address , opts )
133- if err != nil {
134- return err
135- }
128+ megapoolAddress := nodeDetails .MegapoolAddress
136129
137- // Load the megapool
138130 mp , err := megapool .NewMegaPoolV1 (t .rp , megapoolAddress , nil )
139131 if err != nil {
140132 return err
141133 }
142134
143- // Iterate over megapool validators checking whether they're ready to submit a final balance proof
144- validatorCount , err := mp .GetValidatorCount (nil )
145- if err != nil {
146- return err
147- }
148- validatorInfo , err := services .GetMegapoolValidatorDetails (t .rp , t .bc , mp , megapoolAddress , uint32 (validatorCount ), opts )
149- if err != nil {
150- return err
135+ validatorDetailsToProve := make (map [uint32 ]beacon.ValidatorStatus )
136+ pubkeys := state .MegapoolToPubkeysMap [megapoolAddress ]
137+ for _ , pubkey := range pubkeys {
138+ validatorDetails , exists := state .MegapoolValidatorDetails [pubkey ]
139+ if ! exists {
140+ return fmt .Errorf ("validator %s not found in state" , pubkey .Hex ())
141+ }
142+
143+ validatorInfo := state .MegapoolValidatorInfo [pubkey ]
144+
145+ if validatorDetails .Status == beacon .ValidatorState_WithdrawalDone && validatorInfo .ValidatorInfo .Exiting && ! validatorInfo .ValidatorInfo .Exited && validatorDetails .EffectiveBalance == 0 {
146+ validatorDetailsToProve [validatorInfo .ValidatorId ] = validatorDetails
147+ }
151148 }
152149
153- // Get the beacon state
154- beaconState , err := services .GetBeaconState (t .bc )
155- if err != nil {
156- return err
150+ // Check if there are any validators to notify
151+ if len (validatorDetailsToProve ) == 0 {
152+ return nil
157153 }
158154
159- for i := uint32 ( 0 ); i < uint32 ( validatorCount ); i ++ {
160- if validatorInfo [ i ]. BeaconStatus . Status == "withdrawal_done" && validatorInfo [ i ]. Exiting && ! validatorInfo [ i ]. Exited && validatorInfo [ i ]. BeaconStatus . EffectiveBalance == 0 {
161- // Log
162- t .log .Printlnf ("The validator ID %d needs a final balance proof" , validatorInfo [ i ]. ValidatorId )
155+ // Notify the validators
156+ for validatorId , validatorDetails := range validatorDetailsToProve {
157+ // Log
158+ t .log .Printlnf ("The validator id %d needs a final balance proof" , validatorId )
163159
164- t .createFinalBalanceProof (t .rp , mp , validatorInfo [i ], state , types .ValidatorPubkey (validatorInfo [i ].PubKey ), beaconState , opts )
165- }
160+ t .createFinalBalanceProof (t .rp , mp , state , validatorId , validatorDetails , opts )
166161 }
167162
168163 // Return
169164 return nil
170165
171166}
172167
173- func (t * notifyFinalBalance ) createFinalBalanceProof (rp * rocketpool.RocketPool , mp megapool.Megapool , validatorInfo apitypes. MegapoolValidatorDetails , state * state.NetworkState , validatorPubkey types. ValidatorPubkey , beaconState eth2. BeaconState , callopts * bind.CallOpts ) error {
168+ func (t * notifyFinalBalance ) createFinalBalanceProof (rp * rocketpool.RocketPool , mp megapool.Megapool , state * state.NetworkState , validatorId uint32 , validatorDetails beacon. ValidatorStatus , callopts * bind.CallOpts ) error {
174169
175170 // Get transactor
176171 opts , err := t .w .GetNodeAccountTransactor ()
@@ -180,7 +175,7 @@ func (t *notifyFinalBalance) createFinalBalanceProof(rp *rocketpool.RocketPool,
180175
181176 t .log .Printlnf ("Crafting a final balance proof. This process can take several seconds and is CPU and memory intensive. If you don't see a [FINISHED] log entry your system may not have enough resources to perform this operation." )
182177
183- validatorIndexStr , err := t .bc .GetValidatorIndex (validatorPubkey )
178+ validatorIndexStr , err := t .bc .GetValidatorIndex (validatorDetails . Pubkey )
184179 if err != nil {
185180 return err
186181 }
@@ -190,15 +185,15 @@ func (t *notifyFinalBalance) createFinalBalanceProof(rp *rocketpool.RocketPool,
190185 return err
191186 }
192187
193- slot := validatorInfo .WithdrawableEpoch * 32
188+ slot := validatorDetails .WithdrawableEpoch * 32
194189
195190 withdrawalProof , proofSlot , stateUsed , err := services .GetWithdrawalProofForSlot (t .c , slot , validatorIndex )
196191 if err != nil {
197- return fmt .Errorf ("error getting withdrawal proof for validator 0x%s (index: %d): %w" , validatorPubkey .String (), validatorIndex , err )
192+ return fmt .Errorf ("error getting withdrawal proof for validator 0x%s (index: %d): %w" , validatorDetails . Pubkey .String (), validatorIndex , err )
198193 }
199- t .log .Printlnf ("The Beacon WithdrawalSlot for validator ID %d is: %d" , validatorInfo . ValidatorId , withdrawalProof .WithdrawalSlot )
194+ t .log .Printlnf ("The Beacon WithdrawalSlot for validator index %d is: %d" , validatorDetails . Index , withdrawalProof .WithdrawalSlot )
200195
201- validatorProof , slotTimestamp , slotProof , err := services .GetValidatorProof (t .c , proofSlot , t .w , state .BeaconConfig , mp .GetAddress (), validatorPubkey , stateUsed )
196+ validatorProof , slotTimestamp , slotProof , err := services .GetValidatorProof (t .c , proofSlot , t .w , state .BeaconConfig , mp .GetAddress (), validatorDetails . Pubkey , stateUsed )
202197 if err != nil {
203198 t .log .Printlnf ("There was an error during the proof creation process: %w" , err )
204199 return err
@@ -221,9 +216,9 @@ func (t *notifyFinalBalance) createFinalBalanceProof(rp *rocketpool.RocketPool,
221216 t .log .Printlnf ("The validator final balance proof has been successfully created." )
222217
223218 // Get the gas limit
224- gasInfo , err := megapool .EstimateNotifyFinalBalance (rp , mp .GetAddress (), validatorInfo . ValidatorId , slotTimestamp , finalBalanceProof , validatorProof , slotProof , opts )
219+ gasInfo , err := megapool .EstimateNotifyFinalBalance (rp , mp .GetAddress (), validatorId , slotTimestamp , finalBalanceProof , validatorProof , slotProof , opts )
225220 if err != nil {
226- t .log .Printlnf ("Could not estimate the gas required to notify final balance on megapool validator %d: %w" , validatorInfo . ValidatorId , err )
221+ t .log .Printlnf ("Could not estimate the gas required to notify final balance on megapool validator %d: %w" , validatorId , err )
227222 return err
228223 }
229224 gas := big .NewInt (int64 (gasInfo .SafeGasLimit ))
@@ -246,7 +241,7 @@ func (t *notifyFinalBalance) createFinalBalanceProof(rp *rocketpool.RocketPool,
246241 opts .GasLimit = gas .Uint64 ()
247242
248243 // Call Notify Final Balance
249- tx , err := megapool .NotifyFinalBalance (rp , mp .GetAddress (), validatorInfo . ValidatorId , slotTimestamp , finalBalanceProof , validatorProof , slotProof , opts )
244+ tx , err := megapool .NotifyFinalBalance (rp , mp .GetAddress (), validatorId , slotTimestamp , finalBalanceProof , validatorProof , slotProof , opts )
250245 if err != nil {
251246 return err
252247 }
@@ -258,7 +253,7 @@ func (t *notifyFinalBalance) createFinalBalanceProof(rp *rocketpool.RocketPool,
258253 }
259254
260255 // Log
261- t .log .Printlnf ("Successfully notified validator %d final balance." , validatorInfo . ValidatorId )
256+ t .log .Printlnf ("Successfully notified validator %d final balance." , validatorId )
262257
263258 // Return
264259 return nil
0 commit comments