-
Notifications
You must be signed in to change notification settings - Fork 330
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
feat(cycles-minting): Cycles Minting canister refunds automatically. #3484
feat(cycles-minting): Cycles Minting canister refunds automatically. #3484
Conversation
f50d3b7
to
3be81cc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this pull request affects the behavior of any canister owned by
the Governance team, remember to update the corresponding
unreleased_changes.md file(s).
To acknowldge this reminder (and unblock the PR), dismiss this
code review by going to the bottom of the pull request page, and
supply one of the following reasons:
-
Done.
-
No canister behavior changes.
New functionality is disabled via a flag. It will be enabled once security team reviews.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, other than small changes about commentary in code comments
…existing tests still pass, but still need new tests.
…ngress_as." This reverts commit bc6492c.
…ulMemo. The new name is more apt, and was suggested in code review.
…ore attempting to call ledger. To wit, abort.
… when constructing a CMC. Also, that caused my new test to fail. Therefore, I stopped having it set to 1 when constructing CMC in test.
47e606b
to
f6a9aa6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Comments:
- It looks like you have carefully ensured that a block can be processed successfully at most once. Since processing a block only refunds a block XOR mints cycles for the block, there is no way to double issue_automatic_refund or issue_automatic_refund AND mint cycles. (Where issue_automatic_refund refers to the new refund path in this PR, as opposed to refund paths that happen when there is an error during minting.)
- I’d like to note that there is some brittleness to the current design that is causing extra complexity in bookkeeping. This brittleness is not caused by the current PR, but it creates complexity for the current PR to handle — namely the current PR must ensure minting and issue_automatic_refund do not overlap. The issue is that the CMC deals with recent blocks and not the total ICP in a subaccount. During minting of cycles, the CMC mints first and burns later. This means that a panic could allow ICP to be left in the subaccount after minting. (The block would be stuck in “Processing”.) There could also be unrefunded ICP that gets stuck in the subaccount. Whereas, if the CMC burned first and minted second, the CMC could let the ledger ensure no double spending, and the bookkeeping and refunding logic in the CMC could be simplified.
- The temporary buffer containing block statuses creates further brittleness. A block that is being processed for refunding could error out, and then become too old for further processing. Blocks could be stuck in processing and be forgotten. The condition for being too old must also be adjusted manually because it does not directly limit the size of the buffer. If there are too many blocks in a short time the buffer could still grow too large.
} | ||
|
||
// There is no (known) way to reach this case, since we already | ||
// verified that memo is in MEANINGFUL_MEMOS. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you mean "since we already verified that memo is NOT in MEANINGFUL_MEMOS".
.inspect_err(|_err| { | ||
// This allows the user to retry. | ||
clear_block_processing_status(incoming_block_index); | ||
})?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a comment on the behavior. NCR.
If there is a panic after calling the ledger to refund ICP, the block will be stuck in processing. This would need to be manually resolved. Manual resolution would entail checking that the memo indicates the block should be refunded, and looking for a refund on the ledger to see if a new refund should be sent.
This is per [feedback] from Andrew Lee. [feedback]: #3484 (comment) --------- Co-authored-by: Arshavir Ter-Gabrielyan <[email protected]>
Implementation of this feature was done in an [earlier PR][impl], but was left disabled. For details of this feature, see the description of the aforementioned PR. [impl]: #3484 Per the reminder bot, an entry has been added to unreleased_changes.md.
This happens when the
memo
(oricrc1_memo
) in an ICP transfer is not one of the special values that CMC recognizes as signaling the purpose of the transfer.This behavior gets triggered when one of the
notify_*
methods gets called.The new behavior is not actually active yet. To turn it on, we simply need to set
IS_AUTOMATIC_REFUND_ENABLED
to true. I have run the tests with this set to true locally, and they pass.Motivation
Avoids ICP getting stuck, which can result from people making mistakes when sending ICP to the CMC.
Implementation Overview
Added
issue_automatic_refund_if_memo_not_offerred
. As indicated by the name, this is the heart of the implementation of this new functionality. This is called fromfetch_transaction
. The call is guarded behind the aforementionedIS_AUTOMATIC_REFUND_ENABLED
flag.Added
MEANINGFUL_MEMOS
constant. This is used to detect when automatic refund should be performed.Minor Changes
Added
AutomaticallyRefunded
toNotificationStatus
. This ensures that we do NOT duplicate refunds.Changed one parameter of
fetch_transaction
fromAccountIdentifier
toSubaccount
, because you cannot go "backwards" fromAccountIdentifier
toSubaccount
.Factored out the
memo
+icrc1_memo
unifying code which used to live intransaction_has_expected_memo
. Now, that code lives in a newget_u64_memo
function.Future Work
Added a couple of other helpers. One is
set_block_status_to_processing
. This could be used to reduce code duplication innotify_*
methods, but such refactoring is left to future PRs.References
This will be enabled by another PR.
We promised to do this in this forum post.
Closes NNS1-3573.
The other feature that we promised in that thread (use icrc1_memo) was implemented in an earlier PR.