-
Notifications
You must be signed in to change notification settings - Fork 217
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
Tighten criteria for accepting Shelley or Byron addresses in REST API #3019
Conversation
97da63f
to
a9bf986
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.
Thank-you for making this PR!
I've had a look through, and it seems very reasonable. Though I have a question and a couple of small suggestions. (See comments.)
Thanks!
tryBech32 text = do | ||
(_, dp) <- either (const Nothing) Just (Bech32.decodeLenient text) | ||
dataPartToBytes dp | ||
tryBech32 = fmap CA.unAddress . CA.fromBech32 |
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.
By following CA.fromBech32
to its definition, I think I have confirmed that fromBech32
does indeed also use Bech32.decodeLenient
. However, I just want to check: do we have regression test coverage to warn us if this ever changes?
(I ask, because it's just inside the realm of possibility that someone might change the definition of CA.fromBech32
to use Bech32.decode
, rather than its more lenient 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.
Hm. I'm not sure if we should check this, for two reasons:
- The address format is standardized in CIP-0019 which lists the
cardano-addresses
package as a reference implementation. So, regardless of howCardano.Address.fromBech32
is implemented, it must be correct — by virtue of being a reference. 😅 - Using
Bech32.decode
instead ofBech32.decodeLenient
would actually not be a regression — as far as the definition and error correcting properties of the Bech32 encoding are concerned. 🙈 (BIP-0173: "A Bech32 string is at most 90 characters long and consists of […]"). Shelley addresses are typically 57 bytes in length (1 byte header + 28 bytes payment part + 28 bytes delegation part), so that would work out. The big exception are pointer addresses which can be arbitrarily long, but of which there are only a handful of instances on mainnet. 🙈
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.
Oh wait. Even the regular Shelley addresses would not quite fit into the 90 character limit, as 57 bytes = 456 bits = 92.5 * (5 bits), and one character encodes 5 bits.
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 have added a test that covers Shelly addresses with delegation part; these will start to fail if the 90 character limit is enforced. In this way, we are testing functionality while covering the formalities.
db395be
to
dace3d1
Compare
Thanks for your review, Jonathan! 😊 Will merge unless there are further objections. |
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.
Would it be possible to add a note to the swagger API doc, just to make clear the decoding behaviour to users?
dace3d1
to
543e7a7
Compare
543e7a7
to
217c3cc
Compare
bors r+ |
3019: Tighten criteria for accepting Shelley or Byron addresses in REST API r=HeinrichApfelmus a=HeinrichApfelmus ### Summary It has become established usage that Byron addresses are associated with the Base58 encoding while Shelley addresses are associated with the Bech32 encoding. To catch more user errors, we now enforce this usage more strictly. Specifically, * Base58 encoded addresses are assumed to be Byron addresses and are additionally deserialized to CBOR to check whether they comply with the Byron address binary format. * We no longer accept Base16 encoded addresses. The swagger documentation has already highlighted that only Base58 and Bech32 are accepted. To avoid loss of funds, we strongly recommend to use Shelley addresses and the Bech32 encoding, as this encoding includes error detection and is more robust against misspellings and truncations. Relevant standards: [CIP 19 — Cardano addresses](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0019). ### Comments (EDIT: correction) * Ideally, lay users would only see a single canonical version of every address. Unfortunately, we are not quite there yet, and this PR is only a partial improvement. For example, * Bech32-encoded addresses can represent Byron addresses instead of Shelley addresses. These would be shown in Base58 encoding in the blockchain explorer. * A sequence of bytes which is too long to be a valid Shelley address, but has a header-byte that indicates a Shelley address, may be truncated to the proper size. Put differently, seemingly invalid addresses are mapped to valid ones. Fortunately, the error correction inherent to Bech32 and reserving the Base58 encoding for Byron addresses (implemented in this PR) make this less likely to occur through user mistake. * A general clean up of our address data types would be nice, but is out of scope for this pull request. ### Issue Number ADP-1033, ADP-1280 Co-authored-by: Heinrich Apfelmus <[email protected]>
Build failed:
I believe this is |
0424900
to
320bc22
Compare
, ( "wildcards", T.unpack wildcardsWalletName, parseErr ) | ||
, ( "arabic", T.unpack arabicWalletName, encodeErr ) | ||
, ( "kanji", T.unpack kanjiWalletName, encodeErr ) | ||
, ( "polish", T.unpack polishWalletName, encodeErr ) | ||
, ( "[]", "[]", encodeErr ) | ||
, ( "no address", "", encodeErr2 ) | ||
, ( "no address", "", encodeErr ) |
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.
Maybe it would be actually good to add addresses from the issue to that list?
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.
For reasons of privacy, I suppose that we do not want to add the addresses from the issue. However, I have added a randomly generated Base58 string that is not a valid Byron address.
Strictly speaking, the Bech32 standard defines that the encoded sequence may not be longer than 90 characters — but Shelley addresses can be longer than that. We can cover this case with a test that looks more at functionality and considers addresses with delegation part. Also changes suggested during review and additional tests. Co-authored-by: Jonathan Knowles <[email protected]>
320bc22
to
1461cc3
Compare
bors r+ |
Build succeeded: |
Summary
It has become established usage that Byron addresses are associated with the Base58 encoding while Shelley addresses are associated with the Bech32 encoding.
To catch more user errors, we now enforce this usage more strictly.
Specifically,
To avoid loss of funds, we strongly recommend to use Shelley addresses and the Bech32 encoding, as this encoding includes error detection and is more robust against misspellings and truncations.
Relevant standards: CIP 19 — Cardano addresses.
Comments
(EDIT: correction)
Issue Number
ADP-1033, ADP-1280