Skip to content

Commit

Permalink
optimize event deserialization
Browse files Browse the repository at this point in the history
  • Loading branch information
uprendis committed Jun 26, 2022
1 parent d2a00f5 commit 52613a1
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 9 deletions.
2 changes: 1 addition & 1 deletion gossip/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ var ProtocolVersions = []uint{FTM62, FTM63}
// protocolLengths are the number of implemented message corresponding to different protocol versions.
var protocolLengths = map[uint]uint64{FTM62: EventsStreamResponse + 1, FTM63: EPsStreamResponse + 1}

const protocolMaxMsgSize = 10 * 1024 * 1024 // Maximum cap on the size of a protocol message
const protocolMaxMsgSize = inter.ProtocolMaxMsgSize // Maximum cap on the size of a protocol message

// protocol message codes
const (
Expand Down
17 changes: 14 additions & 3 deletions inter/event_serializer.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ var (

const MaxSerializationVersion = 1

const ProtocolMaxMsgSize = 10 * 1024 * 1024

func (e *Event) MarshalCSER(w *cser.Writer) error {
// version
if e.Version() > 0 {
Expand Down Expand Up @@ -116,6 +118,9 @@ func eventUnmarshalCSER(r *cser.Reader, e *MutableEventPayload) (err error) {
gasPowerLeft1 := r.U64()
// parents
parentsNum := r.U32()
if parentsNum > ProtocolMaxMsgSize/24 {
return cser.ErrTooLargeAlloc
}
parents := make(hash.Events, 0, parentsNum)
for i := uint32(0); i < parentsNum; i++ {
// lamport difference
Expand Down Expand Up @@ -150,7 +155,7 @@ func eventUnmarshalCSER(r *cser.Reader, e *MutableEventPayload) (err error) {
}
}
// extra
extra := r.SliceBytes()
extra := r.SliceBytes(ProtocolMaxMsgSize)

if version == 0 && epoch < 256 {
return ErrTooLowEpoch
Expand Down Expand Up @@ -205,6 +210,9 @@ func (bvs *LlrBlockVotes) UnmarshalCSER(r *cser.Reader) error {
start := r.U64()
epoch := r.U32()
num := r.U32()
if num > ProtocolMaxMsgSize/32 {
return cser.ErrTooLargeAlloc
}
records := make([]hash.Hash, num)
for i := range records {
r.FixedBytes(records[i][:])
Expand Down Expand Up @@ -300,6 +308,9 @@ func (e *MutableEventPayload) UnmarshalCSER(r *cser.Reader) error {
if size == 0 {
return cser.ErrNonCanonicalEncoding
}
if size > ProtocolMaxMsgSize/64 {
return cser.ErrTooLargeAlloc
}
for i := uint64(0); i < size; i++ {
tx, err := TransactionUnmarshalCSER(r)
if err != nil {
Expand All @@ -308,7 +319,7 @@ func (e *MutableEventPayload) UnmarshalCSER(r *cser.Reader) error {
txs = append(txs, tx)
}
} else {
b := r.SliceBytes()
b := r.SliceBytes(ProtocolMaxMsgSize)
err := rlp.DecodeBytes(b, &txs)
if err != nil {
return err
Expand All @@ -319,7 +330,7 @@ func (e *MutableEventPayload) UnmarshalCSER(r *cser.Reader) error {
// mps
mps := make([]MisbehaviourProof, 0)
if e.AnyMisbehaviourProofs() {
b := r.SliceBytes()
b := r.SliceBytes(ProtocolMaxMsgSize)
err := rlp.DecodeBytes(b, &mps)
if err != nil {
return err
Expand Down
8 changes: 7 additions & 1 deletion inter/transaction_serializer.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func TransactionUnmarshalCSER(r *cser.Reader) (*types.Transaction, error) {
r.FixedBytes(_to[:])
to = &_to
}
data := r.SliceBytes()
data := r.SliceBytes(ProtocolMaxMsgSize)
// sig
v := r.BigInt()
var sig [64]byte
Expand All @@ -116,10 +116,16 @@ func TransactionUnmarshalCSER(r *cser.Reader) (*types.Transaction, error) {
} else if txType == types.AccessListTxType || txType == types.DynamicFeeTxType {
chainID := r.BigInt()
accessListLen := r.U32()
if accessListLen > ProtocolMaxMsgSize/24 {
return nil, cser.ErrTooLargeAlloc
}
accessList := make(types.AccessList, accessListLen)
for i := range accessList {
r.FixedBytes(accessList[i].Address[:])
keysLen := r.U32()
if keysLen > ProtocolMaxMsgSize/32 {
return nil, cser.ErrTooLargeAlloc
}
accessList[i].StorageKeys = make([]common.Hash, keysLen)
for j := range accessList[i].StorageKeys {
r.FixedBytes(accessList[i].StorageKeys[j][:])
Expand Down
4 changes: 2 additions & 2 deletions utils/cser/binary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ func TestVals(t *testing.T) {
require.Equal(exp, got, i)
}
for i, exp := range expSliceBytes {
got := r.SliceBytes()
got := r.SliceBytes(255)
require.Equal(exp, got, i)
}
for i, exp := range expU8 {
Expand Down Expand Up @@ -314,7 +314,7 @@ func TestBadVals(t *testing.T) {
require.Equal(len(exp), len(got), i)
}
for i, exp := range expSliceBytes {
got := r.SliceBytes()
got := r.SliceBytes(1)
require.NotEqual(exp, got, i)
require.Equal(len(exp), len(got), i)
}
Expand Down
10 changes: 8 additions & 2 deletions utils/cser/read_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ import (
var (
ErrNonCanonicalEncoding = errors.New("non canonical encoding")
ErrMalformedEncoding = errors.New("malformed encoding")
ErrTooLargeAlloc = errors.New("too large allocation")
)

const MaxAlloc = 100 * 1024

type Writer struct {
BitsW *bits.Writer
BytesW *fast.Writer
Expand Down Expand Up @@ -200,9 +203,12 @@ func (w *Writer) FixedBytes(v []byte) {
w.BytesW.Write(v)
}

func (r *Reader) SliceBytes() []byte {
func (r *Reader) SliceBytes(maxLen int) []byte {
// read slice size
size := r.U56()
if size > uint64(maxLen) {
panic(ErrTooLargeAlloc)
}
buf := make([]byte, size)
// read slice content
r.FixedBytes(buf)
Expand Down Expand Up @@ -236,7 +242,7 @@ func (w *Writer) BigInt(v *big.Int) {

func (r *Reader) BigInt() *big.Int {
// deserialize as an ordinary slice
buf := r.SliceBytes()
buf := r.SliceBytes(512)
if len(buf) == 0 {
return new(big.Int)
}
Expand Down

0 comments on commit 52613a1

Please sign in to comment.