New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix amino overhead computation for Tx #2792
Conversation
- also count the fieldnum / typ3 - add method to compute overhead per Tx - slightly clarify comment on MaxAminoOverheadForBlock - add tests
Codecov Report
@@ Coverage Diff @@
## develop #2792 +/- ##
===========================================
- Coverage 62.3% 62.28% -0.02%
===========================================
Files 212 212
Lines 17210 17141 -69
===========================================
- Hits 10722 10677 -45
+ Misses 5588 5566 -22
+ Partials 900 898 -2
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for fixing this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🏖
@@ -21,6 +21,8 @@ const ( | |||
|
|||
// MaxAminoOverheadForBlock - maximum amino overhead to encode a block (up to | |||
// MaxBlockSizeBytes in size) not including it's parts except Data. | |||
// This means it also excludes the overhead for individual transactions. | |||
// To compute individual transactions' overhead use types.ComputeAminoOverhead(tx types.Tx, fieldNum int). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️
@@ -118,3 +120,9 @@ type TxResult struct { | |||
Tx Tx `json:"tx"` | |||
Result abci.ResponseDeliverTx `json:"result"` | |||
} | |||
|
|||
func ComputeAminoOverhead(tx Tx, fieldNum int) int64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought you're going to write a godoc comment?)
- add a note about fieldNum = 1 - add forgotten godoc comment
877d219
to
c746d93
Compare
// as a field (this field number is repeated for each contained Tx). | ||
// If some []Tx are encoded directly (without a parenting struct), the default | ||
// fieldNum is also 1 (see BinFieldNum in amino.MarshalBinaryBare). | ||
func ComputeAminoOverhead(tx Tx, fieldNum int) int64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Protobuf is so silly :/, the type is getting prepended to every single element of the slice. Why wouldn't they just make a native concept of slices with a length prefix at the beginning :L.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Protobuf can actually behave as you'd expect it. But only for primitive types. bytes
doesn't seem to fall in this category (as it is length-delimited) ¯_(ツ)_/¯
Otherwise, you could do sth along the lines of:
message Data {
repeated bytes Txs = 1 [packed = true];
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:(, protobuf why you no treat bytes as primitives :(
Good to know though, thank you!
@@ -88,8 +87,12 @@ func IsPreCheckError(err error) bool { | |||
func PreCheckAminoMaxBytes(maxBytes int64) PreCheckFunc { | |||
return func(tx types.Tx) error { | |||
// We have to account for the amino overhead in the tx size as well | |||
aminoOverhead := amino.UvarintSize(uint64(len(tx))) | |||
txSize := int64(len(tx) + aminoOverhead) | |||
// NOTE: fieldNum = 1 as types.Block.Data contains Txs []Tx as first field. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the []Tx
relevant here? The mempool only ever deals in Tx
, not []Tx
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see, we need to encode the size of txs as they will appear in the block, not as they appear individually in the mempool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the fix. Nasty bug. We should add some tests in the state package that check that blocks made from txs that pass these filters are valid. That might have caught this sooner.
|
||
// ComputeAminoOverhead calculates the overhead for amino encoding a transaction. | ||
// The overhead consists of varint encoding the field number and the wire type | ||
// (= length-delimited = 2), and another varint encoding the length of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does (= length-delimited = 2)
mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wire-type is what we call Typ3_ByteLength
in amino, or, length-delimited in proto3, or, equal to 2
in both cases. Maybe that comment is too verbose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see. Yeh I would have been more explicit, like (2, in this case, for a length-delimited type)
but that's fine
Oops I need to fix the test |
Opened follow-up issue to write better test: #2806 |
* 'master' of https://github.com/tendermint/tendermint: (330 commits) Release/v0.26.1 (tendermint#2803) fix amino overhead computation for Tx (tendermint#2792) p2p: re-check after sleeps (tendermint#2664) check the result of `ps.peer.Send` before calling `ps.setHasVote` (tendermint#2787) p2p: AddressBook requires addresses to have IDs; Do not close conn immediately after sending pex addrs in seed mode (tendermint#2797) test AutoFile#Size (happy path) [autofile/group] do not panic when checking size openFile creates a file if not exist => ErrNotExist is not possible use our logger in autofile/group Add tests for ValidateBasic methods (tendermint#2754) [docs] improve organization of ABCI docs & fix links (tendermint#2749) p2p: peer-id -> peer_id (tendermint#2771) mempool: print postCheck error (tendermint#2762) Fix crypto/merkle ProofOperators.Verify to check bounds on keypath pa… (tendermint#2756) Mempool WAL is still created by default in home directory, leads to permission errors (tendermint#2758) mempool: ErrPreCheck and more log info (tendermint#2724) Release/v0.26.0 (tendermint#2726) [ADR] [DRAFT] pubsub 2.0 (tendermint#2532) validate reactor messages (tendermint#2711) TMHASH is 32 bytes. Closes tendermint#1990 (tendermint#2732) ...
adds a method to compute overhead per Tx which also counts the fieldnum / typ3
fixes #2789