@@ -23,12 +23,22 @@ const (
2323
2424func candidateAction (ctx context.Context ) {
2525 now := time .Now ()
26+
2627 currentAPI := deps .NodeBridge .APIProvider ().APIForTime (now )
2728 currentSlot := currentAPI .TimeProvider ().SlotFromTime (now )
2829
30+ if ! deps .NodeBridge .NodeStatus ().GetIsBootstrapped () {
31+ Component .LogDebugf ("not issuing candidacy announcement for account %s in slot %d because node is not bootstrapped yet." , validatorAccount .ID (), currentSlot )
32+
33+ // If a node is not bootstrapped, then retry until it is bootstrapped.
34+ executor .ExecuteAt (CandidateTask , func () { candidateAction (ctx ) }, now .Add (ParamsValidator .CandidacyRetryInterval ))
35+
36+ return
37+ }
38+
2939 isCandidate , err := readIsCandidate (ctx , validatorAccount .ID (), currentSlot )
3040 if err != nil {
31- Component .LogWarnf ("error while checking if account is already a candidate: %s" , err .Error ())
41+ Component .LogWarnf ("error while checking if account %s is already a candidate: %s" , validatorAccount . ID () , err .Error ())
3242
3343 // If there is an error, then retry registering as a candidate, except if the context was canceled.
3444 if ! ierrors .Is (err , context .Canceled ) {
@@ -39,7 +49,8 @@ func candidateAction(ctx context.Context) {
3949 }
4050
4151 if isCandidate {
42- Component .LogDebugf ("not issuing candidacy announcement block as account %s is already registered as candidate in epoch %d" , validatorAccount .ID (), currentAPI .TimeProvider ().EpochFromSlot (currentSlot ))
52+ Component .LogDebugf ("not issuing candidacy announcement for account %s in slot %d as it is already registered as candidate in epoch %d" , validatorAccount .ID (), currentSlot , currentAPI .TimeProvider ().EpochFromSlot (currentSlot ))
53+
4354 // If an account is a registered candidate, then try to register as a candidate in the next epoch.
4455 executor .ExecuteAt (CandidateTask , func () { candidateAction (ctx ) }, currentAPI .TimeProvider ().SlotStartTime (currentAPI .TimeProvider ().EpochStart (currentAPI .TimeProvider ().EpochFromSlot (currentSlot )+ 1 )))
4556
@@ -49,41 +60,47 @@ func candidateAction(ctx context.Context) {
4960 epochEndSlot := currentAPI .TimeProvider ().EpochEnd (currentAPI .TimeProvider ().EpochFromSlot (currentSlot ))
5061 if currentSlot + currentAPI .ProtocolParameters ().EpochNearingThreshold () > epochEndSlot {
5162 Component .LogDebugf ("not issuing candidacy announcement for account %s as block's slot would be issued in (%d) is past the Epoch Nearing Threshold (%d) of epoch %d" , validatorAccount .ID (), currentSlot , epochEndSlot - currentAPI .ProtocolParameters ().EpochNearingThreshold (), currentAPI .TimeProvider ().EpochFromSlot (currentSlot ))
63+
5264 // If it's too late to register as a candidate, then try to register in the next epoch.
5365 executor .ExecuteAt (CandidateTask , func () { candidateAction (ctx ) }, currentAPI .TimeProvider ().SlotStartTime (currentAPI .TimeProvider ().EpochStart (currentAPI .TimeProvider ().EpochFromSlot (currentSlot )+ 1 )))
5466
5567 return
5668 }
5769
5870 // Schedule next committeeMemberAction regardless of the result below.
59- // If a node is not bootstrapped, then retry until it is bootstrapped.
6071 // The candidacy block might be issued and fail to be accepted in the node for various reasons,
6172 // so we should stop issuing candidacy blocks only when the account is successfully registered as a candidate.
6273 // For this reason,
6374 // retry interval parameter should be bigger than the fishing threshold to avoid issuing redundant candidacy blocks.
6475 executor .ExecuteAt (CandidateTask , func () { candidateAction (ctx ) }, now .Add (ParamsValidator .CandidacyRetryInterval ))
6576
66- if ! deps .NodeBridge .NodeStatus ().GetIsBootstrapped () {
67- Component .LogDebug ("not issuing candidate block because node is not bootstrapped yet." )
68-
69- return
70- }
71-
7277 if err = issueCandidateBlock (ctx , now , currentAPI ); err != nil {
73- Component .LogWarnf ("error while trying to issue candidacy announcement: %s" , err .Error ())
78+ Component .LogWarnf ("error while trying to issue candidacy announcement for account %s in slot %d : %s" , validatorAccount . ID (), currentSlot , err .Error ())
7479 }
7580}
7681
7782func committeeMemberAction (ctx context.Context ) {
7883 now := time .Now ()
84+
7985 currentAPI := deps .NodeBridge .APIProvider ().APIForTime (now )
8086 currentSlot := currentAPI .TimeProvider ().SlotFromTime (now )
8187 currentEpoch := currentAPI .TimeProvider ().EpochFromSlot (currentSlot )
82- slotDurationMillis := int64 ( currentAPI . ProtocolParameters (). SlotDurationInSeconds ()) * 1000
88+
8389 // Calculate the broadcast interval in milliseconds.
90+ slotDurationMillis := int64 (currentAPI .ProtocolParameters ().SlotDurationInSeconds ()) * 1000
8491 broadcastIntervalMillis := slotDurationMillis / int64 (currentAPI .ProtocolParameters ().ValidationBlocksPerSlot ())
8592 committeeBroadcastInterval := time .Duration (broadcastIntervalMillis * int64 (time .Millisecond ))
8693
94+ // If we are not bootstrapped and we are _not_ ignoring such condition, we return.
95+ if ! deps .NodeBridge .NodeStatus ().GetIsBootstrapped () && ! ParamsValidator .IgnoreBootstrapped {
96+ Component .LogDebugf ("not issuing validation block for account %s because node is not bootstrapped yet." , validatorAccount .ID ())
97+
98+ // If a node is not bootstrapped, then retry until it is bootstrapped.
99+ executor .ExecuteAt (CommitteeTask , func () { committeeMemberAction (ctx ) }, now .Add (committeeBroadcastInterval ))
100+
101+ return
102+ }
103+
87104 // If we are bootstrapped let's check if we are part of the committee.
88105 if deps .NodeBridge .NodeStatus ().GetIsBootstrapped () {
89106 isCommitteeMember , err := readIsCommitteeMember (ctx , validatorAccount .ID (), currentSlot )
@@ -99,44 +116,37 @@ func committeeMemberAction(ctx context.Context) {
99116 }
100117
101118 if ! isCommitteeMember {
102- Component .LogDebug ("account %s is not a committee member in epoch %d" , currentEpoch )
119+ Component .LogDebugf ("account %s is not a committee member in epoch %d" , validatorAccount . ID () , currentEpoch )
103120 executor .ExecuteAt (CommitteeTask , func () { committeeMemberAction (ctx ) }, currentAPI .TimeProvider ().SlotStartTime (currentAPI .TimeProvider ().EpochStart (currentEpoch + 1 )))
104121
105122 return
106123 }
107124 }
108125
109- // Schedule next committeeMemberAction regardless of whether the node is bootstrapped or validation block is issued
126+ // Schedule next committeeMemberAction regardless of whether the validation block is issued or not
110127 // as it must be issued as part of validator's responsibility.
111128 executor .ExecuteAt (CommitteeTask , func () { committeeMemberAction (ctx ) }, now .Add (committeeBroadcastInterval ))
112129
113- // If we are not bootstrapped and we are _not_ ignoring such condition, we return.
114- if ! deps .NodeBridge .NodeStatus ().GetIsBootstrapped () && ! ParamsValidator .IgnoreBootstrapped {
115- Component .LogDebug ("not issuing validation block because node is not bootstrapped yet." )
116-
117- return
118- }
119-
120130 // If we are either bootstrapped (and we are part of the committee) or we are ignoring being bootstrapped we issue
121131 // a validation block, reviving the chain if necessary.
122132 if err := issueValidationBlock (ctx , now , currentAPI , committeeBroadcastInterval ); err != nil {
123- Component .LogWarnf ("error while trying to issue validation block: %s" , err .Error ())
133+ Component .LogWarnf ("error while trying to issue validation block for account %s : %s" , validatorAccount . ID () , err .Error ())
124134 }
125135}
126136
127137func issueCandidateBlock (ctx context.Context , blockIssuingTime time.Time , currentAPI iotago.API ) error {
128- blockSlot := currentAPI .TimeProvider ().SlotFromTime (blockIssuingTime )
129-
130138 issuanceBlockHeaderResponse , err := blockIssuance (ctx , iotago .BasicBlockMaxParents )
131139 if err != nil {
132- return ierrors .Wrapf (err , "failed to get blockIssuance" )
140+ return ierrors .Wrap (err , "failed to get blockIssuance" )
133141 }
134142
135143 latestParentBlockIssuingTime := issuanceBlockHeaderResponse .LatestParentBlockIssuingTime .Add (time .Nanosecond )
136144 if blockIssuingTime .Before (latestParentBlockIssuingTime ) {
137145 blockIssuingTime = latestParentBlockIssuingTime
138146 }
139147
148+ blockSlot := currentAPI .TimeProvider ().SlotFromTime (blockIssuingTime )
149+
140150 addressableCommitment , err := getAddressableCommitment (ctx , blockSlot )
141151 if err != nil {
142152 return ierrors .Wrap (err , "error getting commitment" )
@@ -185,12 +195,12 @@ func issueCandidateBlock(ctx context.Context, blockIssuingTime time.Time, curren
185195func issueValidationBlock (ctx context.Context , blockIssuingTime time.Time , currentAPI iotago.API , committeeBroadcastInterval time.Duration ) error {
186196 protocolParametersHash , err := currentAPI .ProtocolParameters ().Hash ()
187197 if err != nil {
188- return ierrors .Wrapf (err , "failed to get protocol parameters hash" )
198+ return ierrors .Wrap (err , "failed to get protocol parameters hash" )
189199 }
190200
191201 issuanceBlockHeaderResponse , err := blockIssuance (ctx , iotago .ValidationBlockMaxParents )
192202 if err != nil {
193- return ierrors .Wrapf (err , "failed to get blockIssuance" )
203+ return ierrors .Wrap (err , "failed to get blockIssuance" )
194204 }
195205
196206 latestParentBlockIssuingTime := issuanceBlockHeaderResponse .LatestParentBlockIssuingTime .Add (time .Nanosecond )
@@ -208,15 +218,15 @@ func issueValidationBlock(ctx context.Context, blockIssuingTime time.Time, curre
208218 // to allow the validator to issue validation blocks.
209219 commitment , parentID , reviveChainErr := reviveChain (ctx , blockIssuingTime )
210220 if reviveChainErr != nil {
211- return ierrors .Wrapf (err , "error reviving chain" )
221+ return ierrors .Wrap (err , "error reviving chain" )
212222 }
213223
214224 addressableCommitment = commitment
215225 issuanceBlockHeaderResponse .StrongParents = []iotago.BlockID {parentID }
216226 issuanceBlockHeaderResponse .WeakParents = []iotago.BlockID {}
217227 issuanceBlockHeaderResponse .ShallowLikeParents = []iotago.BlockID {}
218228 } else if err != nil {
219- return ierrors .Wrapf (err , "error getting commitment" )
229+ return ierrors .Wrap (err , "error getting commitment" )
220230 }
221231
222232 // create the validation block here using the validation block builder from iota.go
@@ -232,12 +242,12 @@ func issueValidationBlock(ctx context.Context, blockIssuingTime time.Time, curre
232242 Sign (validatorAccount .ID (), validatorAccount .PrivateKey ()).
233243 Build ()
234244 if err != nil {
235- return ierrors .Wrapf (err , "error creating validation block" )
245+ return ierrors .Wrap (err , "error creating validation block" )
236246 }
237247
238248 blockID , err := submitBlock (ctx , validationBlock )
239249 if err != nil {
240- return ierrors .Wrapf (err , "error issuing validation block" )
250+ return ierrors .Wrap (err , "error issuing validation block" )
241251 }
242252
243253 Component .LogDebugf ("issued validation block: %s - commitment %s %d - latest finalized slot %d - broadcast interval %v" , blockID , validationBlock .Header .SlotCommitmentID , validationBlock .Header .SlotCommitmentID .Slot (), validationBlock .Header .LatestFinalizedSlot , committeeBroadcastInterval .Truncate (time .Millisecond ))
0 commit comments