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
stdaddr: Introduce package for standard addrs. #2610
Conversation
fb6daae
to
31f8df8
Compare
This looks great. May i suggest naming the package |
That sounds good to me. We also need to decide on where to put it. I just put it under |
31f8df8
to
f3dc363
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.
I left two in-line comments, and then I have these three notes from my Readme review. I realize I'm not exactly the technical target audience for this package, but I'm trying to follow along for my own understanding. Here are my comments:
- You don't really define
script
in the Readme. I realize it's not really in the scope of this readme, but you asked for advice for how to make this primer more clear. Perhaps just some quick definitions or references would be helpful. I'm nominally aware of Bitcoin's Script, and aware that it uses opcodes for super concise and byte-efficient commands. That's the extent of my knowledge.- Is Decred's script the same as Bitcoin's, just with different opcodes?
- You don't really talk about opcodes until
Address Use in the Staking System
- You use
script
instead ofScript
. The capitalization seems like it might be more clear that you're referring to the Script system.
- I don't know what Hash160 is, even after reading the blurb about RIPEMD-160 hashes. It would be nice to link to a reference.
- I don't know what you mean by Version 0 addresses. I don't know much about address versioning, unless you're talking about things like Segwit or Taproot.
Also, in the PR commit message, Paragraph 2 has a typo:
"Specifically, it does not support or provide a clean path to enable support for different script versions and it the way they are handled in stake transactions is entirely non-intuitive."
Otherwise, it reads very well, and the motivation and improvement is very clear! Thank you.
5ed1fc4
to
06c4018
Compare
I've updated this to rename the package to the recommended |
@matthawkins90 Thanks for the feedback. It's always good to get a fresh pair of eyes! I'll comment inline, as your points are all valid, but, I did want to point out that, as you note, this is really aimed at developers who already have some background knowledge about the underlying concepts. If this were in a developer guide, I would put this type of information after sections which have already described how the transaction scripting language works which includes opcodes, as well as the notion of standard scripts.
I'll add a link to the
Yes.
Right. The underlying transaction scripts are really just a collection of opcodes. There is some assumed knowledge here. Again, I think having an initial link to the
Not sure I follow you here. Is there a specific instance you can point out? As far as I can tell, all of the references to scripts are indeed talking about scripts, whereas references to the scripting system specifically say scripting system. Maybe I missed some cases?
Good point. I'll add a link to the
That is likely because there currently is no real notion of versioned addresses since there is only the existing addresses (hence version 0). The plan in the future is to introduce a new version with a different encoding scheme. Also, perhaps more importantly, since addresses really just unpack to underlying scripts that enforce a set of constraints, and all software working with an address has to be able to produce scripts that are valid for a given script version, they effectively have a one-to-one correspondence with the underlying script version. It seems like it would be worthwhile to add a blurb about address versioning in the primer.
Fixed. |
06c4018
to
63de7c8
Compare
@matthawkins90 I believe I have addressed all of you feedback. See the diff of changes here. |
Thanks for the updates. Reading now!
Sorry for the confusion. This is incredibly nitpicky and inconsequential, so please let me know if this simply doesn't matter.
The main phrase I'm getting hung up on is "script version". So, examples:
|
371ed3c
to
43e7034
Compare
I've updated the generic decoding logic to implement a length check for determining if an address is probably a version 0 base58 address as well as slightly modified it a bit to be a bit more efficient when a new version is added as well as introduced some additional tests to cover the differences. |
@matthawkins90 Thanks for the clarification. I'll think on it a bit as I understand from your description why you find it confusing, though I'm not really sure that |
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.
Nicely done with great documentation 👍
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 looks great to me. The code is much easier to follow than the existing script creation code in txscript
and it makes sense to cleanly split out standard script creation from txscript
. The tests are excellent and make it straightforward to review the code for correctness as well. Just noticed a few typos.
43e7034
to
0a83984
Compare
@matthawkins90 After thinking about it a bit, I decided to go with "scripting language version" throughout which should hopefully address your points. I also changed the wording from |
0a83984
to
c06fe29
Compare
c06fe29
to
4257326
Compare
Just reviewed the README. As somebody with a low-medium level of familiarity of the topic, it reads well and goes into a good level of depth. ACK. |
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.
Excellent work! I also ran run_tests.sh
in every commit to assert the correct behavior.
Only noted two points for clarification.
@davecgh, really great work! Thanks for working to make this more approachable and understandable for people. |
edff0c1
to
3dabd6b
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.
🎉
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.
Amazing.
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 probably sounds wierd, but I can't get the example test to print out with go test --run=ExampleDecodeAddress -v
unless I add another fmt.Println()
somewhere else in the file. Not sure what it is.
edit: Oh, I see. It's not a test. Nevermind.
edit2: I cannot find much documentation on "package_test". Is it possible to have that print to stdout?
It's a testable example. |
I see! I don't know how I missed this part of golang testing. I see that the output must match what is under |
This corrects the generic public key address constructor to pass the actual serialized ed25519 public key to specialized constructor instead of incorrectly including the initial byte that identifies the signature suite and y bit oddness.
The current code for handling standard addresses implemented in dcrutil was written many years ago prior a wide variety of changes and several new features added by Decred. As a result, it entirely lacks support for some features and supports others in a roundabout and non-intuitive way. Specifically, it does not support or provide a clean path to enable support for different script versions and the way they are handled in stake transactions is entirely non-intuitive. Further, back when the original address code was implemented, it was necessary to implement script creation in the txscript package which led to the current design of providing methods such as txscript.PayTo{AddrScript,SStx,SStxChange}, and others, which need to type assert the specific concrete types of addresses in order to produce the necessary scripts. This, unfortunately, effectively negates the use of an interface to support generic addresses because it means callers, such as dcrwallet, are not able to implement their own types without somewhat invisibly breaking the script creation. Finally, the aforementioned blending of the address code into txscript has led to confusion regarding what is considered standard and what is considered consensus which has tripped up several contributors over the years. This is part of a series of commits that aims to resolve all of the aforementioned issues by introducing a new package named stdaddr which entirely reworks the way addresses are handled. For the time being, the package is introduced into the internal staging area for initial review. The following provides an overview of some of the key features of the new design: - Supports versioned addresses - Produces scripts directly via methods implemented on underlying types - Provides direct support for creation of the scripts necessary for the staking system - Uses a capabilities-based approach via interfaces so callers can cleanly and generically determine under what circumstances addresses can be used - Allows callers to create their own concrete address types without worrying about breaking the existing ones - Clearly denotes that addresses are a standardized construction that must not be used directly in consensus code In order to help ease the review process, this commit only contains the overall generic infrastructure without adding support for any specific address types. Each supported version 0 address type will be added in future commits.
This adds the overall infrastracture for decoding version 0 addresses along with associated testing infrastructure. Note that, in order to help ease the review process, this only adds the relevant infrastructure and does not yet support any version 0 address types. Each supported version 0 address type will be added in future commits. This is part of a series of commits to fully implement the stdaddr package.
This adds a new type to fully support version 0 pay-to-pubkey-ecdsa-secp256k1 addresses along with associated tests. This is part of a series of commits to fully implement the stdaddr package.
This adds a new type to fully support version 0 pay-to-pubkey-ed25519 addresses along with associated tests. This is part of a series of commits to fully implement the stdaddr package.
This adds a new type to fully support version 0 pay-to-pubkey-schnorr-secp256k1 addresses along with associated tests. This is part of a series of commits to fully implement the stdaddr package.
This adds a new type to fully support version 0 pay-to-pubkey-hash-ecdsa-secp256k1 addresses along with associated tests. This is part of a series of commits to fully implement the stdaddr package.
This adds a new type to fully support version 0 pay-to-pubkey-hash-ed25519 addresses along with associated tests. This is part of a series of commits to fully implement the stdaddr package.
This adds a new type to fully support version 0 pay-to-pubkey-hash-schnorr-secp256k1 addresses along with associated tests. This is part of a series of commits to fully implement the stdaddr package.
This adds a new type to fully support version 0 pay-to-script-hash addresses along with associated tests. This is part of a series of commits to fully implement the stdaddr package.
This adds benchmarks for decoding and generating the payment script for each supported version 0 address type. This is part of a series of commits to fully implement the stdaddr package.
3dabd6b
to
9d533c2
Compare
The current code for handling standard addresses implemented in
dcrutil
was written many years ago prior a wide variety of changes and several new features added by Decred. As a result, it entirely lacks support for some features and supports others in a roundabout and non-intuitive way.Specifically, it does not support or provide a clean path to enable support for different script versions and the way they are handled in stake transactions is entirely non-intuitive.
Further, back when the original address code was implemented, it was necessary to implement script creation in the
txscript
package which led to the current design of providing methods such astxscript.PayTo{AddrScript,SStx,SStxChange}
, and others, which need to type assert the specific concrete types of addresses in order to produce the necessary scripts. This, unfortunately, effectively negates the use of an interface to support generic addresses because it means callers, such asdcrwallet
, are not able to implement their own types without somewhat invisibly breaking the script creation.Finally, the aforementioned blending of the address code into
txscript
has led to confusion regarding what is considered standard and what is considered consensus which has tripped up several contributors over the years.This aims to resolve all of the aforementioned issues by introducing a new package named
stdaddr
which entirely reworks the way addresses are handled.It is split up into a series of commits to help ease the review process such that the initial generic infrastructure is introduced first, followed by the overall version 0 address decoding logic, then each supported version 0 address, followed by an example, and finally what I hope is a fairly complete
README.md
that describes the architecture. Comprehensive tests are included.For the time being, the package is introduced into the internal staging area for initial review.
The following provides an overview of some of the key features of the new design:
Finally, although the primary goal here is not optimization, this also significantly reduces the execution time and number of allocations needed to produce the payment scripts as can be seen in the following benchmarks: