Skip to content

Conversation

sipa
Copy link
Member

@sipa sipa commented Jul 13, 2020

This introduces a concept of "serialization parameters". Every serializer can define its own parameter type, and a value of that type must be provided when serializing/deserializing, e.g. using ss << WithParams(parameter, value), causing value to be serialized to ss, with parameter parameter. Note these parameters are automatically passed down the stack, so for example a vector can be serialized with a parameter, which will be available to all the elements' serializers.

In this PR, the feature is only used for CAddress serialization, but I plan to also convert SERIALIZE_TRANSACTION_NO_WITNESS in a follow-up. Eventually I hope to get rid of all GetVersion/GetType and replace it with this approach, which is type-safe (code won't compile if the correct parameter isn't passed somewhere), and avoids collisions between flags.

@fanquake fanquake added the P2P label Jul 13, 2020
@sipa sipa requested a review from ryanofsky July 13, 2020 04:43
@DrahtBot
Copy link
Contributor

DrahtBot commented Jul 13, 2020

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@practicalswift
Copy link
Contributor

Concept ACK

Getting rid of GetVersion/GetType and replacing them with a compile-time checked approach would be very nice.

Copy link
Contributor

@jnewbery jnewbery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK. Can be rebased on master now that #19486 is merged to drop the first two commits.

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK, no idea why it is not compatible with the live network

8d1b1df474db73d3010324f728cb8b7851036b4f

@dongcarl
Copy link
Contributor

Concept ACK as it will allow for a previously hacky solution to be neater. See #19477 for more details

