Skip to content

Commit 21a37af

Browse files
committed
docs: add docs for new and updated structs/functions/impl
Signed-off-by: Gustavo Inacio <[email protected]>
1 parent d1c87d4 commit 21a37af

File tree

7 files changed

+307
-35
lines changed

7 files changed

+307
-35
lines changed

crates/tap-agent/src/agent/sender_account.rs

Lines changed: 122 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ const INITIAL_RAV_REQUEST_CONCURRENT: usize = 1;
100100
type RavMap = HashMap<Address, u128>;
101101
type Balance = U256;
102102

103+
/// Information for Ravs that are abstracted away from the SignedRav itself
103104
#[derive(Debug, Default, PartialEq, Eq)]
104105
pub struct RavInformation {
105106
pub allocation_id: Address,
@@ -133,27 +134,61 @@ impl From<&tap_graph::v2::SignedRav> for RavInformation {
133134
}
134135
}
135136

137+
/// Custom update receipt fee message
138+
///
139+
/// It has different logic depending on the variant
136140
#[derive(Debug)]
137141
pub enum ReceiptFees {
142+
/// Adds the receipt value to the fee tracker
143+
///
144+
/// Used when a receipt is received
138145
NewReceipt(u128, u64),
146+
/// Overwrite the current fee tracker with the given value
147+
///
148+
/// Used while starting up to signalize the sender it's current value
139149
UpdateValue(UnaggregatedReceipts),
150+
/// Overwrite the current fee tracker with the given value
151+
///
152+
/// If the rav response was successful, update the rav tracker
153+
/// If not, signalize the fee_tracker to apply proper backoff
140154
RavRequestResponse((UnaggregatedReceipts, anyhow::Result<Option<RavInformation>>)),
155+
/// Ignores all logic and simply retry Allow/Deny and Rav Request logic
156+
///
157+
/// This is used inside a scheduler to trigger a Rav request in case the
158+
/// sender is denied since the only way to trigger a Rav request is by
159+
/// receiving a receipt and denied senders don't receive receipts
141160
Retry,
142161
}
143162

163+
/// Enum containing all types of messages that a SenderAccount can receive
144164
#[derive(Debug)]
145165
pub enum SenderAccountMessage {
166+
/// Updates the sender balance and
146167
UpdateBalanceAndLastRavs(Balance, RavMap),
168+
/// Spawn and Stop SenderAllocations that were added or removed
169+
/// in comparision with it current state and updates the state
147170
UpdateAllocationIds(HashSet<AllocationId>),
171+
/// Manual request to create a new Sender Allocation
148172
NewAllocationId(AllocationId),
173+
/// Updates the fee tracker for a given allocation
174+
///
175+
/// All allowing or denying logic is called inside the message handler
176+
/// as well as requesting the underlaying allocation rav request
177+
///
178+
/// Custom behavior is defined in [ReceiptFees]
149179
UpdateReceiptFees(Address, ReceiptFees),
180+
/// Updates the counter for invalid receipts and verify to deny sender
150181
UpdateInvalidReceiptFees(Address, UnaggregatedReceipts),
182+
/// Update rav tracker
151183
UpdateRav(RavInformation),
152184
#[cfg(test)]
185+
/// Returns the sender fee tracker, used for tests
153186
GetSenderFeeTracker(ractor::RpcReplyPort<SenderFeeTracker>),
154187
#[cfg(test)]
188+
/// Returns the Deny status, used for tests
155189
GetDeny(ractor::RpcReplyPort<bool>),
156190
#[cfg(test)]
191+
/// Returns if the scheduler is enabled, used for tests
157192
IsSchedulerEnabled(ractor::RpcReplyPort<bool>),
158193
}
159194

