Adds a dev dep on bincode crate, for testing serialization.
serializes Digest as hex, but only for human-readable formats like json.
Adds FromHexDigestError error enum
Adds TryFrom<&[u8]> for Digest, which is used by ::try_from_hex()
Adds tests for hex encoding and decoding
Adds tests for bytes --> Digest --> bytes roundtrip.
Note that some hex tests and the bytes roundtrip tests are presently failing due to issue #195, which needs to be resolved. All tests now pass but some inputs that would cause a failure are commented out and/or test is made #[should_panic], with a reference to #195.
The hex functions will be useful for a block explorer and probably many other use-cases down the road. It is not strictly necessary to have these fn inside twenty-first, but makes life easier for api users and provides a consistent way to encode/decode Digests for end-users to see throughout neptune ecosystem.
Also the TryFrom<&[u8]> seems generally useful. While it doesn't have dedicated test(s), it has test coverage as it is used by ::try_from_hex().
Motivation: I've begun work on a neptune block explorer and I quickly realized that Digests are heavily used as user-facing identifiers within the neptune system. In particular both blocks and utxos are identified by Digest and are key components of the block explorer and its RPC API which is built using REST (JSON). When using the REST API, the browser would display Digests embedded in other stuctures, eg BlockInfo in a comma separated format, eg:
This looks a bit intimidating and is not friendly for copy paste. If I do want to copy/paste it, I cannot just double-click because that will only highlight one of the 5 numbers [1], and if I manually select it, should I include the "[..]" brackets or not? It's unwieldy.
With this PR, the equivalent JSON data looks like:
this encoding uses fewer bytes, so its less data over the wire.
The value is easy to copy/paste.
It looks similar to a transaction id or block hash in bitcoin, which "crypto" users are already familiar with.
It does not look like an address, so should not be confused with one.
note: (3) and (4) were considerations for using a simple hex encoding instead of bech32 which is more commonly used for addresses.
It would be awkward for client applications such as a block-explorer to hex encode Digests embedded in data structures returned from neptune-core's API. It is possible using serde, but would probably require tediously wrapping each type with a newtype and then manually implementing Serialize and Deserialize for each newtype. ugh. Its much simpler and consistent to do it in one place and have some proper tests around it.
I realized however that we should not be hex encoding Digests that are being serialized with bincode, eg for storage in the DB. For this reason, the custom Serialize and Deserialize impls only use hex encoding if the output format identifies as human-readable. Unit tests are included that verify both json and bincode usage.
BREAKING CHANGE: The serialization change is a breaking change for neptune-core because .dat files (eg used by the wallet) contain JSON data. The new code will not read a pre-existing .dat file correctly. However the new code can still read levelDB databases because serialization is unchanged for binary formats such as bincode.
Note also that this PR does NOT change impl Display for Digest. It still displays 5 u64 joined by commas. I would prefer that it display hex also for consistency between log-files and RPC JSON, urls, etc, but a request was made to keep it that way, so we do.
[1] I've observed that in github's textbox's using brave I actually can double click a CSV value and get the entire string. However that has not been my experience with other browsers, cli terminals, etc in the past. Testing now, I find that in firefox and konsole, double-clicking CSV values selects a sub-value, while in brave and xfce4-terminal the entire string is selected. So behavior seems to be improving but is still inconsistent between apps.
coverage: 97.324% (+0.1%) from 97.178%
when pulling fe1df97ee2ccd831ba6dee62065a5b69f14ae209 on digest_hex_encode_and_decode_pr
into 2a331dd3267f53d04b3669d47eb0b54f04092e54 on master.
Adds Digest::to_hex() and Digest::try_from_hex().
Also:
hex
crate.Note that some hex tests and the bytes roundtrip tests are presently failing due to issue #195, which needs to be resolved.All tests now pass but some inputs that would cause a failure are commented out and/or test is made #[should_panic], with a reference to #195.The hex functions will be useful for a block explorer and probably many other use-cases down the road. It is not strictly necessary to have these fn inside twenty-first, but makes life easier for api users and provides a consistent way to encode/decode Digests for end-users to see throughout neptune ecosystem.
Also the
TryFrom<&[u8]>
seems generally useful. While it doesn't have dedicated test(s), it has test coverage as it is used by ::try_from_hex().Motivation: I've begun work on a neptune block explorer and I quickly realized that Digests are heavily used as user-facing identifiers within the neptune system. In particular both blocks and utxos are identified by Digest and are key components of the block explorer and its RPC API which is built using REST (JSON). When using the REST API, the browser would display Digests embedded in other stuctures, eg
BlockInfo
in a comma separated format, eg:This looks a bit intimidating and is not friendly for copy paste. If I do want to copy/paste it, I cannot just double-click because that will only highlight one of the 5 numbers [1], and if I manually select it, should I include the "[..]" brackets or not? It's unwieldy.
With this PR, the equivalent JSON data looks like:
Note that:
note: (3) and (4) were considerations for using a simple hex encoding instead of bech32 which is more commonly used for addresses.
It would be awkward for client applications such as a block-explorer to hex encode Digests embedded in data structures returned from neptune-core's API. It is possible using serde, but would probably require tediously wrapping each type with a newtype and then manually implementing Serialize and Deserialize for each newtype. ugh. Its much simpler and consistent to do it in one place and have some proper tests around it.
I realized however that we should not be hex encoding Digests that are being serialized with bincode, eg for storage in the DB. For this reason, the custom Serialize and Deserialize impls only use hex encoding if the output format identifies as human-readable. Unit tests are included that verify both json and bincode usage.
BREAKING CHANGE: The serialization change is a breaking change for neptune-core because .dat files (eg used by the wallet) contain JSON data. The new code will not read a pre-existing .dat file correctly. However the new code can still read levelDB databases because serialization is unchanged for binary formats such as bincode.
Note also that this PR does NOT change
impl Display for Digest
. It still displays 5u64
joined by commas. I would prefer that it display hex also for consistency between log-files and RPC JSON, urls, etc, but a request was made to keep it that way, so we do.[1] I've observed that in github's textbox's using brave I actually can double click a CSV value and get the entire string. However that has not been my experience with other browsers, cli terminals, etc in the past. Testing now, I find that in firefox and konsole, double-clicking CSV values selects a sub-value, while in brave and xfce4-terminal the entire string is selected. So behavior seems to be improving but is still inconsistent between apps.