Skip to content

Commit 48d7b9f

Browse files
authored
*: v1.8.1 rc1 (#4207)
Fix for exits. category: feature ticket: none
1 parent 801c014 commit 48d7b9f

File tree

2 files changed

+51
-11
lines changed

2 files changed

+51
-11
lines changed

cmd/exit_broadcast.go

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ import (
99
"fmt"
1010
"os"
1111
"path/filepath"
12+
"slices"
1213
"strings"
1314
"time"
1415

16+
eth2v1 "github.com/attestantio/go-eth2-client/api/v1"
1517
eth2p0 "github.com/attestantio/go-eth2-client/spec/phase0"
1618
k1 "github.com/decred/dcrd/dcrec/secp256k1/v4"
1719
libp2plog "github.com/ipfs/go-log/v2"
@@ -252,9 +254,42 @@ func fetchFullExit(ctx context.Context, exitFilePath string, config exitConfig,
252254
}
253255

254256
func broadcastExitsToBeacon(ctx context.Context, eth2Cl eth2wrap.Client, exits map[core.PubKey]eth2p0.SignedVoluntaryExit) error {
257+
blsKeys := []eth2p0.BLSPubKey{}
258+
259+
for key := range exits {
260+
blsKey, err := key.ToETH2()
261+
if err != nil {
262+
return errors.Wrap(err, "convert core pubkey to eth2 pubkey", z.Str("core_pubkey", key.String()))
263+
}
264+
265+
blsKeys = append(blsKeys, blsKey)
266+
}
267+
268+
rawValData, err := queryBeaconForValidator(ctx, eth2Cl, blsKeys, nil, []eth2v1.ValidatorState{eth2v1.ValidatorStateActiveOngoing})
269+
if err != nil {
270+
return errors.Wrap(err, "fetch all validators indices from beacon")
271+
}
272+
273+
activePubKeys := []eth2p0.BLSPubKey{}
274+
for _, val := range rawValData.Data {
275+
activePubKeys = append(activePubKeys, val.Validator.PublicKey)
276+
}
277+
278+
activeExits := make(map[core.PubKey]eth2p0.SignedVoluntaryExit)
279+
255280
for validator, fullExit := range exits {
256281
valCtx := log.WithCtx(ctx, z.Str("validator", validator.String()))
257282

283+
eth2Key, err := validator.ToETH2()
284+
if err != nil {
285+
return errors.Wrap(err, "convert core pubkey to eth2 pubkey", z.Str("core_pubkey", validator.String()))
286+
}
287+
288+
if !slices.Contains(activePubKeys, eth2Key) {
289+
log.Info(valCtx, "Validator is not active, skipping broadcast")
290+
continue
291+
}
292+
258293
rawPkBytes, err := validator.Bytes()
259294
if err != nil {
260295
return errors.Wrap(err, "serialize validator key bytes", z.Str("validator", validator.String()))
@@ -284,9 +319,11 @@ func broadcastExitsToBeacon(ctx context.Context, eth2Cl eth2wrap.Client, exits m
284319
if err := tbls.Verify(pubkey, exitRoot[:], signature); err != nil {
285320
return errors.Wrap(err, "exit message signature not verified")
286321
}
322+
323+
activeExits[validator] = fullExit
287324
}
288325

289-
for validator, fullExit := range exits {
326+
for validator, fullExit := range activeExits {
290327
valCtx := log.WithCtx(ctx, z.Str("validator", validator.String()))
291328
if err := eth2Cl.SubmitVoluntaryExit(valCtx, &fullExit); err != nil {
292329
return errors.Wrap(err, "submit voluntary exit")

cmd/exit_sign.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -224,26 +224,28 @@ func signAllValidatorsExits(ctx context.Context, config exitConfig, eth2Cl eth2w
224224
valsEth2 = append(valsEth2, eth2PK)
225225
}
226226

227-
rawValData, err := queryBeaconForValidator(ctx, eth2Cl, valsEth2, nil)
227+
rawValData, err := queryBeaconForValidator(ctx, eth2Cl, valsEth2, nil, []eth2v1.ValidatorState{eth2v1.ValidatorStatePendingQueued, eth2v1.ValidatorStateActiveOngoing})
228228
if err != nil {
229229
return nil, errors.Wrap(err, "fetch all validators indices from beacon")
230230
}
231231

232+
activeShares := make(keystore.ValidatorShares)
233+
232234
for _, val := range rawValData.Data {
233235
share, ok := shares[core.PubKeyFrom48Bytes(val.Validator.PublicKey)]
234236
if !ok {
235237
return nil, errors.New("validator public key not found in cluster lock", z.Str("validator_public_key", val.Validator.PublicKey.String()))
236238
}
237239

238240
share.Index = int(val.Index)
239-
shares[core.PubKeyFrom48Bytes(val.Validator.PublicKey)] = share
241+
activeShares[core.PubKeyFrom48Bytes(val.Validator.PublicKey)] = share
240242
}
241243

242-
log.Info(ctx, "Signing partial exit message for all active validators")
244+
log.Info(ctx, "Signing partial exit message for all active validators", z.Int("active_validators", len(activeShares)), z.Int("inactive_validators", len(shares)-len(activeShares)))
243245

244246
var exitBlobs []obolapi.ExitBlob
245247

246-
for pk, share := range shares {
248+
for pk, share := range activeShares {
247249
exitMsg, err := signExit(ctx, eth2Cl, eth2p0.ValidatorIndex(share.Index), share.Share, eth2p0.Epoch(config.ExitEpoch))
248250
if err != nil {
249251
return nil, errors.Wrap(err, "sign partial exit message", z.Str("validator_public_key", pk.String()), z.Int("validator_index", share.Index), z.Int("exit_epoch", int(config.ExitEpoch)))
@@ -276,7 +278,7 @@ func fetchValidatorBLSPubKey(ctx context.Context, config exitConfig, eth2Cl eth2
276278
return valEth2, nil
277279
}
278280

279-
rawValData, err := queryBeaconForValidator(ctx, eth2Cl, nil, []eth2p0.ValidatorIndex{eth2p0.ValidatorIndex(config.ValidatorIndex)})
281+
rawValData, err := queryBeaconForValidator(ctx, eth2Cl, nil, []eth2p0.ValidatorIndex{eth2p0.ValidatorIndex(config.ValidatorIndex)}, nil)
280282
if err != nil {
281283
return eth2p0.BLSPubKey{}, errors.Wrap(err, "fetch validator pubkey from beacon", z.Str("beacon_address", eth2Cl.Address()), z.U64("validator_index", config.ValidatorIndex))
282284
}
@@ -300,7 +302,7 @@ func fetchValidatorIndex(ctx context.Context, config exitConfig, eth2Cl eth2wrap
300302
return 0, errors.Wrap(err, "convert core pubkey to eth2 pubkey", z.Str("core_pubkey", config.ValidatorPubkey))
301303
}
302304

303-
rawValData, err := queryBeaconForValidator(ctx, eth2Cl, []eth2p0.BLSPubKey{valEth2}, nil)
305+
rawValData, err := queryBeaconForValidator(ctx, eth2Cl, []eth2p0.BLSPubKey{valEth2}, nil, nil)
304306
if err != nil {
305307
return 0, errors.Wrap(err, "fetch validator index from beacon", z.Str("beacon_address", eth2Cl.Address()), z.Str("validator_pubkey", valEth2.String()))
306308
}
@@ -314,11 +316,12 @@ func fetchValidatorIndex(ctx context.Context, config exitConfig, eth2Cl eth2wrap
314316
return 0, errors.New("validator public key not found in beacon node response", z.Str("beacon_address", eth2Cl.Address()), z.Str("validator_pubkey", valEth2.String()), z.Any("raw_response", rawValData))
315317
}
316318

317-
func queryBeaconForValidator(ctx context.Context, eth2Cl eth2wrap.Client, pubKeys []eth2p0.BLSPubKey, indices []eth2p0.ValidatorIndex) (*eth2api.Response[map[eth2p0.ValidatorIndex]*eth2v1.Validator], error) {
319+
func queryBeaconForValidator(ctx context.Context, eth2Cl eth2wrap.Client, pubKeys []eth2p0.BLSPubKey, indices []eth2p0.ValidatorIndex, states []eth2v1.ValidatorState) (*eth2api.Response[map[eth2p0.ValidatorIndex]*eth2v1.Validator], error) {
318320
valAPICallOpts := &eth2api.ValidatorsOpts{
319-
State: "head",
320-
PubKeys: pubKeys,
321-
Indices: indices,
321+
State: "head",
322+
PubKeys: pubKeys,
323+
Indices: indices,
324+
ValidatorStates: states,
322325
}
323326

324327
rawValData, err := eth2Cl.Validators(ctx, valAPICallOpts)

0 commit comments

Comments
 (0)