@@ -168,57 +203,122 @@ pub enum SenderAccountMessage {
168203
/// - Requesting the last RAV from the sender's TAP aggregator for all EOL allocations.
169204
pub struct SenderAccount;
170205

206+
/// Arguments received in startup while spawing [SenderAccount] actor
171207
pub struct SenderAccountArgs {
172208
pub config: &'static SenderAccountConfig,
173209

210+
/// Connection to database
174211
pub pgpool: PgPool,
212+
/// Current sender address
175213
pub sender_id: Address,
214+
/// Watcher that returns a list of escrow accounts for current indexer
176215
pub escrow_accounts: Receiver<EscrowAccounts>,
216+
/// Watcher that returns a set of open and recently closed allocation ids
177217
pub indexer_allocations: Receiver<HashSet<AllocationId>>,
218+
/// SubgraphClient of the escrow subgraph
178219
pub escrow_subgraph: &'static SubgraphClient,
220+
/// SubgraphClient of the network subgraph
179221
pub network_subgraph: &'static SubgraphClient,
222+
/// Domain separator used for tap
180223
pub domain_separator: Eip712Domain,
224+
/// Endpoint URL for aggregator server
181225
pub sender_aggregator_endpoint: Url,
226+
/// List of allocation ids that must created at startup
182227
pub allocation_ids: HashSet<AllocationId>,
228+
/// Prefix used to bypass limitations of global actor registry (used for tests)
183229
pub prefix: Option<String>,
184230

231+
/// Configuration for retry scheduler in case sender is denied
185232
pub retry_interval: Duration,
186233
}
234+
235+
/// State used by the actor
236+
///
237+
/// This is a separate instance that makes it easier to have mutable
238+
/// reference, for more information check ractor library
187239
pub struct State {
240+
/// Prefix used to bypass limitations of global actor registry (used for tests)
188241
prefix: Option<String>,
242+
/// Tracker used to monitor all pending fees across allocations
243+
///
244+
/// Since rav requests are per allocation, this also has the algorithm
245+
/// to select the next allocation to have a rav request.
246+
///
247+
/// This monitors if rav requests succeeds or fails and apply proper backoff.
248+
///
249+
/// Keeps track of the buffer returning values for both inside or outside the buffer.
250+
///
251+
/// It selects the allocation with most amount of pending fees.
252+
/// Filters out allocations in the algorithm in case:
253+
/// - In back-off
254+
/// - Marked as closing allocation (blocked)
255+
/// - Rav request in flight (selected the previous time)
189256
sender_fee_tracker: SenderFeeTracker,
257+
/// Simple tracker used to monitor all Ravs that were not redeemed yet.
258+
///
259+
/// This is used to monitor both active allocations and closed but not redeemed.
190260
rav_tracker: SimpleFeeTracker,
261+
/// Simple tracker used to monitor all invalid receipts ever.
191262
invalid_receipts_tracker: SimpleFeeTracker,
263+
/// Set containing current active allocations
192264
allocation_ids: HashSet<AllocationId>,
265+
/// Keeps a reference of the handle for indexer_allocation pipe
193266
_indexer_allocations_handle: JoinHandle<()>,
267+
/// Keeps a reference of the handle for escrow_account pipe
194268
_escrow_account_monitor: JoinHandle<()>,
269+
/// Scheduler used to send a retry message in case sender is denied
270+
///
271+
/// If scheduler is set, it's canceled in the first [SenderAccountMessage::UpdateReceiptFees]
272+
/// message
195273
scheduled_rav_request: Option<JoinHandle<Result<(), MessagingErr<SenderAccountMessage>>>>,
196274

275+
/// Current sender address
197276
sender: Address,
198277

199-
// Deny reasons
278+
/// State to check if sender is current denied
200279
denied: bool,
280+
/// Sender Balance used to verify if it has money in
281+
/// the escrow to pay for all non-redeemed fees (ravs and receipts)
201282
sender_balance: U256,
283+
/// Configuration for retry scheduler in case sender is denied
202284
retry_interval: Duration,
203285

204-
// concurrent rav request
286+
/// Adaptative limiter for concurrent Rav Request
287+
///
288+
/// This uses a simple algorithm where it increases by one in case
289+
/// of a success or decreases by half in case of a failure
205290
adaptive_limiter: AdaptiveLimiter,
206291

207-
// Receivers
292+
/// Watcher containing the escrow accounts
208293
escrow_accounts: Receiver<EscrowAccounts>,
209294

295+
/// SubgraphClient of the escrow subgraph
210296
escrow_subgraph: &'static SubgraphClient,
297+
/// SubgraphClient of the network subgraph
211298
network_subgraph: &'static SubgraphClient,
212299

300+
/// Domain separator used for tap
213301
domain_separator: Eip712Domain,
302+
/// Database connection
214303
pgpool: PgPool,
304+
/// Aggregator client for V1
305+
///
306+
/// This is only send to [SenderAllocation] in case
307+
/// it's a [AllocationId::Legacy]
215308
aggregator_v1: AggregatorV1<Channel>,
309+
/// Aggregator client for V2
310+
///
311+
/// This is only send to [SenderAllocation] in case
312+
/// it's a [AllocationId::Horizon]
216313
aggregator_v2: AggregatorV2<Channel>,
217314

218-
// Backoff info
315+
// Used as a global backoff for triggering new rav requests
316+
//
317+
// This is used when there are failures in Rav request and
318+
// reset in case of a successful response
219319
backoff_info: BackoffInfo,
220320

221-
// Config
321+
// Config forwarded to [SenderAllocation]
222322
config: &'static SenderAccountConfig,
223323
}
224324

@@ -251,6 +351,10 @@ impl SenderAccountConfig {
251351
}
252352

253353
impl State {
354+
/// Spawn a sender allocation given the allocation_id
355+
///
356+
/// Since this is a function inside State, we need to provide
357+
/// the reference for the [SenderAccount] actor
254358
async fn create_sender_allocation(
255359
&self,
256360
sender_account_ref: ActorRef<SenderAccountMessage>,
@@ -358,6 +462,10 @@ impl State {
358462
Ok(())
359463
}
360464

465+
/// Proccess the rav response sent by [SenderAllocation]
466+
///
467+
/// This updates all backoff information for fee_tracker, backoff_info and
468+
/// adaptative_limiter as well as updating the rav tracker and fee tracker
361469
fn finalize_rav_request(
362470
&mut self,
363471
allocation_id: Address,
@@ -471,8 +579,8 @@ impl State {
471579
.set(0);
472580
}
473581

474-
/// receives a list of possible closed allocations and verify
475-
/// if they are really closed
582+
/// Receives a list of possible closed allocations and verify
583+
/// if they are really closed in the subgraph
476584
async fn check_closed_allocations(
477585
&self,
478586
allocation_ids: HashSet<&AllocationId>,
@@ -526,12 +634,16 @@ impl State {
526634
}
527635
}
528636

637+
/// Actor implementation for [SenderAccount]
529638
#[async_trait::async_trait]
530639
impl Actor for SenderAccount {
531640
type Msg = SenderAccountMessage;
532641
type State = State;
533642
type Arguments = SenderAccountArgs;
534643

644+
/// This is called in the [ractor::Actor::spawn] method and is used
645+
/// to process the [SenderAccountArgs] with a reference to the current
646+
/// actor
535647
async fn pre_start(
536648
&self,
537649
myself: ActorRef<Self::Msg>,
@@ -736,6 +848,7 @@ impl Actor for SenderAccount {
736848
Ok(state)
737849
}
738850

851+
/// Handle a new [SenderAccountMessage] message
739852
async fn handle(
740853
&self,
741854
myself: ActorRef<Self::Msg>,
@@ -1028,8 +1141,8 @@ impl Actor for SenderAccount {
10281141
Ok(())
10291142
}
10301143

1031-
// we define the supervisor event to overwrite the default behavior which
1032-
// is shutdown the supervisor on actor termination events
1144+
/// We define the supervisor event to overwrite the default behavior which
1145+
/// is shutdown the supervisor on actor termination events
10331146
async fn handle_supervisor_evt(
10341147
&self,
10351148
myself: ActorRef<Self::Msg>,

crates/tap-agent/src/agent/sender_accounts_manager.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,19 @@ pub struct NewReceiptNotification {
4848

4949
pub struct SenderAccountsManager;
5050

51+
/// Wrapped AllocationId Address with two possible variants
52+
///
53+
/// This is used by children actors to define what kind of
54+
/// SenderAllocation must be created to handle the correct
55+
/// Rav and Receipt types
5156
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
5257
pub enum AllocationId {
5358
Legacy(Address),
5459
Horizon(Address),
5560
}
5661

5762
impl AllocationId {
63+
/// Take the inner address for both allocation types
5864
pub fn address(&self) -> Address {
5965
match self {
6066
AllocationId::Legacy(address) | AllocationId::Horizon(address) => *address,
@@ -109,6 +115,9 @@ impl Actor for SenderAccountsManager {
109115
type State = State;
110116
type Arguments = SenderAccountsManagerArgs;
111117

118+
/// This is called in the [ractor::Actor::spawn] method and is used
119+
/// to process the [SenderAccountsManagerArgs] with a reference to the current
120+
/// actor
112121
async fn pre_start(
113122
&self,
114123
myself: ActorRef<Self::Msg>,
@@ -303,6 +312,13 @@ impl State {
303312
sender_allocation_id
304313
}
305314

315+
/// Helper function to create a [SenderAccount]
316+
///
317+
/// It takes the current [SenderAccountsManager] cell to use it
318+
/// as supervisor, sender address and a list of initial allocations
319+
///
320+
/// In case there's an error creating it, deny so it
321+
/// can no longer send queries
306322
async fn create_or_deny_sender(
307323
&self,
308324
supervisor: ActorCell,
@@ -322,6 +338,11 @@ impl State {
322338
}
323339
}
324340

341+
/// Helper function to create a [SenderAccount]
342+
///
343+
/// It takes the current [SenderAccountsManager] cell to use it
344+
/// as supervisor, sender address and a list of initial allocations
345+
///
325346
async fn create_sender_account(
326347
&self,
327348
supervisor: ActorCell,
@@ -354,11 +375,10 @@ impl State {
354375
Ok(())
355376
}
356377

378+
/// Gather all outstanding receipts and unfinalized RAVs from the database.
379+
/// Used to create [SenderAccount] instances for all senders that have unfinalized allocations
380+
/// and try to finalize them if they have become ineligible.
357381
async fn get_pending_sender_allocation_id(&self) -> HashMap<Address, HashSet<AllocationId>> {
358-
// Gather all outstanding receipts and unfinalized RAVs from the database.
359-
// Used to create SenderAccount instances for all senders that have unfinalized allocations
360-
// and try to finalize them if they have become ineligible.
361-
362382
// First we accumulate all allocations for each sender. This is because we may have more
363383
// than one signer per sender in DB.
364384
let mut unfinalized_sender_allocations_map: HashMap<Address, HashSet<AllocationId>> =
@@ -462,6 +482,11 @@ impl State {
462482

463483
unfinalized_sender_allocations_map
464484
}
485+
486+
/// Helper function to create [SenderAccountArgs]
487+
///
488+
/// Fails if the provided sender_id is not present
489+
/// in the sender_aggregator_endpoints map
465490
fn new_sender_account_args(
466491
&self,
467492
sender_id: &Address,
@@ -541,6 +566,16 @@ async fn new_receipts_watcher(
541566
tracing::error!("Manager killed");
542567
}
543568

569+
/// Handles a new detected [NewReceiptNotification] and routes to proper
570+
/// reference of [super::sender_allocation::SenderAllocation]
571+
///
572+
/// If the allocation doesn't exist yet, we trust that the whoever has
573+
/// access to the database already verified that the allocation really
574+
/// exists and we ask for the sender to create a new allocation.
575+
///
576+
/// After a request to create allocation, we don't need to do anything
577+
/// since the startup script is going to recalculate the receipt in the
578+
/// database
544579
async fn handle_notification(
545580
new_receipt_notification: NewReceiptNotification,
546581
escrow_accounts_rx: Receiver<EscrowAccounts>,

0 commit comments

Comments
 (0)