Perhaps a worthwhile followup: Completing the example documentations of our serialization "helpers" (seems like there's already a few examples, but not all of them are documented)

@sipa sipa force-pushed the 202007_ser_options branch from 2149a5f to f00db5c Compare July 13, 2020 20:12
@sipa
Copy link
Member Author

sipa commented Jul 13, 2020

Rebased after #19486 merge. Addressed comments.

@maflcko
Copy link
Member

maflcko commented Jul 14, 2020

Looks like the fuzzers don't compile on some of the commits

@naumenkogs
Copy link
Member

Concept ACK.

@sipa sipa force-pushed the 202007_ser_options branch 2 times, most recently from 9ee7bd0 to f58fca6 Compare July 14, 2020 17:27
@sipa
Copy link
Member Author

sipa commented Jul 14, 2020

@dongcarl Agree - I've added more comments to explain the feature for now, but a more comprehensive overview of all the things the serialization framework supports would be a nice further improvement.

@MarcoFalke Hopefully fixed. I also added all variants of deserialization to the fuzzers.

@vasild
Copy link
Contributor

vasild commented Jul 15, 2020

Code coverage report for this PR from unit + functional tests (lines not modified by this PR are dimmed and files not modified by this PR are omitted from the report):

@jnewbery
Copy link
Contributor

jnewbery commented Jul 15, 2020

just net_processing.cpp:3942 is "interesting" (it is modified by this PR and not covered by tests).

That line is pretty much a no-op and could be removed. It's ensuring that we never send more than 1000 CAddress records in a single ADDR message. However, the ADDR message is populated from vAddrToSend, which itself is limited to 1000 entries (see the PushAddress() function). So we could just remove that entire if block (and potentially replace it with an assert(vAddr.size() <= 1000) after the for loop).

Copy link
Contributor

@jnewbery jnewbery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

concept ACK and code review ACK of the changes in protocol.h. The syntax/interface for WithParams() and SERIALIZE_METHODS_PARAMS seems reasonable, but I find it very difficult to understand the template code in serialize.h so I wasn't able to give it a thorough review.

@sipa sipa force-pushed the 202007_ser_options branch from 1f4ad39 to 68822be Compare July 16, 2020 23:55
Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 483ed45

Thanks for adding input validation to the hex/dec examples in the unit tests!

Copy link
Member

@jonatack jonatack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 483ed45 code review over several sessions this week, verified the build at each commit, ran the 3 address deserialization fuzz tests as a sanity check. Thanks for the unit test coverage -- a good addition and demonstrates use of the feature. Edit: am running a node with this branch.

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review ACK 483ed45.

This seems all right, but I think it's significantly more complex than it needs to because it is making serialization with params something that can be done in conjunction with using a formatter, instead of just a special case of formatting. Simplification along lines of 106d803 branch) seems to work (only ran tests locally).

uint32_t data;
bool ok;
if (fmt == BaseFormat::DEC) {
ok = ParseUint32(str, &data);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In commit "test: add tests that exercise WithParams()" (483ed45)

Think this needs to capitalize Int: ParseUInt32

@sipa
Copy link
Member Author

sipa commented Jul 22, 2020

@ryanofsky That approach works and is a lot simpler, but I think it misses the "automatic recursion" property I was hoping for, that you could e.g. serialize a CBlock with specified CTransaction parameters, and it would transparently pass those parameters down. Or a block could define its own type that can be converted to the CTransaction parameters type, but not need to anything beyond that.

Whether that's a desirable depends how much you treat a higher-level structure as openly containing the lower-level structure, but I think in general most of our complex serializable data structures are like that.

@maflcko
Copy link
Member

maflcko commented Aug 4, 2020

re-ACK 483ed45, though I did not review the serialize.h changes 🚤

Changes since last review:

  • Rebase
  • Added comments/doc
  • Fix "off-by-one" issue/typo bug in commit "12a5a3c032 Disentangle disk address version from client version"
  • Properly deserialize addrFrom without time (Bugfix in commit "21446c5b5d Use serialization parameters for CAddress serialization")
  • Fix and extend fuzzers
  • Add tests from vasild
Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

re-ACK 483ed457411d164ad71115dbfe1d2b4ff8b2e5f3, though I did not review the serialize.h changes 🚤

Changes since last review:
* Rebase
* Added comments/doc
* Fix "off-by-one" issue/typo bug in commit "12a5a3c032 Disentangle disk address version from client version"
* Properly deserialize addrFrom without time (Bugfix in commit "21446c5b5d Use serialization parameters for CAddress serialization")
* Fix and extend fuzzers
* Add tests from vasild
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUiZTQwAoa37uqI1WTtHnkBHX/T8VKa36Ba6GzwdKgCSLVl7uMr0qw5jL/UrHuG+
tHm4W6GH6fuxYSblm+r7ujigrAkD4/3gPsbOG5mHaYTDOtiL9/ZTHT4HT/nbyZBL
KmaVaLHihfZy8NS05IG8y4sB97ZWXmiAak4An6NdfmjtB5ahWVH5HuLxLERIM7nb
yLjW/5GVbnnMvhirK/nyMcAAXSlTY5twmjT2LYWQ0TnJnNF0djY0VMkvNF8RrvgZ
k3zVnE0J+MW5mv2KcKRCYouGXc+WK777s5gc7bVOfP0J0So9i20LP1pFGqdR+FhV
0WF0aO27EJVePxev36zdaF4CuEFadP99NN5fKnY6rUwpd7+3hIRWZOH2958bbaSH
3oE+M5tLKd+qsAIZ+Lz7W3XU/oK9DE3v8YRasuLzgAFXoiZVkYnISWp/N+FZv+/6
rhAFSyF45HGFkEAa40KdzPV/aT+LWi9UnZe+wa1RtOoiM25jDMTbyLBJiJNz3EoT
vjuegm6r
=lpi2
-----END PGP SIGNATURE-----

Timestamp of file with hash c6299c40a36d62d1a32997018080b37d4feeef88382e17059f749fec43043e26 -

@maflcko
Copy link
Member

maflcko commented Aug 4, 2020

Note to myself, if this gets merged: It would be good to remove the now unused protocol version includes. I.e.

commit 7ffff5b3237fa418637d30ddb59534ab47d3f610 (HEAD)
Author: MarcoFalke <falke.marco@gmail.com>
Date:   Tue Aug 4 14:58:25 2020 +0200

    Remove unused protocol version header from protocol.h

diff --git a/src/bench/rpc_blockchain.cpp b/src/bench/rpc_blockchain.cpp
index 4b45264a3c..09bfcb60a5 100644
--- a/src/bench/rpc_blockchain.cpp
+++ b/src/bench/rpc_blockchain.cpp
@@ -8,6 +8,7 @@
 #include <rpc/blockchain.h>
 #include <streams.h>
 #include <validation.h>
+#include <version.h> // For PROTOCOL_VERSION
 
 #include <univalue.h>
 
diff --git a/src/protocol.h b/src/protocol.h
index a564508f89..58669e20b5 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -14,7 +14,6 @@
 #include <primitives/transaction.h>
 #include <serialize.h>
 #include <uint256.h>
-#include <version.h>
 
 #include <stdint.h>
 #include <string>

and

commit 4550d37e268e7ffe34b3f5ea11d6b3f231d9065a
Author: MarcoFalke <falke.marco@gmail.com>
Date:   Tue Aug 4 12:56:55 2020 +0200

    Remove unused protocol version header from undo.h

diff --git a/src/undo.h b/src/undo.h
index a98f046735..1fb9ac0688 100644
--- a/src/undo.h
+++ b/src/undo.h
@@ -11,7 +11,6 @@
 #include <consensus/consensus.h>
 #include <primitives/transaction.h>
 #include <serialize.h>
-#include <version.h>
 
 /** Formatter for undo information for a CTxIn
  *

@DrahtBot
Copy link
Contributor

🐙 This pull request conflicts with the target branch and needs rebase.

Want to unsubscribe from rebase notifications on this pull request? Just convert this pull request to a "draft".

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still needs rebase (trivial)

{
SER_READ(obj, obj.nTime = TIME_INIT);
int nVersion = s.GetVersion();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One include can now be removed, see #19503 (comment)

@jonatack
Copy link
Member

Needs rebase.

@vasild
Copy link
Contributor

vasild commented Oct 22, 2020

This would resolve #19477.

Also, ADDRV2_FORMAT could be replaced with the technique introduced in this PR.

@maflcko
Copy link
Member

maflcko commented Nov 25, 2020

Could also use LIFETIMEBOUND as per #19387 (comment)?

@DrahtBot
Copy link
Contributor

There hasn't been much activity lately and the patch still needs rebase. What is the status here?
  • Is it still relevant? ➡️ Please solve the conflicts to make it ready for review and to ensure the CI passes.
  • Is it no longer relevant? ➡️ Please close.
  • Did the author lose interest or time to work on this? ➡️ Please close it and mark it 'Up for grabs' with the label, so that it can be picked up in the future.

@maflcko
Copy link
Member

maflcko commented Dec 15, 2021

@sipa Let us know if someone should pick this up. I might take a stab at it.

@sipa
Copy link
Member Author

sipa commented Dec 19, 2021

@MarcoFalke Not going to work on this for the time being.

@fanquake
Copy link
Member

fanquake commented Aug 8, 2022

Removing up for grabs as this has mostly been picked up. i.e #25284.

@bitcoin bitcoin locked and limited conversation to collaborators Aug 8, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.