diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index d0980f1d9..5c23bd7b4 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -23,6 +23,7 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi - Apps - [ABCI] \#5447 Remove `SetOption` method from `ABCI.Client` interface - [ABCI] \#5447 Reset `Oneof` indexes for `Request` and `Response`. + - [ABCI] \#5818 Use protoio for msg length delimitation. Migrates from int64 to uint64 length delimiters. - P2P Protocol diff --git a/UPGRADING.md b/UPGRADING.md index a6ce485d2..318928fe4 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -10,6 +10,8 @@ This guide provides instructions for upgrading to specific versions of Tendermin * The method `SetOption` has been removed from the ABCI.Client interface. This feature was used in the early ABCI implementation's. +* Messages are written to a byte stream using uin64 length delimiters instead of int64. + ### Config Changes * `fast_sync = "v1"` is no longer supported. Please use `v2` instead. diff --git a/abci/types/messages.go b/abci/types/messages.go index eaf1721dd..a80663646 100644 --- a/abci/types/messages.go +++ b/abci/types/messages.go @@ -1,11 +1,10 @@ package types import ( - "bufio" - "encoding/binary" "io" "github.com/gogo/protobuf/proto" + "github.com/tendermint/tendermint/libs/protoio" ) const ( @@ -14,57 +13,19 @@ const ( // WriteMessage writes a varint length-delimited protobuf message. func WriteMessage(msg proto.Message, w io.Writer) error { - bz, err := proto.Marshal(msg) + protoWriter := protoio.NewDelimitedWriter(w) + _, err := protoWriter.WriteMsg(msg) if err != nil { return err } - return encodeByteSlice(w, bz) + + return nil } // ReadMessage reads a varint length-delimited protobuf message. func ReadMessage(r io.Reader, msg proto.Message) error { - return readProtoMsg(r, msg, maxMsgSize) -} - -func readProtoMsg(r io.Reader, msg proto.Message, maxSize int) error { - // binary.ReadVarint takes an io.ByteReader, eg. a bufio.Reader - reader, ok := r.(*bufio.Reader) - if !ok { - reader = bufio.NewReader(r) - } - length64, err := binary.ReadVarint(reader) - if err != nil { - return err - } - length := int(length64) - if length < 0 || length > maxSize { - return io.ErrShortBuffer - } - buf := make([]byte, length) - if _, err := io.ReadFull(reader, buf); err != nil { - return err - } - return proto.Unmarshal(buf, msg) -} - -//----------------------------------------------------------------------- -// NOTE: we copied wire.EncodeByteSlice from go-wire rather than keep -// go-wire as a dep - -func encodeByteSlice(w io.Writer, bz []byte) (err error) { - err = encodeVarint(w, int64(len(bz))) - if err != nil { - return - } - _, err = w.Write(bz) - return -} - -func encodeVarint(w io.Writer, i int64) (err error) { - var buf [10]byte - n := binary.PutVarint(buf[:], i) - _, err = w.Write(buf[0:n]) - return + reader := protoio.NewDelimitedReader(r, maxMsgSize) + return reader.ReadMsg(msg) } //----------------------------------------