3838 subnet_id* : SubnetId
3939 slot* : Slot
4040
41+ PTCDuty * = object
42+ slot* : Slot
43+ validator_index: ValidatorIndex
44+
4145 ActionTracker * = object
4246 nodeId: UInt256
4347
7377 lastSyncUpdate* : Opt [SyncCommitteePeriod ]
7478 syncDuties* : Table [ValidatorPubKey , Epoch ]
7579
80+ ptcSlots* : array [2 , uint32 ]
81+ ptcDuties* : HashSet [PTCDuty ]
82+
7683func hash * (x: AggregatorDuty ): Hash =
7784 hashAllFields (x)
7885
@@ -116,6 +123,32 @@ func hasSyncDuty*(
116123 tracker: ActionTracker , pubkey: ValidatorPubKey , epoch: Epoch ): bool =
117124 epoch < tracker.syncDuties.getOrDefault (pubkey, GENESIS_EPOCH )
118125
126+ proc registerPTCDuty * (
127+ tracker: var ActionTracker , slot: Slot , vidx: ValidatorIndex ) =
128+ if slot < tracker.currentSlot or
129+ slot >= Slot (uint64 (tracker.currentSlot) + (SLOTS_PER_EPOCH * 2 )):
130+ debug " Irrelevant PTC duty" , slot, vidx
131+ return
132+
133+ tracker.knownValidators[vidx] = slot
134+
135+ let newDuty = PTCDuty (slot: slot, validator_index: vidx)
136+
137+ debug " Registering PTC duty" , slot, vidx
138+ tracker.ptcDuties.incl (newDuty)
139+
140+ from std/ sequtils import anyIt, toSeq
141+
142+ func hasPTCDuty * (tracker: ActionTracker , slot: Slot ): bool =
143+ tracker.ptcDuties.anyIt (it.slot == slot)
144+
145+ func getPTCDuties * (tracker: ActionTracker , slot: Slot ): seq [ValidatorIndex ] =
146+ var duties: seq [ValidatorIndex ]
147+ for duty in tracker.ptcDuties:
148+ if duty.slot == slot:
149+ duties.add (duty.validator_index)
150+ duties
151+
119152func aggregateSubnets * (tracker: ActionTracker , wallSlot: Slot ): AttnetBits =
120153 var res: AttnetBits
121154 # Subscribe to subnets for upcoming duties
@@ -146,6 +179,7 @@ proc updateSlot*(tracker: var ActionTracker, wallSlot: Slot) =
146179 # are only so many slot/subnet combos - prune both internal and API-supplied
147180 # duties at the same time
148181 tracker.duties.keepItIf (it.slot >= wallSlot)
182+ tracker.ptcDuties.keepItIf (it.slot >= wallSlot)
149183
150184 block :
151185 var dels: seq [ValidatorPubKey ]
@@ -211,8 +245,6 @@ func needsUpdate*(
211245 tracker.attesterDepRoot !=
212246 state.dependent_root (if epoch > Epoch (0 ): epoch - 1 else : epoch)
213247
214- from std/ sequtils import toSeq
215-
216248func updateActions * (
217249 tracker: var ActionTracker , shufflingRef: ShufflingRef ,
218250 beaconProposers: openArray [Opt [ValidatorIndex ]]) =
@@ -232,6 +264,7 @@ func updateActions*(
232264 tracker.proposingSlots[epoch mod 2 ] or (1 'u32 shl i)
233265
234266 tracker.attestingSlots[epoch mod 2 ] = 0
267+ tracker.ptcSlots[epoch mod 2 ] = 0
235268
236269 # The relevant bitmaps are 32 bits each.
237270 static : doAssert SLOTS_PER_EPOCH <= 32
@@ -257,6 +290,12 @@ func updateActions*(
257290 tracker.attestingSlots[epoch mod 2 ] or
258291 (1 'u32 shl (slot mod SLOTS_PER_EPOCH ))
259292
293+ for duty in tracker.ptcDuties:
294+ if duty.slot.epoch == epoch:
295+ tracker.ptcSlots[epoch mod 2 ] =
296+ tracker.ptcSlots[epoch mod 2 ] or
297+ (1 'u32 shl (duty.slot mod SLOTS_PER_EPOCH ))
298+
260299func init * (
261300 T: type ActionTracker , nodeId: UInt256 , subscribeAllAttnets: bool ): T =
262301 T (
0 commit comments