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 listadresses #709

Merged
merged 1 commit into from
Nov 11, 2023
Merged

Conversation

pythcoiner
Copy link
Collaborator

@pythcoiner pythcoiner commented Sep 9, 2023

address #681

todo:

  • implement tests
  • update docs

edit: i'm really new to rust, don't hesitate to kick my ass when i write stupid code

src/commands/mod.rs Outdated Show resolved Hide resolved
@pythcoiner pythcoiner mentioned this pull request Sep 10, 2023
Copy link
Member

@darosior darosior left a comment

Choose a reason for hiding this comment

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

Approach ACK. Needs a bit more testing (and an entry in doc/API.md) but it's in good shape!

src/commands/mod.rs Outdated Show resolved Hide resolved
src/commands/mod.rs Outdated Show resolved Hide resolved
src/commands/mod.rs Outdated Show resolved Hide resolved
src/commands/mod.rs Show resolved Hide resolved
src/commands/mod.rs Outdated Show resolved Hide resolved
src/commands/mod.rs Outdated Show resolved Hide resolved
src/commands/mod.rs Outdated Show resolved Hide resolved
tests/test_rpc.py Show resolved Hide resolved
src/commands/mod.rs Outdated Show resolved Hide resolved
@pythcoiner pythcoiner force-pushed the get_all_adresses branch 4 times, most recently from 08d7f7a to 646c525 Compare September 12, 2023 08:40
@darosior
Copy link
Member

Let me know when this is ready for review by moving this out of draft / WIP. No rush!

@pythcoiner pythcoiner marked this pull request as ready for review September 12, 2023 18:31
@pythcoiner
Copy link
Collaborator Author

Let me know when this is ready for review by moving this out of draft / WIP. No rush!

i think it is now ;)

doc/API.md Outdated Show resolved Hide resolved
doc/API.md Outdated Show resolved Hide resolved
doc/API.md Outdated Show resolved Hide resolved
doc/API.md Outdated Show resolved Hide resolved
@pythcoiner
Copy link
Collaborator Author

thx @jp1ac4 for your review, comments have been addressed in 4e0bc0a

