Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: paginate account credit debits #522

Merged
merged 17 commits into from
Feb 26, 2025
Merged

Conversation

avichalp
Copy link
Collaborator

@avichalp avichalp commented Feb 7, 2025

  • Paginate account debiting using HAMT's for_each_ranged method. Store the next address process in the current debit cycle in the state.
  • Paginate blob deletion by keeping the next index of AMT in the state

closes #478

@avichalp avichalp changed the title Paginate account credit debits perf: paginate account credit debits Feb 7, 2025
Copy link
Contributor

@sanderpick sanderpick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is looking good to me. are there any red flags popping up for you?

@avichalp
Copy link
Collaborator Author

@sanderpick: no red flags but was just worrying if i am missing an edge case.

where should we put the pagination batch sizes? it is currently hardcoded in this PR

@sanderpick
Copy link
Contributor

@sanderpick: no red flags but was just worrying if i am missing an edge case.

where should we put the pagination batch sizes? it is currently hardcoded in this PR

you could put in the recall_config actor. note: that will require an SDK update. there are commands to set the config.

re: the tests... can you manually try and figure out what the threshholds are for these batch sizes? ie, at what point do they run out of gas. maybe there's a way to use the recall loader-cli (cc @brunocalza) to add many 1000s of accounts and an bucket and object from each? or maybe there's a theoretical way to understand, ie, how much gas each iteration takes and if it grows linearly (it should since we're using hamt/amt). that would be nice, since load testing the expiries sounds like it would take some extra custom work.

@avichalp avichalp force-pushed the avichalp/paginated-debits branch from 673fadc to 8dbf155 Compare February 19, 2025 03:33
@avichalp
Copy link
Collaborator Author

avichalp commented Feb 19, 2025

Here is a break down of manually testing the debit_accounts method and different batch sized.

When walking the outer expiry AMT N times, we could go upto ~ 330 before running into block gas limit (10B).

1 account and N blobs

1: 29_528_398
100: 2_756_052_956
250: 7_392_148_602
300: 8_881_775_388
325: 9_651_803_132
330: 9_868_023_508
335: 9_995_108_942
336: out of gas

However, debit_accounts also iterate over Accounts in addition to expiry AMT. With Accounts traversal the breakdown looks something like this:

N accounts with 1 blob each (excludes expiry traversal gas)

1: 11_519_090
335: 820_064_125
1000: 2_096_304_681
2000: 3_617_460_618
5000: 7_618_952_490
6000: 8_976_209_296
6500: 9_659_512_057
6700: 9_912_982_462
6800: out of gas

Combining these two I have been trying account debiting with the following. It consumes ~ 9.2-9.3B gas units which almost fills the whole block but remains within the BLOCK_GAS_LIMIT

  • expiry batch size: 150
  • accounts batch size: 2000

Note: we should also reduce the debit interval if we go with expiry batch size of 150 to ensure there is not much backlog

@sanderpick
Copy link
Contributor

thanks for the great rundown here! maybe,

expiry batch size: 100
accounts batch size: 1000

would be better? more conservative? i wonder also, is there a way we can not propagate the error is this system level tx fails? kind of like we did for the blob reader callback method?

Signed-off-by: avichalp <[email protected]>
Signed-off-by: avichalp <[email protected]>
Signed-off-by: avichalp <[email protected]>
Signed-off-by: avichalp <[email protected]>
Signed-off-by: avichalp <[email protected]>
Signed-off-by: avichalp <[email protected]>
Signed-off-by: avichalp <[email protected]>
Signed-off-by: avichalp <[email protected]>
@avichalp avichalp force-pushed the avichalp/paginated-debits branch from 940a443 to 084a3d1 Compare February 20, 2025 03:57
@avichalp
Copy link
Collaborator Author

@sanderpick: 100 and 1000 sounds good to me!

I added the error handling for debit accounts call here: 084a3d1. I had to create the return object with default values in the error case to satisfy the return type. Is this okay?

Also, here are the two PRs for

I believe the set_config tests are failing at the moment due to changed event interface.

Also, where do we call the set_config? I think, that is the place where we actually set the values 1000 and 100.

@sanderpick
Copy link
Contributor

@sanderpick: 100 and 1000 sounds good to me!

I added the error handling for debit accounts call here: 084a3d1. I had to create the return object with default values in the error case to satisfy the return type. Is this okay?

I think so... does it work when you hit the out of gas error? ie, does the chain keep progressing? I wonder also, is there some way to know if the debiting falls behind with some logging?

Also, here are the two PRs for

I believe the set_config tests are failing at the moment due to changed event interface.

👀

Also, where do we call the set_config? I think, that is the place where we actually set the values 1000 and 100.

it's called from the SDK recall subnet config set command. so far we haven't used it -- the initial values are used.

Signed-off-by: avichalp <[email protected]>
@avichalp
Copy link
Collaborator Author

@sanderpick:

I think so... does it work when you hit the out of gas error? ie, does the chain keep progressing?

interestingly, we don't need to explicitly handle the error here. having state.execute_implicit(msg)? doesn't stop the chain. i recall, i saw this behaviour early on with blob reader too. but i thought i might have missed something at the time, so later changed that to explicit handling

@sanderpick
Copy link
Contributor

ah, so the tx just fails like a normal user txn that fails? and then the chain would just try again during the next "cron" tick?

@avichalp
Copy link
Collaborator Author

yes, it seems so. a WARN is logged

Screenshot 2025-02-20 at 4 17 41 PM

Signed-off-by: avichalp <[email protected]>
avichalp added a commit to recallnet/contracts that referenced this pull request Feb 21, 2025
Updates set config events related to
recallnet/ipc#522

Signed-off-by: avichalp <[email protected]>
@avichalp avichalp marked this pull request as ready for review February 21, 2025 02:48
@@ -32,6 +32,10 @@ pub struct RecallConfig {
pub blob_min_ttl: ChainEpoch,
/// The default epoch duration a blob is stored.
pub blob_default_ttl: ChainEpoch,
/// Maximum number of blobs to delete in a single batch during debit.
pub blob_delete_batch_size: u64,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adds two new config parameters

Ok(true)
})?;
let (count, next_idx) = expiries.for_each_while_ranged(
self.next_idx,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uses "next index" to continue the cursor based pagination

Ok(())
})?;

let start_key = self
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

next key for pagination

},
)?;
self.next_idx = batch_size.and(next_idx);
log::info!(
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logs next index and current epoch so we can get a sense of backlog

@avichalp avichalp requested a review from sanderpick February 21, 2025 22:54
@sanderpick
Copy link
Contributor

sorry for delay here... will look asap

Copy link
Contributor

@sanderpick sanderpick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks great! this is a big improvement 👍

@sanderpick sanderpick merged commit 963ec53 into main Feb 26, 2025
13 checks passed
@sanderpick sanderpick deleted the avichalp/paginated-debits branch February 26, 2025 18:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

debit_accounts() May Run Out Of Gas
2 participants