Skip to content

Method of deciding amino overhead of tx in ReapMaxBytesMaxGas is wrong #2789

@yutianwu

Description

@yutianwu

I wrote a test for amino overhead of tx:

func TestAmino(t *testing.T) {
	txs := []types.Tx{
		[]byte{1, 2, 3},
		[]byte{1, 2, 3},
	}
	var totalBytes int64 = 0
	for _, tx := range txs {
		aminoOverhead := int64(amino.UvarintSize(uint64(len(tx))))

		totalBytes += aminoOverhead + int64(len(tx))
	}

	bz, _ := cdc.MarshalBinary(txs)
	println("len: ", len(txs), "\nexpected length: ", totalBytes, "\nactual length: ", len(bz), "\ndiff: ", (int64(len(bz)) - totalBytes))
}
/*
=== RUN   TestAmino
len:  2 
expected length:  8 
actual length:  11 
diff:  3
--- PASS: TestAmino (0.00s)
PASS
*/

The underlying reason is amino.UvarintSize forget encodeFieldNumberAndTyp3 which will be called in marshal list slice. So we add one extra byte in every tx when marshaling real txs and that's why we have a diff in the test.

It will cause consensus failure because the actual block size exceeds the max block size for the error deciding amino overhead of txs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C:consensusComponent: ConsensusC:mempoolComponent: MempoolT:bugType Bug (Confirmed)T:securityType: Security (specify priority)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions