Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
this PR is best reviewed one commit at a time.
This introduces a new way of serializing compressed CLVM incrementally. This relies on a new feature in
ObjectCache
, to provide a "stop_token". This is the first commit. The second commit introduces aSerializer
object that can be fed CLVM structures, incrementally, via itsadd()
function.Use case
This is intended to be used for serializing block generators in compressed form until we fill the block cost. Compression introduces a challenge in predicting the size of the generator, and hence the byte cost. The
Serializer
in this PR allows us to add one spend bundle at a time until we exceed the cost limit, and then undo adding the last spend bundle.ObjectCache
The object cache maps
NodePtr
to serialized length and tree hash for every node we serialize. This let us look up duplicate sub-trees and reference them rather than repeating them in the serialized form. With the incremental serialization, we need a way to indicate that we can't compute the tree hash (or serialized length) because the sub tree contains the sentinel (calledstop_token
in the context ofObjectCache
).We simply return
None
in this case, as if the node is not in the cache. The serializer also need to support some nodes not having a tree hash (or serialized length).Serializer
The optional
sentinel
NodePtr
indicates where the serialization should suspend and return. The serialization is resumed by callingadd()
again, with the subtree that goes in the location of the sentinel in the previous call.The call to
add()
can be undone by using theUndoState
returned byadd()
and callrestore()
on theSerializer
.Limited compression
Since we can't compute tree hashes of structures where parts of it were added incrementally, there are some (contrived) cases where the one-pass serialization does a better job. However, I don't believe this would ever happen in a block generator (only if we had identical spends repeated multiple times). There is a test case covering this.
fuzzers
The incremental serialization has a fuzzer that:
add()
, in two steps