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

Implement auto-cycling of Noble deposit addresses #4878

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

zbuc
Copy link
Member

@zbuc zbuc commented Oct 2, 2024

Describe your changes

This introduces changes to rotate Noble addresses based on an incrementing sequence number, as well as renames the pcli tx register-forwarding-account command as pcli view noble-address to provide a better experience:

$ pcli view noble-address 0 --channel channel-221 --noble-node http://noble-testnet-grpc.polkachu.com:21590

next one-time use Noble forwarding address for account 0 is: noble1...

please deposit funds to this address...

awaiting deposit...


💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫💫

registered Noble forwarding account with address noble1... to forward to Penumbra address penumbra1......

your funds should show up in your Penumbra account shortly

Issue ticket number and link

Closes #4873

Checklist before requesting a review

  • If this code contains consensus-breaking changes, I have added the "consensus-breaking" label. Otherwise, I declare my belief that there are not consensus-breaking changes, for the following reason:

    client-only

@zbuc zbuc requested a review from hdevalence October 2, 2024 01:01
@zbuc zbuc force-pushed the 4873_noble_rotation branch from c78757c to 5e8ea2b Compare October 2, 2024 14:56
@conorsch conorsch mentioned this pull request Oct 4, 2024
7 tasks
@cronokirby cronokirby added the pr-needs-testing Before being mergeable, this PR should add tests to the code, or have a human perform tests label Oct 7, 2024
Comment on lines +116 to +118
// This means the midpoint had a deposit in it waiting for registration.
// This will "flush" this unregistered address, however the user still wants a new one, so return the midpoint + 1.
Ok(mid + 1)
Copy link
Contributor

Choose a reason for hiding this comment

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

What about these cases:

  • Both sequence 23 and sequence 24 has funds in it. Binary search ends up hitting 23 first with a registration call. It succeeds in flushing the funds and then this function returns 24. We display that address to the user, but when we poll, we successfully flush that one too. Then the user attempts to deposit into that address. Will that deposit bounce as it's already registered?
  • What if we flush the max sequence number. Would this return max + 1?

Copy link
Member

Choose a reason for hiding this comment

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

  1. The program should check the address before it is displayed to ensure it's fresh (could have been used by another instance on another machine)

  2. Yes it should wrap around after 2^16 deposits

Copy link
Contributor

@grod220 grod220 Oct 15, 2024

Choose a reason for hiding this comment

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

Re point 2:

With a binary search, how there could be a notion of wrapping around? All sequence numbers will have been exhausted. Or are you suggesting once all are registered, we just offer up sequence 0 to re-use? Edit: or just pick one at random?

Copy link
Member Author

Choose a reason for hiding this comment

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

Wrap-around is hard to do without state tracking, so I think using a random sequence number (and potentially notifying the user that it's being re-used) is a good idea

Comment on lines +121 to +125
if left == mid || right == mid {
// We've iterated as far as we can, the next sequence number
// after the midpoint should be the next available sequence number.
return Ok(mid + 1);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

What if all sequence numbers have been registered? Will this return max + 1?

Comment on lines +234 to +238
match code {
9 => Ok(NobleRegistrationResponse::NeedsDeposit),
0 => Ok(NobleRegistrationResponse::Success),
19 => Ok(NobleRegistrationResponse::AlreadyRegistered),
_ => Err(anyhow::anyhow!("unknown response from Noble")),
Copy link
Contributor

Choose a reason for hiding this comment

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

On web, we don't get the code 19, but below when submitting a tx with the same sequence fyi. Looks like a cometbft mempool err.

{"code":-32603,"message":"Internal error","data":"tx already exists in cache"}

Comment on lines +62 to +76
async fn get_next_noble_sequence(
account: Option<u32>,
fvk: &FullViewingKey,
channel: &str,
noble_node: &Url,
) -> Result<u16> {
// perform binary search to find the first unused noble sequence number
// search space (sequence number) is 2 bytes wide
let left = 0u16;
let right = 0xffffu16;
let mid = (left + right) / 2u16;

// attempt to register midpoint
_get_next_noble_sequence(left, right, mid, noble_node, channel, fvk, account).await
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Here is a web implementation of binary search, inspired by this, but handles edge cases a bit differently: https://github.com/prax-wallet/prax/pull/215/files#diff-c569e62334fe6b19c6a1434837ca111daa9f4eb8287e7ab0c4925564c2ff44c2

@conorsch
Copy link
Contributor

The Noble testnet has changed since this PR was first authored. We believe the encoding error has been resolved, but there's a temporary blocker in that the current Noble testnet is charging gas fees for registration transactions. The Noble team is aware of this regression and intends to address it, so that registration txs are gas-less again. Once that's done, we're unblocked to test again.

@zbuc Can you write a detailed test plan in the meantime? Then we can functionally verify this PR is working against latest Noble testnet prior to merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr-needs-testing Before being mergeable, this PR should add tests to the code, or have a human perform tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Automatically rotate Noble deposit addresses
5 participants