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
Make Map trait private #752
Make Map trait private #752
Conversation
Not knowledgeable about the topic, structure of the code looks fine. Tests (as a separate commit) would be really helpful. |
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.
ACK 3582f69
concept ACK making this an error. I'm not sure if there are any scenarios where the user might want to remove or replace keys in this map (IIRC the combine
logic has some interesting stuff here where if it sees two different paths in one spot, it will always use the longer of the two), but the current "silently replace" behavior is surprising and inconsistent with how we handle e.g. proprietary keys.
I really like the structure of this PR. These cleanups are great. Thanks!
3582f69
to
39614a0
Compare
I tried something new; after your comment @apoelstra over here I've been thinking how to best get docs fixes in in the least invasive manner. I added a couple of patches to the PR that do docs improvements to the code already being touched by the PR. |
@Kixunil I can't really work out what needs testing here. The new logic in this PR is trivial, instead of putting foo in one map put it in another one - no point testing that really. Is there something specific you had in mind. Now whether the logic is correct or not is another matter :) |
b76e370
to
4158b23
Compare
My understanding was that it was previously wrong behavior and now it's fixed so write a test that fails for previous code and doesn't for the fixed version. This would make it less likely that future changes break it again. |
Lol! So, there was not actually a behavioural bug at all then. (Indeed, the existing ACK this PR even though it is now purely a cleanup/refactoring PR. |
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.
ACK 4158b23
Can you change the PR title to reflect its current contents? |
src/util/psbt/map/global.rs
Outdated
|
||
Ok(()) | ||
fn insert_pair(&mut self, _: raw::Pair) -> Result<(), encode::Error> { | ||
// This method is only called during deserialization, for PSBT the insertion-like logic is |
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 don't understand this comment, therefore I suspect it could be made more clear. Please remember that it's more necessary and helpful for people who do not understand what is going on, than to people that already do.
I understand that you figured out that this is never used, but I just don't understand why it is never used. And (often recrusive) "why" is the most important question to answer. Is it some accident, or are there deeper fundamental reasons behind it?
BTW. Implementation of a trait(interface) method that returns a "not implemented/needed" error is often a sign that the interface is incorrect. Possibly trait Map
should be split into trait Map
and trait MapMut : Map
or something (named like DerefMut
)
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 suspect the reason is, as you say, that this Map
trait tries to generalize over the different PSBT components but actually they have different logic.
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.
Thanks for your comments @dpc, I'll have a bit more of a play with this and see what I can come up with.
Changing the |
4158b23
to
68dc0b1
Compare
@dpc is totally correct, returning First 4 patches were untouched, please re-review @apoelstra at your leisure since this is not a bug anymore (label can probably be removed from #576). |
src/util/psbt/map/mod.rs
Outdated
pub use self::output::{Output, TapTree}; | ||
|
||
/// A trait for inserting into a PSBT key-value map. | ||
pub(super) trait Insert { |
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.
Not strong feelings about it, but having two names so different does not seem idiomatic (in a sense the e.g. standard library doesn't do that, AFAICT).
https://doc.rust-lang.org/std/ops/trait.DerefMut.html is a best example, but not exactly like what is happening here.
At very least it seems MapInsert
+ Map
seems to tie the two together.
Also, unless there's a good use-case for maps one can insert to but not get, trait MapInsert : Map
would help the code using these, as T : MapInsert
will imply T: Map
which will save some typing when both reading and writing is used.
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.
Thanks for your input @dpc, I ended up going with @apoelstra's suggestion below and making insert_pair
into functions.
I'm alright with 68dc0b1 but I'm not convinced that the My feeling is that GIven that |
Will work in the comments above and re-spin. |
861f08a
to
6041461
Compare
re-based on |
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.
ACK 6041461
Looks like a pretty annoying rebase lol.
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.
src/util/psbt/map/global.rs
Outdated
} | ||
} else { | ||
return Err(Error::DuplicateKey(pair.key).into()) | ||
pub fn consensus_decode_global<D: io::Read>(d: D) -> Result<PartiallySignedTransaction, encode::Error> { |
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.
Why remove the pub(crate) visibilty? This is a now public function inside a private mod.
Would it be better to have a pub(crate) or pub(in Path
)? I don't know if pub(in path) is supported in MSRV.
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.
Fair point, I tried with pub(in path)
. Seems my new shell function to build with 1.29 doesn't work today so I'm relying on CI to see if it works.
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.
The first time in my rust experience I finally see the case for this strange in path
visibility. Usually you need a cross-mod visibility and in path
is not applicable there...
33f7b30
to
eccb549
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.
ACK eccb549
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.
Several questions/issues - pls see comments
src/util/psbt/map/input.rs
Outdated
btree_map::Entry::Occupied(k) => { | ||
return Err(Error::DuplicateKey(k.key().clone()).into()) | ||
} | ||
btree_map::Entry::Vacant(empty_key) => {empty_key.insert(raw_value);} |
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.
nit: very unusual formatting not used elsewhere in this library. I will argue to keep the original one in this variant
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.
Ha! Yes this is indeed strange syntax, it was here before me, I also had to look at it twice. Now it has caught you also I'll change them all. FTR the reason is so that the match arm does not return anything, this cannot be done on a single line without this strange usage of braces.
src/util/psbt/map/global.rs
Outdated
} | ||
} else { | ||
return Err(Error::DuplicateKey(pair.key).into()) | ||
pub fn consensus_decode_global<D: io::Read>(d: D) -> Result<PartiallySignedTransaction, encode::Error> { |
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.
The first time in my rust experience I finally see the case for this strange in path
visibility. Usually you need a cross-mod visibility and in path
is not applicable there...
src/util/psbt/map/global.rs
Outdated
impl PartiallySignedTransaction { | ||
pub(crate) fn consensus_decode_global<D: io::Read>(d: D) -> Result<Self, encode::Error> { |
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 will argue not to change the function into a global one (even with limited visibility).
The whole concept of associated methods not taking self
is about namespacing - and I do not see a reason to introduce a large BLOB of consensus-critical code change just to reformat things and have a namespace as a part of a function name and not struct abstraction.
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.
Fair point, thanks. I've removed the patch that made this change. That also requires removing the in path
patch also (FTR its the first time I've ever seen it either, I had to look up how to do it :)
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.
PSBT is not consensus code.
Dropped two patches from this PR and force pushed. I'll have to ask you to re-ack please @apoelstra (gee that's the fifth one for you now, sorry about that). |
eccb549
to
bf09d75
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.
ACK bf09d75
Needs rebase again :( |
bf09d75
to
112169c
Compare
Apart from that just rebased on master. Please re-ack @apoelstra and accept my nomination for PR with the most re-acks :) |
These imports are unusually placed, from the code comment it seems the reason is stale. Move imports to top of file as is typical.
Refactor the match arms to make the code around the key used for map look up easier read. Refactor only, no logic changes.
Mildly improve the docs by adding full stops to every rustdoc comment.
Improve the function rustdocs in the `psbt::map` module by: - using third person tense as is idiomatic in the Rust ecosystem - using rustdoc `///` not code comments `//` for methods - Use `# Return` section for documenting return values Done for this module only as part of a PR fixing code within this module.
The `Map` trait has been deemed confusing and not that useful to users of the library, we still use it internally within the `psbt` module though so make it visible only in `psbt` and `psbt::map`.
The method implementation of `insert_pair` is currently not used for `PartiallySignedTransaction`. Having an implementation available is deceiving. Delete the unused `insert_pair` code from `PartiallySignedTransaction` (dead code). Make the `insert_pair` methods from `Input` and `Output` be standalone functions.
112169c
to
dfd8924
Compare
Fixed error I introduced while re-basing ( |
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.
ACK dfd8924
/// Returns the inner as Err if it is not a complete tree | ||
/// Converts a [`TaprootBuilder`] into a tree if it is complete binary tree. | ||
/// | ||
/// # Return |
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.
nit: AFAIR it is usually named "Returns"
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.
doh, you got me! I'm going to leave it as is for 2 reasons
- Constant docs fixes are high on my priority list while I'm finding my feet in this project, so this will get done
- This PR has been doing cycling for ages and now has 2 acks, I'll do a follow up
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.
no, for sure do not update it discarding 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.
Cheers
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.
ACK dfd8924
(6 commits, for future reference ... range-diff is easier to run if you know this value)
The
Map
methodinsert_pair
is never called forPartiallySignedTransaction
. Separate the method into its own trait (Insert
) and delete dead code. The dead code contains the alleged bug in #576.Map
trait private to thepsbt
modulePatch 6: Makeconcensus_decode_global
method into a function76: Pullinsert_pair
method out ofMap
trait into newly createInsert
traitResolves: #576
(Title of PR is
Make Map trait private
because that is the API break.)