@@ -17,6 +17,7 @@ import {
1717 CallEffect ,
1818 call ,
1919 takeLatest ,
20+ retry ,
2021} from "redux-saga/effects" ;
2122import { CGAccount } from "../../models/account" ;
2223import { deleteKeystore , saveValidatorData } from "../../services/utils/account" ;
@@ -163,6 +164,7 @@ export function* addNewValidatorSaga(action: ReturnType<typeof addNewValidator>)
163164 yield put ( addValidator ( validator ) ) ;
164165 yield put ( setLoadingValidator ( false ) ) ;
165166 yield spawn ( validatorInfoUpdater , validator . publicKey , validator . network ) ;
167+ yield put ( startValidatorDutiesWatcher ( validator . publicKey ) ) ;
166168}
167169
168170function * removeValidatorSaga (
@@ -524,9 +526,24 @@ export function* watchValidatorDuties({
524526} : ReturnType < typeof startValidatorDutiesWatcher > ) : Generator <
525527 SelectEffect | TakeEffect | CallEffect ,
526528 void ,
527- IValidatorComplete & typeof CgEth2ApiClient & ICGValidatorResponse & ReturnType < typeof updateEpoch > & Beacon
529+ IValidatorComplete &
530+ typeof CgEth2ApiClient &
531+ ICGValidatorResponse &
532+ ReturnType < typeof updateEpoch > &
533+ Beacon &
534+ ReturnType < typeof setValidatorBeaconNode >
528535> {
529- const validator = yield select ( getValidator , { publicKey : payload } ) ;
536+ let validator : IValidatorComplete = yield select ( getValidator , { publicKey : payload } ) ;
537+ if ( ! validator . beaconNodes . length ) {
538+ while ( true ) {
539+ const updatedValidator = yield take ( setValidatorBeaconNode ) ;
540+ if ( updatedValidator . payload . length && validator . publicKey === updatedValidator . meta ) {
541+ validator = { ...validator , beaconNodes : updatedValidator . payload } ;
542+ break ;
543+ }
544+ }
545+ }
546+
530547 const config = getNetworkConfig ( validator . network ) ?. eth2Config || mainnetConfig ;
531548 const { genesisTime} = getNetworkConfig ( validator . network ) ;
532549
@@ -539,11 +556,27 @@ export function* watchValidatorDuties({
539556 function * processDuties (
540557 epoch : number ,
541558 ) : Generator < CallEffect | AllEffect < CallEffect > , void , AttesterDuty [ ] & ProposerDuty [ ] > {
542- const attestations = yield call ( eth2API . validator . getAttesterDuties , epoch , [ validatorState . index ] ) ;
543- const attestationsFuture = yield call ( eth2API . validator . getAttesterDuties , epoch + 1 , [ validatorState . index ] ) ;
544- const propositions = yield call ( eth2API . validator . getProposerDuties , epoch , [ validatorId ] ) ;
545- const propositionsFuture = yield call ( eth2API . validator . getProposerDuties , epoch + 1 , [ validatorId ] ) ;
546- const propositionsSuperFuture = yield call ( eth2API . validator . getProposerDuties , epoch + 2 , [ validatorId ] ) ;
559+ let attestations : AttesterDuty [ ] , attestationsFuture : AttesterDuty [ ] ;
560+ try {
561+ attestations = yield retry ( 2 , 0 , eth2API . validator . getAttesterDuties , epoch , [ validatorState . index ] ) ;
562+ attestationsFuture = yield call ( eth2API . validator . getAttesterDuties , epoch + 1 , [ validatorState . index ] ) ;
563+ } catch ( e ) {
564+ attestations = attestations || [ ] ;
565+ attestationsFuture = [ ] ;
566+ cgLogger . warn ( "processDuties attestations" , e ) ;
567+ }
568+
569+ let propositions : ProposerDuty [ ] , propositionsFuture : ProposerDuty [ ] , propositionsSuperFuture : ProposerDuty [ ] ;
570+ try {
571+ propositions = yield call ( eth2API . validator . getProposerDuties , epoch , [ validatorId ] ) ;
572+ propositionsFuture = yield call ( eth2API . validator . getProposerDuties , epoch + 1 , [ validatorId ] ) ;
573+ propositionsSuperFuture = yield call ( eth2API . validator . getProposerDuties , epoch + 2 , [ validatorId ] ) ;
574+ } catch ( e ) {
575+ propositions = propositions || [ ] ;
576+ propositionsFuture = propositionsFuture || [ ] ;
577+ propositionsSuperFuture = [ ] ;
578+ cgLogger . warn ( "processDuties propositions" , e ) ;
579+ }
547580
548581 // store data to database
549582 yield all ( [
@@ -579,6 +612,13 @@ export function* watchValidatorDuties({
579612 yield take ( addBeacons ) ;
580613 beaconNode = yield select ( getBeaconByKey , { key : validator . beaconNodes [ 0 ] } ) ;
581614 }
615+ if ( beaconNode . status !== BeaconStatus . active ) {
616+ while ( true ) {
617+ const newStatus = yield take ( updateStatus ) ;
618+ if ( newStatus . payload === BeaconStatus . active && newStatus . meta === beaconNode . url ) break ;
619+ }
620+ }
621+
582622 yield call ( processDuties , computeEpochAtSlot ( config , beaconNode . slot ) ) ;
583623 while ( true ) {
584624 const newEpoch = yield take ( updateEpoch ) ;
@@ -592,14 +632,15 @@ function* updateDutiesStatus({
592632 meta,
593633} : ReturnType < typeof updateSlot > ) : Generator < SelectEffect | AllEffect < AllEffect < CallEffect > > , void , BeaconValidators > {
594634 const validatorsByBeaconNode = yield select ( getValidatorsByBeaconNode ) ;
595- yield all (
596- validatorsByBeaconNode [ meta ] . map ( ( { publicKey} ) =>
597- all ( [
598- call ( database . validator . propositionDuties . updateMissed , publicKey , payload ) ,
599- call ( database . validator . attestationDuties . updateMissed , publicKey , payload ) ,
600- ] ) ,
601- ) ,
602- ) ;
635+ if ( validatorsByBeaconNode [ meta ] )
636+ yield all (
637+ validatorsByBeaconNode [ meta ] . map ( ( { publicKey} ) =>
638+ all ( [
639+ call ( database . validator . propositionDuties . updateMissed , publicKey , payload ) ,
640+ call ( database . validator . attestationDuties . updateMissed , publicKey , payload ) ,
641+ ] ) ,
642+ ) ,
643+ ) ;
603644}
604645
605646function * onPublishedBlock ( {
0 commit comments