@@ -258,6 +282,14 @@ pub fn handle_request(control: &DaemonControl, req: Request) -> Result<Response,
}
"getinfo" => serde_json::json!(&control.get_info()),
"getnewaddress" => serde_json::json!(&control.get_new_address()),
"listaddresses" => {
let params = req.params.ok_or_else(|| {
Copy link
Collaborator

Choose a reason for hiding this comment

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

As the parameters are optional, I'm wondering if you could keep params as Option<Params> and pass that to list_addresses.

I'm able to run listaddresses without any parameters so I guess req.params is Some also in that case and it works fine, but not sure if there might be a situation where it is None.

@darosior may be able to help.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

you seems right, i wonder why Error::invalid_params is not triggered when call listaddresses w/o args? shouldn't it in that case?

Copy link
Member

Choose a reason for hiding this comment

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

That's most likely you tested with the CLI which always includes a params entry in the JSONRPC request. But that's not mandated by the JSONRPC2 specs.

I agree with @jp1ac4 this shouldn't error if params is None. You can take inspiration from how list_coins does this.

@pythcoiner pythcoiner changed the title [WIP] implement listadresses Implement listadresses Sep 16, 2023
@darosior
Copy link
Member

darosior commented Oct 7, 2023

Could you rebase and squash your commits into a couple ones? I'll review then.

@pythcoiner pythcoiner force-pushed the get_all_adresses branch 2 times, most recently from 3651896 to fbad20d Compare October 7, 2023 14:23
@pythcoiner
Copy link
Collaborator Author

I rebased and squash to 3 commits implement/test/fixes, feel free to tell me if you prefer I squash to a single one.

@darosior
Copy link
Member

darosior commented Oct 8, 2023

Having tests in a separate commit is fine. However having fixups in a separate commit than the one where issues were introduced creates needless churn and confusion.

That's fine for this time, but next time please squash the fixup commit(s) in the appropriate original commit(s).

Copy link
Member

@darosior darosior left a comment

Choose a reason for hiding this comment

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

Almost there, the main things are:

  • There is an off by one when count is not provided
  • Let's not crash on insane inputs
  • Let's not error if a params entry isn't given in the JSONRPC request, since all fields are optional

doc/API.md Outdated Show resolved Hide resolved
doc/API.md Outdated Show resolved Hide resolved
Comment on lines 317 to 318
let child = bip32::ChildNumber::from_normal_idx(index)
.expect("Failed to convert index to ChildNumber");
Copy link
Member

Choose a reason for hiding this comment

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

Could we error instead of crashing if a value greater than 2**31 - 1 is passed for count? It's an insane argument to give to the command, but it's nicer to never crash on insane inputs.

Let's add an InvalidAddressCount variant to the CommandError enum and use it here and above?

src/commands/mod.rs Outdated Show resolved Hide resolved
src/commands/mod.rs Outdated Show resolved Hide resolved
@@ -258,6 +282,14 @@ pub fn handle_request(control: &DaemonControl, req: Request) -> Result<Response,
}
"getinfo" => serde_json::json!(&control.get_info()),
"getnewaddress" => serde_json::json!(&control.get_new_address()),
"listaddresses" => {
let params = req.params.ok_or_else(|| {
Copy link
Member

Choose a reason for hiding this comment

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

That's most likely you tested with the CLI which always includes a params entry in the JSONRPC request. But that's not mandated by the JSONRPC2 specs.

I agree with @jp1ac4 this shouldn't error if params is None. You can take inspiration from how list_coins does this.

tests/test_rpc.py Outdated Show resolved Hide resolved
@pythcoiner
Copy link
Collaborator Author

comment have been adressed

@darosior
Copy link
Member

This comment wasn't addressed? #709 (comment)

@pythcoiner
Copy link
Collaborator Author

This comment wasn't addressed? #709 (comment)

right, it's done now

@@ -37,6 +37,24 @@ def test_getaddress(lianad):
assert res["address"] != lianad.rpc.getnewaddress()["address"]


def test_listadresses(lianad):
Copy link
Member

Choose a reason for hiding this comment

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

nit:

Suggested change
def test_listadresses(lianad):
def test_listaddresses(lianad):

Comment on lines +141 to +142
Self::InvalidAddressCount => write!(f, "Invalid address count, should be under 2^31-1"),
Self::InvalidAddressIndex => write!(f, "Invalid address index, should be under 2^31-1"),
Copy link
Member

Choose a reason for hiding this comment

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

Would be better to introduce a single enum variant, a general "invalid derivation index" which could be reused in the future.

Comment on lines +308 to +310
if start_index > (2u32.pow(31) - 1) {
return Err(CommandError::InvalidAddressIndex);
}
Copy link
Member

Choose a reason for hiding this comment

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

(Here and below) Ok, this works. But it would be much clearer to use ChildNumber::from_normal_idx's error or at the very least add a comment.

return Err(CommandError::InvalidAddressIndex);
}

let count = count.unwrap_or_else(|| receive_index.max(change_index) - start_index);
Copy link
Member

Choose a reason for hiding this comment

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

What if start_index is larger than the maximum of the receive and change indexes? We need to really be careful about underflows in this code.

Comment on lines +314 to +317
if count == 0 {
let out: Vec<AddressInfo> = Vec::new();
return Ok(ListAddressesResult::new(out));
}
Copy link
Member

Choose a reason for hiding this comment

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

It's a bit ugly to special case 0 here to avoid the checked_sub below to return None. Could get rid of the necessity for a checked_sub altogether by using an exclusive range ((x..y)) below instead of an inclusive one ((x..=y)).

@@ -860,6 +927,24 @@ impl GetAddressResult {
}
}

#[derive(Debug, Clone, Serialize)]
Copy link
Member

Choose a reason for hiding this comment

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

Would be nice to make it PartialEq, Eq too.

Comment on lines +1060 to +1061
#[test]
fn listaddresses() {
Copy link
Member

Choose a reason for hiding this comment

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

Would be good to check bounds here for hardened derivation index, overflows and underflows.

Comment on lines +144 to +147
.as_ref()
.and_then(|p| p.get(0, "start_index"))
.and_then(|i| i.as_u64())
.and_then(|i| i.try_into().ok());
Copy link
Member

Choose a reason for hiding this comment

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

We shouldn't silently ignore invalid parameters to listaddresses.

@darosior
Copy link
Member

I've addressed my comments here: https://github.com/darosior/liana/tree/get_all_addresses. Apparently i can't push them to your PR, so i'll open a follow-up..

@darosior darosior mentioned this pull request Nov 11, 2023
@darosior
Copy link
Member

See #808.

@darosior
Copy link
Member

ACK 2660b77 -- my requests are addressed in followup #808.

@darosior darosior merged commit 479efe7 into wizardsardine:master Nov 11, 2023
18 checks passed
darosior added a commit that referenced this pull request Nov 13, 2023
0812a12 jsonrpc: don't ignore invalid params to listaddresses (Antoine Poinsot)
d533820 commands: listaddresses cleanups (Antoine Poinsot)

Pull request description:

  This addresses my latest review from #709.

ACKs for top commit:
  jp1ac4:
    ACK 0812a12

Tree-SHA512: 6f708fd2f1aa2f229a5c78a35e363870ef390513cce10fc6a5938b49e6b7ee5be9205bc4566376750e4f7eeea404709ce6d8c7a29df15b9216b8dbcf4b4fed7e
@pythcoiner pythcoiner deleted the get_all_adresses branch January 13, 2024 23:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants