Replication response size cap#440
Conversation
| size := quoromRoundSizeSlack | ||
|
|
||
| if q.VerifiedBlock != nil { | ||
| blockBytes, err := q.VerifiedBlock.Bytes() |
There was a problem hiding this comment.
Instead of Bytes() we can just have an instance method Size for all these sub-message types (Notarization, EmptyNotarization, etc.) and we can just call the Size() and it will recursively compute the size.
We don't want to serialize the block to bytes just to know the size of the block.
| // it is tens of bytes in practivce, 512 is a generous bound | ||
| const quoromRoundSizeSlack = 512 | ||
|
|
||
| func (q *VerifiedQuorumRound) EstimateSize() (int, error) { |
There was a problem hiding this comment.
I don't think we should have this method return an error. Ideally we would be able to estimate the size of a message without an error.
If we don't marshal the fields to bytes we can remove the error returned.
| } | ||
| return rawBlock.MarshalCanoto(), nil | ||
| } | ||
| func (p *ParsedBlock) Size() int { |
There was a problem hiding this comment.
type ParsedBlock struct {
metadata.StateMachineBlock
msm *metadata.StateMachine
}
Shouldn't the Size() just be a method of StateMachineBlock ?
If StateMachineBlock implements Size() then since ParsedBlock embeds StateMachineBlock, we get it implicitly.
There was a problem hiding this comment.
But here Size() doesn't measure a stateMachineBlock, it measure the RawBlock encoding of one, which is defined in the root package, not in msm (where stateMachineBlock is).
We can't move the Size() method to the msm package, because it doesn't import canotoTag_RawBlock__InnerBlockBytes and canotoTag_RawBlock__Metadata, and msm can't import them because the root already imports msm. (see https://github.com/ava-labs/Simplex/blob/main/external.go#L10)
There was a problem hiding this comment.
but the raw block is just an msm reference which isn't serialized, and the block.
So the Size() of the block should be an instance method of the block, in my opinion.
We can't move the Size() method to the msm package, because it doesn't import canotoTag_RawBlock__InnerBlockBytes and canotoTag_RawBlock__Metadata,
I don't understand.
There was a problem hiding this comment.
ok, in order to do that I just moved the Bytes() and the Size() methods to msm/block.go and they are a method of StateMachineBlock, also moved the RawBlock type there as well. And updated the RawBlock calls to be metadata.RawBlock.
What do you think? Does this work?
There was a problem hiding this comment.
I don't really care where the RawBlock lives, that's fine moving it there.
However, I'm not entirely convinced that using the canoto size cache is the right way to go, it seems to me very ad-hoc and overly dependent on canoto.
I think maybe a better solution would be to pre-compute the size of the StateMachineMetadata by marshaling it once the RawBlock is instantiated, and then Size() can just return the cached version.
There was a problem hiding this comment.
This would mean that Size can return to be in RawBlock as initially.
… into replication-limit
This PR introduces a size cap for the replication response messages so that avalanchego clients doesn't reject messages above the size limit.
Also added unit tests to test for the size limit.