Implement human-readable serde for Witness#1068
Implement human-readable serde for Witness#1068apoelstra merged 6 commits intorust-bitcoin:masterfrom
Witness#1068Conversation
d3b3168 to
ec9ca48
Compare
5e47fe4 to
2181c0a
Compare
|
Changes in force push:
|
src/blockdata/witness.rs
Outdated
There was a problem hiding this comment.
This allocates, however if we use collect_str it will be slower for default implementations because we can't reserve(). So I suggest not to worry about it at least for now.
src/blockdata/witness.rs
Outdated
There was a problem hiding this comment.
Please avoid as, use .into() instead.
There was a problem hiding this comment.
Sure thing, I think you told me this before. I must not have fully groked it then, so I went looking :) Is it because as can be lossy and from only does lossless conversions?
ref: https://stackoverflow.com/questions/48795329/what-is-the-difference-between-fromfrom-and-as-in-rust
There was a problem hiding this comment.
Yes, in this case as is guaranteed to be lossless but it's better to not have to manually check that and the property survives across refactors. (Such refactors almost certainly will not happen here but let's keep good habits, OK? :))
There was a problem hiding this comment.
Why this still contains as and was marked resolved? Also still uses -.
There was a problem hiding this comment.
Seems that fresh mountain air on my week off broke my brain, I thought we had a discussion about no using default '-' and I don't see that. Not to mention that the '-' is still there like you say. Anyways, I've removed it and use Unexpected::Unsigned when its not a char (like I remember you suggesting previously). Thanks for patiently, repeatedly pointing out my mistakes :)
src/blockdata/witness.rs
Outdated
There was a problem hiding this comment.
I think we could avoid allocations if we used custom visitor. That's why I originally suggested to call the one above HRVisitor so that the other one can be called BinaryVisitor (suggest better name please).
There was a problem hiding this comment.
Righto, I'll have a play with it.
There was a problem hiding this comment.
I must not be fully understanding where all the allocations are occurring. I came up with the code below but it seems to me that this code is going to contain the exact same number of allocations as line 343 above (one for each element, and the one outer vector).
fn visit_seq<A: serde::de::SeqAccess<'de>>(self, mut a: A) -> Result<Self::Value, A::Error>
{
let mut ret = Vec::new();
while let Some(elem) = a.next_element::<Vec<u8>>()? {
ret.push(elem);
}
Ok(Witness::from_vec(ret))
}What am I missing?
There was a problem hiding this comment.
I meant to build Witness as non-nested Vec directly. You need to use next_element_seed and a bit more machinery to support it. This example looks very similar to what we have here, you can pretty much copy it minus some generics (we have u8). Note that that example forgot to call reserve() in front of the inner for loop. Should have this:
if let Some(size_hint) = seq.size_hint() {
self.0.reserve(size_hint);
}There was a problem hiding this comment.
I had a good play with this, was educational. Its separate from this PR because its an optimisation, right? I think the correct way to go about it is merge this naive version (fixes the ugly serialization) and then create an separate issue/PR to do it as in the example you link. Would that be fair?
There was a problem hiding this comment.
I don't care if it's merged in this one or a separate one.
There was a problem hiding this comment.
Cool, I'll do it as a separate PR. Cheers.
9bf9591 Optimize Witness Serialization (DanGould) Pull request description: fix #942 > self.to_vec() allocates, it should be possible to avoid it - just feed the items into serializer. based on #1068 ACKs for top commit: Kixunil: ACK 9bf9591 apoelstra: ACK 9bf9591 Tree-SHA512: 14553dfed20aee50bb6361d44986b38556cbb3e112e1b4d9e3b401c3da831b6bdf159089966254cf371c225ae929fc78516c96a6114b40a7bc1fda7305295e4a
As is customary leave a line of white space between functions.
No need for a line of whitespace immediately starting an impl block.
Re-order the import statements in `witness` module to separate `crate` imports from dependency imports.
2181c0a to
4c1dfaf
Compare
|
I suspect that serializaiton could also avoid the |
apoelstra
left a comment
There was a problem hiding this comment.
ACK 4c1dfafcdd8284685fbb0bf880d3cb47bb46d541
|
@apoelstra It's not a clear win - if the serializer uses the default implementation we end up having slower code. I just posted to IRLO about this |
Kixunil
left a comment
There was a problem hiding this comment.
Were some changes lost by accident?
src/blockdata/transaction.rs
Outdated
There was a problem hiding this comment.
I think we should use assert_eq. I know changes to serde would break this but seems less bad than manually checking with funny flags.
There was a problem hiding this comment.
I decided to remove the test all together. I put it in the PR description in case anyone wants to verify that this PR works as advertised.
src/blockdata/witness.rs
Outdated
src/blockdata/witness.rs
Outdated
There was a problem hiding this comment.
Why this still contains as and was marked resolved? Also still uses -.
This also removes tests for JSON backward-compatible encoding. Human-readable encoding will be changed in the next commit and this will break backward compatibility, thus that part of the test is removed.
Previous implementations of Witness (and Vec<Vec<u8>>) serde serialization didn't support human-readable representations. This resulted in long unreadable JSON/YAML byte arrays, which were especially ugly when pretty-printed (a line per each byte). Co-authored-by: Tobin C. Harding <me@tobin.cc>
4c1dfaf to
a1df62a
Compare
|
Changes in force push:
|
9bf9591 Optimize Witness Serialization (DanGould) Pull request description: fix #942 > self.to_vec() allocates, it should be possible to avoid it - just feed the items into serializer. based on rust-bitcoin/rust-bitcoin#1068 ACKs for top commit: Kixunil: ACK 9bf9591 apoelstra: ACK 9bf9591 Tree-SHA512: 14553dfed20aee50bb6361d44986b38556cbb3e112e1b4d9e3b401c3da831b6bdf159089966254cf371c225ae929fc78516c96a6114b40a7bc1fda7305295e4a
…for `Witness` a1df62a Witness human-readable serde test (Dr Maxim Orlovsky) 68577df Witness human-readable serde (Dr Maxim Orlovsky) 93b66c5 Witness serde: test binary encoding to be backward-compatible (Dr Maxim Orlovsky) b409ae7 witness: Refactor import statements (Tobin C. Harding) e23d3a8 Remove unnecessary whitespace (Tobin C. Harding) ac55b10 Add whitespace between functions (Tobin C. Harding) Pull request description: This is dr-orlovsky's [PR](rust-bitcoin/rust-bitcoin#899) picked up at his permission in the discussion thread. I went through the review comments and implemented everything except the perf optimisations. Also includes a patch at the front of the PR that adds a unit test that can be run to see the "before and after", not sure if we want it in, perhaps it should be removed before merge. This PR implicitly fixes 942. To test this PR works as advertised run `cargo test display_transaction --features=serde -- --nocapture` after creating a unit test as follows: ```rust // Used to verify that parts of a transaction pretty print. // `cargo test display_transaction --features=serde -- --nocapture` #[cfg(feature = "serde")] #[test] fn serde_display_transaction() { let tx_bytes = Vec::from_hex( "02000000000101595895ea20179de87052b4046dfe6fd515860505d6511a9004cf12a1f93cac7c01000000\ 00ffffffff01deb807000000000017a9140f3444e271620c736808aa7b33e370bd87cb5a078702483045022\ 100fb60dad8df4af2841adc0346638c16d0b8035f5e3f3753b88db122e70c79f9370220756e6633b17fd271\ 0e626347d28d60b0a2d6cbb41de51740644b9fb3ba7751040121028fa937ca8cba2197a37c007176ed89410\ 55d3bcb8627d085e94553e62f057dcc00000000" ).unwrap(); let tx: Transaction = deserialize(&tx_bytes).unwrap(); let ser = serde_json::to_string_pretty(&tx).unwrap(); println!("{}", ser); } ``` Fixes: #942 ACKs for top commit: apoelstra: ACK a1df62a Kixunil: ACK a1df62a Tree-SHA512: d0ef5b8cbf1cf8456eaaea490a793f1ac7dfb18067c4019a2c3a1bdd9627a231a4dd0a0151a4df9af2b32b909d4b384a5bec1dd3e38d44dc6a23f9c40aa4f1f9
This is dr-orlovsky's PR picked up at his permission in the discussion thread.
I went through the review comments and implemented everything except the perf optimisations. Also includes a patch at the front of the PR that adds a unit test that can be run to see the "before and after", not sure if we want it in, perhaps it should be removed before merge.
This PR implicitly fixes 942.
To test this PR works as advertised run
cargo test display_transaction --features=serde -- --nocaptureafter creating a unit test as follows:Fixes: #942