From 0b089efb12643476c96badf099102f57dec30681 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Thu, 2 Mar 2023 15:34:43 -0500 Subject: [PATCH 01/54] WIP --- go.mod | 1 + go.sum | 2 + message/compression_benchmark_test.go | 127 ++++++++++++++++++++++ utils/compression/compression_bechmark.go | 38 +++++++ utils/compression/zstd_compressor.go | 34 ++++++ 5 files changed, 202 insertions(+) create mode 100644 message/compression_benchmark_test.go create mode 100644 utils/compression/compression_bechmark.go create mode 100644 utils/compression/zstd_compressor.go diff --git a/go.mod b/go.mod index b78e75ba02a..501d39fe995 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ module github.com/ava-labs/avalanchego go 1.19 require ( + github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 github.com/ava-labs/avalanche-network-runner-sdk v0.3.0 diff --git a/go.sum b/go.sum index 6496d0a1192..fd7eddc014f 100644 --- a/go.sum +++ b/go.sum @@ -39,6 +39,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= +github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= diff --git a/message/compression_benchmark_test.go b/message/compression_benchmark_test.go new file mode 100644 index 00000000000..257b4773b62 --- /dev/null +++ b/message/compression_benchmark_test.go @@ -0,0 +1,127 @@ +// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package message + +import ( + "math" + "net" + "testing" + "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/proto/pb/p2p" + "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/utils/compression" + "github.com/ava-labs/avalanchego/utils/hashing" + "github.com/ava-labs/avalanchego/utils/ips" + "github.com/prometheus/client_golang/prometheus" +) + +// TODO only use messages that are actually compressed on the wire +var msgs = map[string][]byte{} + +func init() { + innerBuilder, err := newMsgBuilder("", prometheus.NewRegistry(), 10*time.Second) + if err != nil { + panic(err) + } + builder := newOutboundBuilder(false, innerBuilder) // Note compression disabled + + pingMsg, err := builder.Ping() + if err != nil { + panic(err) + } + msgs["ping"] = pingMsg.Bytes() + + pongMsg, err := builder.Pong(100, []*p2p.SubnetUptime{ + { + SubnetId: utils.RandomBytes(hashing.HashLen), + Uptime: 3, + }, + }) + if err != nil { + panic(err) + } + msgs["pong"] = pongMsg.Bytes() + + versionMsg, err := builder.Version( + 1, + uint64(time.Now().Unix()), + ips.IPPort{ + IP: net.IPv4(127, 0, 0, 1), + Port: 9651, + }, + "v1.0.0", + uint64(time.Now().Unix()), + utils.RandomBytes(256), + []ids.ID{ids.GenerateTestID()}, + ) + if err != nil { + panic(err) + } + msgs["version"] = versionMsg.Bytes() + + chitsMsg, err := builder.Chits( + ids.GenerateTestID(), + 12341234, + []ids.ID{ids.GenerateTestID()}, + []ids.ID{ids.GenerateTestID()}, + p2p.EngineType_ENGINE_TYPE_SNOWMAN, + ) + if err != nil { + panic(err) + } + msgs["chits"] = chitsMsg.Bytes() + + peerListAckMsg, err := builder.PeerListAck([]*p2p.PeerAck{ + { + TxId: utils.RandomBytes(hashing.HashLen), + Timestamp: uint64(time.Now().Unix()), + }, + { + TxId: utils.RandomBytes(hashing.HashLen), + Timestamp: uint64(time.Now().Unix()), + }, + { + TxId: utils.RandomBytes(hashing.HashLen), + Timestamp: uint64(time.Now().Unix()), + }, + }) + if err != nil { + panic(err) + } + msgs["peerListAck"] = peerListAckMsg.Bytes() +} + +func BenchmarkCompressor(b *testing.B) { + zstdCompressor := compression.NewZstdCompressor() + gzipCompressor, err := compression.NewGzipCompressor(math.MaxUint32) + if err != nil { + b.Fatal(err) + } + + compressors := map[string]compression.Compressor{ + "zstd": zstdCompressor, + "gzip": gzipCompressor, + } + + for compressorName, compressor := range compressors { + for msgName, msg := range msgs { + b.Run(compressorName+" "+msgName, func(b *testing.B) { + var bytesSaved int + for i := 0; i < b.N; i++ { + compressed, err := compressor.Compress(msg) + if err != nil { + b.Fatal(err) + } + // if _, err := compressor.Decompress(compressed); err != nil { + // b.Fatal(err) + // } + bytesSaved += len(msg) - len(compressed) + } + b.ReportMetric(float64(bytesSaved)/float64(b.N), "bytes_saved/op") + }) + } + } +} diff --git a/utils/compression/compression_bechmark.go b/utils/compression/compression_bechmark.go new file mode 100644 index 00000000000..4f3470da0a3 --- /dev/null +++ b/utils/compression/compression_bechmark.go @@ -0,0 +1,38 @@ +// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package compression + +import ( + "testing" + + "github.com/ava-labs/avalanchego/proto/pb/p2p" + "google.golang.org/protobuf/proto" +) + +var msgs = [][]byte{} + +func init() { + pingMsg := p2p.Message{ + Message: &p2p.Message_Ping{ + Ping: &p2p.Ping{}, + }, + } + pingMsgBytes, err := proto.Marshal(&pingMsg) + if err != nil { + panic(err) + } + msgs = append(msgs, pingMsgBytes) +} + +func BenchmarkCompressor(b *testing.B, compressor Compressor, msg []byte) { + for i := 0; i < b.N; i++ { + compressed, err := compressor.Compress(msg) + if err != nil { + b.Fatal(err) + } + if _, err := compressor.Decompress(compressed); err != nil { + b.Fatal(err) + } + } +} diff --git a/utils/compression/zstd_compressor.go b/utils/compression/zstd_compressor.go new file mode 100644 index 00000000000..4fb49160ca5 --- /dev/null +++ b/utils/compression/zstd_compressor.go @@ -0,0 +1,34 @@ +// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package compression + +import ( + "fmt" + "math" + + "github.com/DataDog/zstd" +) + +var _ Compressor = (*zstdCompressor)(nil) + +func NewZstdCompressor() Compressor { + return &zstdCompressor{ + maxSize: math.MaxUint32, // TODO fix + } +} + +type zstdCompressor struct { + maxSize int64 +} + +func (c *zstdCompressor) Compress(msg []byte) ([]byte, error) { + if int64(len(msg)) > c.maxSize { + return nil, fmt.Errorf("msg length (%d) > maximum msg length (%d)", len(msg), c.maxSize) + } + return zstd.Compress(nil, msg) +} + +func (c *zstdCompressor) Decompress(msg []byte) ([]byte, error) { + return zstd.Decompress(nil, msg) +} From e4e513bb0b063ddaf766bc4d2a88b99f6e8b5759 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Thu, 2 Mar 2023 15:59:33 -0500 Subject: [PATCH 02/54] remove max size from NewZstdCompressor --- utils/compression/zstd_compressor.go | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/utils/compression/zstd_compressor.go b/utils/compression/zstd_compressor.go index 4fb49160ca5..71114fe771f 100644 --- a/utils/compression/zstd_compressor.go +++ b/utils/compression/zstd_compressor.go @@ -4,28 +4,19 @@ package compression import ( - "fmt" - "math" - "github.com/DataDog/zstd" ) var _ Compressor = (*zstdCompressor)(nil) func NewZstdCompressor() Compressor { - return &zstdCompressor{ - maxSize: math.MaxUint32, // TODO fix - } + return &zstdCompressor{} } type zstdCompressor struct { - maxSize int64 } func (c *zstdCompressor) Compress(msg []byte) ([]byte, error) { - if int64(len(msg)) > c.maxSize { - return nil, fmt.Errorf("msg length (%d) > maximum msg length (%d)", len(msg), c.maxSize) - } return zstd.Compress(nil, msg) } From ef84d36fa620fab7087eabb25b734ea48cf4b24e Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Thu, 2 Mar 2023 16:44:29 -0500 Subject: [PATCH 03/54] WIP support multiple compression types --- message/compression_benchmark_test.go | 2 +- message/creator.go | 5 +- message/messages.go | 77 +++- message/messages_benchmark_test.go | 3 +- message/messages_test.go | 73 ++-- message/outbound_msg_builder.go | 55 +-- message/outbound_msg_builder_test.go | 3 +- network/network_test.go | 3 +- network/peer/peer_test.go | 3 +- network/peer/test_peer.go | 3 +- network/test_network.go | 2 +- node/node.go | 4 +- proto/p2p/p2p.proto | 6 +- proto/pb/p2p/p2p.pb.go | 590 +++++++++++++------------- snow/networking/sender/sender_test.go | 7 +- utils/compression/compressor.go | 8 + utils/compression/zstd_compressor.go | 7 +- utils/constants/networking.go | 4 +- vms/platformvm/vm_test.go | 3 +- 19 files changed, 472 insertions(+), 386 deletions(-) diff --git a/message/compression_benchmark_test.go b/message/compression_benchmark_test.go index 257b4773b62..d2a1374b302 100644 --- a/message/compression_benchmark_test.go +++ b/message/compression_benchmark_test.go @@ -26,7 +26,7 @@ func init() { if err != nil { panic(err) } - builder := newOutboundBuilder(false, innerBuilder) // Note compression disabled + builder := newOutboundBuilder(compression.NoCompression, innerBuilder) // Note compression disabled pingMsg, err := builder.Ping() if err != nil { diff --git a/message/creator.go b/message/creator.go index b96426f7a32..dd599796322 100644 --- a/message/creator.go +++ b/message/creator.go @@ -7,6 +7,7 @@ import ( "fmt" "time" + "github.com/ava-labs/avalanchego/utils/compression" "github.com/prometheus/client_golang/prometheus" ) @@ -25,7 +26,7 @@ type creator struct { func NewCreator( metrics prometheus.Registerer, parentNamespace string, - compressionEnabled bool, + compressionType compression.CompressionType, maxMessageTimeout time.Duration, ) (Creator, error) { namespace := fmt.Sprintf("%s_codec", parentNamespace) @@ -39,7 +40,7 @@ func NewCreator( } return &creator{ - OutboundMsgBuilder: newOutboundBuilder(compressionEnabled, builder), + OutboundMsgBuilder: newOutboundBuilder(compressionType, builder), InboundMsgBuilder: newInboundBuilder(builder), }, nil } diff --git a/message/messages.go b/message/messages.go index d0591e429ad..f199fbef77d 100644 --- a/message/messages.go +++ b/message/messages.go @@ -4,6 +4,7 @@ package message import ( + "errors" "fmt" "time" @@ -24,6 +25,8 @@ import ( var ( _ InboundMessage = (*inboundMessage)(nil) _ OutboundMessage = (*outboundMessage)(nil) + + errTwoCompressionTypes = errors.New("message is compressed with both gzip and zstd") ) // InboundMessage represents a set of fields for an inbound message @@ -121,6 +124,7 @@ func (m *outboundMessage) BytesSavedCompression() int { // TODO: add other compression algorithms with extended interface type msgBuilder struct { gzipCompressor compression.Compressor + zstdCompressor compression.Compressor compressTimeMetrics map[Op]metric.Averager decompressTimeMetrics map[Op]metric.Averager @@ -140,6 +144,7 @@ func newMsgBuilder( mb := &msgBuilder{ gzipCompressor: cpr, + zstdCompressor: compression.NewZstdCompressor(), compressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), decompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), @@ -169,14 +174,14 @@ func newMsgBuilder( func (mb *msgBuilder) marshal( uncompressedMsg *p2p.Message, - gzipCompress bool, + compressionType compression.CompressionType, ) ([]byte, int, time.Duration, error) { uncompressedMsgBytes, err := proto.Marshal(uncompressedMsg) if err != nil { return nil, 0, 0, err } - if !gzipCompress { + if compressionType == compression.NoCompression { return uncompressedMsgBytes, 0, 0, nil } @@ -187,16 +192,33 @@ func (mb *msgBuilder) marshal( // This recursive packing allows us to avoid an extra compression on/off // field in the message. startTime := time.Now() - compressedBytes, err := mb.gzipCompressor.Compress(uncompressedMsgBytes) - if err != nil { - return nil, 0, 0, err - } - compressedMsg := p2p.Message{ - Message: &p2p.Message_CompressedGzip{ - CompressedGzip: compressedBytes, - }, + var compressedMsg p2p.Message + + switch compressionType { + case compression.GzipCompression: + compressedBytes, err := mb.gzipCompressor.Compress(uncompressedMsgBytes) + if err != nil { + return nil, 0, 0, err + } + compressedMsg = p2p.Message{ + Message: &p2p.Message_CompressedGzip{ + CompressedGzip: compressedBytes, + }, + } + + case compression.ZstdCompression: + compressedBytes, err := mb.zstdCompressor.Compress(uncompressedMsgBytes) + if err != nil { + return nil, 0, 0, err + } + compressedMsg = p2p.Message{ + Message: &p2p.Message_CompressedZstd{ + CompressedZstd: compressedBytes, + }, + } } + compressedMsgBytes, err := proto.Marshal(&compressedMsg) if err != nil { return nil, 0, 0, err @@ -213,16 +235,33 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, bool, int, time.Duratio return nil, false, 0, 0, err } - compressed := m.GetCompressedGzip() - if len(compressed) == 0 { + gzipCompressed := m.GetCompressedGzip() + zstdCompressed := m.GetCompressedZstd() + if len(gzipCompressed) == 0 && len(zstdCompressed) == 0 { // The message wasn't compressed return m, false, 0, 0, nil } + if len(gzipCompressed) > 0 && len(zstdCompressed) > 0 { + return nil, true, 0, 0, errTwoCompressionTypes + } startTime := time.Now() - decompressed, err := mb.gzipCompressor.Decompress(compressed) - if err != nil { - return nil, true, 0, 0, err + + var ( + decompressed []byte + err error + ) + if len(gzipCompressed) > 0 { + decompressed, err = mb.gzipCompressor.Decompress(gzipCompressed) + if err != nil { + return nil, true, 0, 0, err + } + } + if len(zstdCompressed) > 0 { + decompressed, err = mb.zstdCompressor.Decompress(zstdCompressed) + if err != nil { + return nil, true, 0, 0, err + } } if err := proto.Unmarshal(decompressed, m); err != nil { @@ -230,12 +269,12 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, bool, int, time.Duratio } decompressTook := time.Since(startTime) - bytesSavedCompression := len(decompressed) - len(compressed) + bytesSavedCompression := len(decompressed) - len(gzipCompressed) return m, true, bytesSavedCompression, decompressTook, nil } -func (mb *msgBuilder) createOutbound(m *p2p.Message, gzipCompress bool, bypassThrottling bool) (*outboundMessage, error) { - b, saved, compressTook, err := mb.marshal(m, gzipCompress) +func (mb *msgBuilder) createOutbound(m *p2p.Message, compressionType compression.CompressionType, bypassThrottling bool) (*outboundMessage, error) { + b, saved, compressTook, err := mb.marshal(m, compressionType) if err != nil { return nil, err } @@ -245,7 +284,7 @@ func (mb *msgBuilder) createOutbound(m *p2p.Message, gzipCompress bool, bypassTh return nil, err } - if gzipCompress { + if compressionType != compression.NoCompression { mb.compressTimeMetrics[op].Observe(float64(compressTook)) } diff --git a/message/messages_benchmark_test.go b/message/messages_benchmark_test.go index c0ad59015f2..7f66b7766f6 100644 --- a/message/messages_benchmark_test.go +++ b/message/messages_benchmark_test.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/proto/pb/p2p" + "github.com/ava-labs/avalanchego/utils/compression" ) var ( @@ -70,7 +71,7 @@ func BenchmarkMarshalVersion(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { if useBuilder { - _, err = codec.createOutbound(&msg, false, false) + _, err = codec.createOutbound(&msg, compression.NoCompression, false) } else { _, err = proto.Marshal(&msg) } diff --git a/message/messages_test.go b/message/messages_test.go index f2d0abf7e3a..632f56bd4c0 100644 --- a/message/messages_test.go +++ b/message/messages_test.go @@ -18,6 +18,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/proto/pb/p2p" "github.com/ava-labs/avalanchego/staking" + "github.com/ava-labs/avalanchego/utils/compression" ) func TestMessage(t *testing.T) { @@ -51,7 +52,7 @@ func TestMessage(t *testing.T) { desc string op Op msg *p2p.Message - gzipCompress bool + compressionType compression.CompressionType bypassThrottling bool bytesSaved bool // if true, outbound message saved bytes must be non-zero }{ @@ -63,7 +64,7 @@ func TestMessage(t *testing.T) { Ping: &p2p.Ping{}, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -77,7 +78,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -97,7 +98,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -118,7 +119,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -140,7 +141,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -162,7 +163,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: true, + compressionType: compression.GzipCompression, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -181,7 +182,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: false, bytesSaved: false, }, @@ -197,7 +198,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -213,7 +214,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -229,7 +230,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: true, + compressionType: compression.GzipCompression, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -246,7 +247,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -263,7 +264,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: true, + compressionType: compression.GzipCompression, // TODO support zstd bypassThrottling: true, bytesSaved: false, }, @@ -279,7 +280,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -295,7 +296,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: true, + compressionType: compression.GzipCompression, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -312,7 +313,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -329,7 +330,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -347,7 +348,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -364,7 +365,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -382,7 +383,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -399,7 +400,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -416,7 +417,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: true, + compressionType: compression.GzipCompression, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -434,7 +435,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -451,7 +452,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -468,7 +469,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: true, + compressionType: compression.GzipCompression, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -486,7 +487,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -504,7 +505,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: true, + compressionType: compression.GzipCompression, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -522,7 +523,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -539,7 +540,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -556,7 +557,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -573,7 +574,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: true, + compressionType: compression.GzipCompression, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -589,7 +590,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -605,7 +606,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: true, + compressionType: compression.GzipCompression, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -620,7 +621,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: false, + compressionType: compression.NoCompression, bypassThrottling: true, bytesSaved: false, }, @@ -635,7 +636,7 @@ func TestMessage(t *testing.T) { }, }, }, - gzipCompress: true, + compressionType: compression.GzipCompression, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -643,7 +644,7 @@ func TestMessage(t *testing.T) { for _, tv := range tests { require.True(t.Run(tv.desc, func(t2 *testing.T) { - encodedMsg, err := mb.createOutbound(tv.msg, tv.gzipCompress, tv.bypassThrottling) + encodedMsg, err := mb.createOutbound(tv.msg, tv.compressionType, tv.bypassThrottling) require.NoError(err) require.Equal(tv.bypassThrottling, encodedMsg.BypassThrottling()) diff --git a/message/outbound_msg_builder.go b/message/outbound_msg_builder.go index f357252207c..988aee99369 100644 --- a/message/outbound_msg_builder.go +++ b/message/outbound_msg_builder.go @@ -8,6 +8,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/proto/pb/p2p" + "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/ips" ) @@ -171,17 +172,17 @@ type OutboundMsgBuilder interface { } type outMsgBuilder struct { - compress bool // set to "true" if compression is enabled + compressionType compression.CompressionType builder *msgBuilder } // Use "message.NewCreator" to import this function // since we do not expose "msgBuilder" yet -func newOutboundBuilder(enableCompression bool, builder *msgBuilder) OutboundMsgBuilder { +func newOutboundBuilder(compressionType compression.CompressionType, builder *msgBuilder) OutboundMsgBuilder { return &outMsgBuilder{ - compress: enableCompression, - builder: builder, + compressionType: compressionType, + builder: builder, } } @@ -192,7 +193,7 @@ func (b *outMsgBuilder) Ping() (OutboundMessage, error) { Ping: &p2p.Ping{}, }, }, - false, + compression.NoCompression, false, ) } @@ -210,7 +211,7 @@ func (b *outMsgBuilder) Pong( }, }, }, - false, + compression.NoCompression, false, ) } @@ -241,7 +242,7 @@ func (b *outMsgBuilder) Version( }, }, }, - false, + compression.NoCompression, true, ) } @@ -266,7 +267,7 @@ func (b *outMsgBuilder) PeerList(peers []ips.ClaimedIPPort, bypassThrottling boo }, }, }, - b.compress, + b.compressionType, bypassThrottling, ) } @@ -280,7 +281,7 @@ func (b *outMsgBuilder) PeerListAck(peerAcks []*p2p.PeerAck) (OutboundMessage, e }, }, }, - false, + compression.NoCompression, false, ) } @@ -300,7 +301,7 @@ func (b *outMsgBuilder) GetStateSummaryFrontier( }, }, }, - false, + compression.NoCompression, false, ) } @@ -320,7 +321,7 @@ func (b *outMsgBuilder) StateSummaryFrontier( }, }, }, - b.compress, + b.compressionType, false, ) } @@ -342,7 +343,7 @@ func (b *outMsgBuilder) GetAcceptedStateSummary( }, }, }, - b.compress, + b.compressionType, false, ) } @@ -364,7 +365,7 @@ func (b *outMsgBuilder) AcceptedStateSummary( }, }, }, - b.compress, + b.compressionType, false, ) } @@ -386,7 +387,7 @@ func (b *outMsgBuilder) GetAcceptedFrontier( }, }, }, - false, + compression.NoCompression, false, ) } @@ -410,7 +411,7 @@ func (b *outMsgBuilder) AcceptedFrontier( }, }, }, - false, + compression.NoCompression, false, ) } @@ -436,7 +437,7 @@ func (b *outMsgBuilder) GetAccepted( }, }, }, - false, + compression.NoCompression, false, ) } @@ -460,7 +461,7 @@ func (b *outMsgBuilder) Accepted( }, }, }, - false, + compression.NoCompression, false, ) } @@ -484,7 +485,7 @@ func (b *outMsgBuilder) GetAncestors( }, }, }, - false, + compression.NoCompression, false, ) } @@ -506,7 +507,7 @@ func (b *outMsgBuilder) Ancestors( }, }, }, - b.compress, + b.compressionType, false, ) } @@ -530,7 +531,7 @@ func (b *outMsgBuilder) Get( }, }, }, - false, + compression.NoCompression, false, ) } @@ -552,7 +553,7 @@ func (b *outMsgBuilder) Put( }, }, }, - b.compress, + b.compressionType, false, ) } @@ -576,7 +577,7 @@ func (b *outMsgBuilder) PushQuery( }, }, }, - b.compress, + b.compressionType, false, ) } @@ -600,7 +601,7 @@ func (b *outMsgBuilder) PullQuery( }, }, }, - false, + compression.NoCompression, false, ) } @@ -628,7 +629,7 @@ func (b *outMsgBuilder) Chits( }, }, }, - false, + compression.NoCompression, false, ) } @@ -650,7 +651,7 @@ func (b *outMsgBuilder) AppRequest( }, }, }, - b.compress, + b.compressionType, false, ) } @@ -666,7 +667,7 @@ func (b *outMsgBuilder) AppResponse(chainID ids.ID, requestID uint32, msg []byte }, }, }, - b.compress, + b.compressionType, false, ) } @@ -681,7 +682,7 @@ func (b *outMsgBuilder) AppGossip(chainID ids.ID, msg []byte) (OutboundMessage, }, }, }, - b.compress, + b.compressionType, false, ) } diff --git a/message/outbound_msg_builder_test.go b/message/outbound_msg_builder_test.go index db7c48e21d8..6d019c0bfb8 100644 --- a/message/outbound_msg_builder_test.go +++ b/message/outbound_msg_builder_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/compression" ) func Test_newOutboundBuilder(t *testing.T) { @@ -25,7 +26,7 @@ func Test_newOutboundBuilder(t *testing.T) { ) require.NoError(err) - builder := newOutboundBuilder(true /*compress*/, mb) + builder := newOutboundBuilder(compression.GzipCompression /*compress*/, mb) // TODO support zstd outMsg, err := builder.GetAcceptedStateSummary( ids.GenerateTestID(), diff --git a/network/network_test.go b/network/network_test.go index 82d8194d4c4..5783ba929dc 100644 --- a/network/network_test.go +++ b/network/network_test.go @@ -26,6 +26,7 @@ import ( "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/subnets" + "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/ips" "github.com/ava-labs/avalanchego/utils/logging" @@ -185,7 +186,7 @@ func newMessageCreator(t *testing.T) message.Creator { mc, err := message.NewCreator( prometheus.NewRegistry(), "", - true, + compression.GzipCompression, // TODO support zstd 10*time.Second, ) require.NoError(t, err) diff --git a/network/peer/peer_test.go b/network/peer/peer_test.go index 36baf7ea737..84b53d7f79f 100644 --- a/network/peer/peer_test.go +++ b/network/peer/peer_test.go @@ -23,6 +23,7 @@ import ( "github.com/ava-labs/avalanchego/snow/networking/tracker" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" + "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/ips" "github.com/ava-labs/avalanchego/utils/logging" @@ -51,7 +52,7 @@ func newMessageCreator(t *testing.T) message.Creator { mc, err := message.NewCreator( prometheus.NewRegistry(), "", - true, + compression.GzipCompression, // TODO support zstd 10*time.Second, ) require.NoError(t, err) diff --git a/network/peer/test_peer.go b/network/peer/test_peer.go index 2f32e0ea8a9..32ebf541a47 100644 --- a/network/peer/test_peer.go +++ b/network/peer/test_peer.go @@ -18,6 +18,7 @@ import ( "github.com/ava-labs/avalanchego/snow/networking/tracker" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" + "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/ips" "github.com/ava-labs/avalanchego/utils/logging" @@ -71,7 +72,7 @@ func StartTestPeer( mc, err := message.NewCreator( prometheus.NewRegistry(), "", - true, + compression.GzipCompression, // TODO support zstd 10*time.Second, ) if err != nil { diff --git a/network/test_network.go b/network/test_network.go index 5abc4849788..09bc6e45d81 100644 --- a/network/test_network.go +++ b/network/test_network.go @@ -81,7 +81,7 @@ func NewTestNetwork( msgCreator, err := message.NewCreator( metrics, "", - constants.DefaultNetworkCompressionEnabled, + constants.DefaultNetworkCompressionType, constants.DefaultNetworkMaximumInboundTimeout, ) if err != nil { diff --git a/node/node.go b/node/node.go index bb433619e05..78246a62397 100644 --- a/node/node.go +++ b/node/node.go @@ -56,6 +56,7 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/trace" "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/filesystem" @@ -1278,7 +1279,8 @@ func (n *Node) Initialize( n.msgCreator, err = message.NewCreator( n.MetricsRegisterer, n.networkNamespace, - n.Config.NetworkConfig.CompressionEnabled, + // n.Config.NetworkConfig.CompressionEnabled, TODO add config for this + compression.GzipCompression, n.Config.NetworkConfig.MaximumInboundMessageTimeout, ) if err != nil { diff --git a/proto/p2p/p2p.proto b/proto/p2p/p2p.proto index 6a83046d8b0..fcccc621812 100644 --- a/proto/p2p/p2p.proto +++ b/proto/p2p/p2p.proto @@ -17,8 +17,12 @@ message Message { // This field is only set if the message type supports compression. bytes compressed_gzip = 1; + // zstd-compressed bytes of a "p2p.Message" whose "oneof" "message" field is + // NOT compressed_* BUT one of the message types (e.g. ping, pong, etc.). + // This field is only set if the message type supports compression. + bytes compressed_zstd = 2; + // Fields lower than 10 are reserved for other compression algorithms. - // TODO: support COMPRESS_ZSTD // TODO: support COMPRESS_SNAPPY // Network messages: diff --git a/proto/pb/p2p/p2p.pb.go b/proto/pb/p2p/p2p.pb.go index 035f04dbb15..63409e33d55 100644 --- a/proto/pb/p2p/p2p.pb.go +++ b/proto/pb/p2p/p2p.pb.go @@ -81,7 +81,9 @@ type Message struct { // That is because when the compression is enabled, we don't want to include uncompressed fields. // // Types that are assignable to Message: + // // *Message_CompressedGzip + // *Message_CompressedZstd // *Message_Ping // *Message_Pong // *Message_Version @@ -154,6 +156,13 @@ func (x *Message) GetCompressedGzip() []byte { return nil } +func (x *Message) GetCompressedZstd() []byte { + if x, ok := x.GetMessage().(*Message_CompressedZstd); ok { + return x.CompressedZstd + } + return nil +} + func (x *Message) GetPing() *Ping { if x, ok := x.GetMessage().(*Message_Ping); ok { return x.Ping @@ -326,6 +335,13 @@ type Message_CompressedGzip struct { CompressedGzip []byte `protobuf:"bytes,1,opt,name=compressed_gzip,json=compressedGzip,proto3,oneof"` } +type Message_CompressedZstd struct { + // zstd-compressed bytes of a "p2p.Message" whose "oneof" "message" field is + // NOT compressed_* BUT one of the message types (e.g. ping, pong, etc.). + // This field is only set if the message type supports compression. + CompressedZstd []byte `protobuf:"bytes,2,opt,name=compressed_zstd,json=compressedZstd,proto3,oneof"` +} + type Message_Ping struct { // Network messages: Ping *Ping `protobuf:"bytes,11,opt,name=ping,proto3,oneof"` @@ -425,6 +441,8 @@ type Message_PeerListAck struct { func (*Message_CompressedGzip) isMessage_Message() {} +func (*Message_CompressedZstd) isMessage_Message() {} + func (*Message_Ping) isMessage_Message() {} func (*Message_Pong) isMessage_Message() {} @@ -2346,203 +2364,184 @@ var File_p2p_p2p_proto protoreflect.FileDescriptor var file_p2p_p2p_proto_rawDesc = []byte{ 0x0a, 0x0d, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x32, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x03, 0x70, 0x32, 0x70, 0x22, 0xb3, 0x0a, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x03, 0x70, 0x32, 0x70, 0x22, 0xde, 0x0a, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x67, 0x7a, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0e, 0x63, 0x6f, 0x6d, - 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x47, 0x7a, 0x69, 0x70, 0x12, 0x1f, 0x0a, 0x04, 0x70, - 0x69, 0x6e, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x70, 0x32, 0x70, 0x2e, - 0x50, 0x69, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x04, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x0a, 0x04, - 0x70, 0x6f, 0x6e, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x70, 0x32, 0x70, - 0x2e, 0x50, 0x6f, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x12, 0x28, 0x0a, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, - 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x07, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x09, 0x70, 0x65, 0x65, 0x72, 0x5f, - 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x32, 0x70, - 0x2e, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x08, 0x70, 0x65, 0x65, - 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x5b, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x32, 0x70, 0x2e, - 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, - 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x17, 0x67, 0x65, 0x74, 0x53, 0x74, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x47, 0x7a, 0x69, 0x70, 0x12, 0x29, 0x0a, 0x0f, 0x63, + 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x7a, 0x73, 0x74, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, + 0x65, 0x64, 0x5a, 0x73, 0x74, 0x64, 0x12, 0x1f, 0x0a, 0x04, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x48, + 0x00, 0x52, 0x04, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x0a, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x6f, 0x6e, 0x67, + 0x48, 0x00, 0x52, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x12, 0x28, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x32, 0x70, 0x2e, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x09, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, + 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, + 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x08, 0x70, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, + 0x12, 0x5b, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x0f, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, - 0x65, 0x72, 0x12, 0x51, 0x0a, 0x16, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x10, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, - 0x14, 0x73, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x5b, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x32, 0x70, 0x2e, - 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x48, 0x00, 0x52, 0x17, 0x67, 0x65, 0x74, 0x41, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x12, 0x51, 0x0a, 0x16, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x12, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, - 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x48, 0x00, 0x52, - 0x14, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x4e, 0x0a, 0x15, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x13, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, - 0x52, 0x13, 0x67, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x11, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, - 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, - 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x0c, 0x67, - 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0b, 0x67, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, - 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x08, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x18, 0x16, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, - 0x38, 0x0a, 0x0d, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, - 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, - 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x67, 0x65, 0x74, - 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2e, 0x0a, 0x09, 0x61, 0x6e, 0x63, - 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, - 0x32, 0x70, 0x2e, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x48, 0x00, 0x52, 0x09, - 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x03, 0x67, 0x65, 0x74, - 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, - 0x48, 0x00, 0x52, 0x03, 0x67, 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x03, 0x70, 0x75, 0x74, 0x18, 0x1a, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x75, 0x74, 0x48, 0x00, - 0x52, 0x03, 0x70, 0x75, 0x74, 0x12, 0x2f, 0x0a, 0x0a, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, - 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, 0x09, 0x70, 0x75, 0x73, - 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x0a, 0x70, 0x75, 0x6c, 0x6c, 0x5f, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, - 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, 0x09, 0x70, 0x75, - 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x22, 0x0a, 0x05, 0x63, 0x68, 0x69, 0x74, 0x73, - 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x68, 0x69, - 0x74, 0x73, 0x48, 0x00, 0x52, 0x05, 0x63, 0x68, 0x69, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x0b, 0x61, - 0x70, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x35, 0x0a, 0x0c, 0x61, 0x70, 0x70, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, - 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x70, 0x70, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x0a, 0x61, 0x70, 0x70, 0x5f, 0x67, 0x6f, - 0x73, 0x73, 0x69, 0x70, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, - 0x2e, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x48, 0x00, 0x52, 0x09, 0x61, 0x70, - 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x65, 0x65, 0x72, 0x5f, - 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, - 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, - 0x48, 0x00, 0x52, 0x0b, 0x70, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, 0x42, - 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x06, 0x0a, 0x04, 0x50, 0x69, - 0x6e, 0x67, 0x22, 0x43, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, - 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x12, - 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x58, 0x0a, 0x04, 0x50, 0x6f, 0x6e, 0x67, 0x12, - 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6e, 0x65, - 0x74, 0x5f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, - 0x6d, 0x65, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x22, 0xf5, 0x01, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, - 0x0a, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, - 0x6d, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, - 0x79, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, - 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x79, 0x5f, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x79, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x79, 0x5f, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x0d, 0x6d, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x10, - 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, - 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x6e, - 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x6b, - 0x65, 0x64, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x22, 0xbd, 0x01, 0x0a, 0x0d, 0x43, 0x6c, - 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x78, - 0x35, 0x30, 0x39, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x78, 0x35, 0x30, 0x39, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, - 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x22, 0x48, 0x0a, 0x08, 0x50, 0x65, 0x65, - 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x10, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, - 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, - 0x6f, 0x72, 0x74, 0x52, 0x0e, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, - 0x72, 0x74, 0x73, 0x22, 0x3c, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x12, 0x13, - 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, - 0x78, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x22, 0x3e, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, - 0x12, 0x29, 0x0a, 0x09, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x6b, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, - 0x6b, 0x52, 0x08, 0x70, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, - 0x02, 0x22, 0x6f, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, - 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, - 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, - 0x6e, 0x65, 0x22, 0x6a, 0x0a, 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x89, - 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x04, 0x52, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x71, 0x0a, 0x14, 0x41, 0x63, + 0x65, 0x72, 0x48, 0x00, 0x52, 0x17, 0x67, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x51, 0x0a, + 0x16, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x66, + 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x70, 0x32, 0x70, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x14, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, + 0x12, 0x5b, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x11, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, - 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, - 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x0a, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x49, 0x64, 0x73, 0x22, 0x9d, 0x01, - 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, + 0x72, 0x79, 0x48, 0x00, 0x52, 0x17, 0x67, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, + 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x51, 0x0a, + 0x16, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, + 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x70, 0x32, 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x48, 0x00, 0x52, 0x14, 0x61, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x12, 0x4e, 0x0a, 0x15, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, + 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, + 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x13, 0x67, 0x65, 0x74, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, + 0x12, 0x44, 0x0a, 0x11, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x6f, + 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, + 0x65, 0x72, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, + 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x0c, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, + 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x48, 0x00, + 0x52, 0x0b, 0x67, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x2b, 0x0a, + 0x08, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0d, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x48, 0x00, + 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x0d, 0x67, 0x65, + 0x74, 0x5f, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x67, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2e, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, + 0x73, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x6e, + 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x48, 0x00, 0x52, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x03, 0x67, 0x65, 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x00, 0x52, 0x03, 0x67, + 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x03, 0x70, 0x75, 0x74, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x08, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x75, 0x74, 0x48, 0x00, 0x52, 0x03, 0x70, 0x75, 0x74, + 0x12, 0x2f, 0x0a, 0x0a, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x1b, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, 0x09, 0x70, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x12, 0x2f, 0x0a, 0x0a, 0x70, 0x75, 0x6c, 0x6c, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, + 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x75, 0x6c, 0x6c, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, 0x09, 0x70, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x12, 0x22, 0x0a, 0x05, 0x63, 0x68, 0x69, 0x74, 0x73, 0x18, 0x1d, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x68, 0x69, 0x74, 0x73, 0x48, 0x00, 0x52, + 0x05, 0x63, 0x68, 0x69, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x5f, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0a, + 0x61, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x0c, 0x61, 0x70, + 0x70, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x2f, 0x0a, 0x0a, 0x61, 0x70, 0x70, 0x5f, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x18, + 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x47, + 0x6f, 0x73, 0x73, 0x69, 0x70, 0x48, 0x00, 0x52, 0x09, 0x61, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, + 0x69, 0x70, 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, + 0x61, 0x63, 0x6b, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, + 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x0b, 0x70, + 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x06, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x22, 0x43, 0x0a, + 0x0c, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, + 0x09, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, + 0x6d, 0x65, 0x22, 0x58, 0x0a, 0x04, 0x50, 0x6f, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, + 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x75, 0x70, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, + 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x73, + 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x22, 0xf5, 0x01, 0x0a, + 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x79, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x79, 0x54, 0x69, 0x6d, 0x65, + 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, + 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, + 0x72, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6d, 0x79, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x74, + 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x08, + 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, + 0x6e, 0x65, 0x74, 0x73, 0x22, 0xbd, 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, + 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x78, 0x35, 0x30, 0x39, 0x5f, 0x63, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0f, 0x78, 0x35, 0x30, 0x39, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, + 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, + 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, + 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, + 0x74, 0x78, 0x49, 0x64, 0x22, 0x48, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, + 0x12, 0x3c, 0x0a, 0x10, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x69, 0x70, 0x5f, 0x70, + 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x32, 0x70, + 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x0e, + 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x22, 0x3c, + 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x12, 0x1c, + 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3e, 0x0a, 0x0b, + 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, 0x12, 0x29, 0x0a, 0x09, 0x70, + 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, + 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x52, 0x08, 0x70, 0x65, + 0x65, 0x72, 0x41, 0x63, 0x6b, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x6f, 0x0a, 0x17, + 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, + 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, + 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x6a, 0x0a, + 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, + 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x89, 0x01, 0x0a, 0x17, 0x47, 0x65, + 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x30, 0x0a, 0x0b, 0x65, - 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xa3, 0x01, - 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, - 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, - 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, - 0x73, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, - 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, - 0x79, 0x70, 0x65, 0x22, 0xba, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, - 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, - 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x30, - 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x22, 0x9b, 0x01, 0x0a, 0x08, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, + 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x04, 0x52, 0x07, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x71, 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, + 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, + 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x49, 0x64, 0x73, 0x22, 0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, + 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xa3, 0x01, 0x0a, 0x10, 0x41, 0x63, 0x63, + 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, @@ -2551,114 +2550,136 @@ var file_p2p_p2p_proto_rawDesc = []byte{ 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xb9, - 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, - 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, - 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, - 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, - 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, - 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x97, 0x01, 0x0a, 0x09, 0x41, - 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, + 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xba, + 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, + 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, + 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, + 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, + 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, + 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x9b, 0x01, 0x0a, 0x08, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x73, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, - 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x22, 0xb0, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, - 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, - 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, - 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, - 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, - 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x8f, 0x01, 0x0a, 0x03, 0x50, 0x75, 0x74, 0x12, - 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, - 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xb1, 0x01, 0x0a, 0x09, 0x50, 0x75, - 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xb9, 0x01, 0x0a, 0x0c, 0x47, 0x65, + 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, + 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x97, 0x01, 0x0a, 0x09, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, + 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0c, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x30, 0x0a, + 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, + 0xb0, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1c, 0x0a, - 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, - 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xb6, 0x01, - 0x0a, 0x09, 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, - 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, - 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xe1, 0x01, 0x0a, 0x05, 0x43, 0x68, 0x69, 0x74, 0x73, - 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x72, - 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x15, 0x70, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, - 0x64, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, - 0x28, 0x0c, 0x52, 0x14, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, - 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, - 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x7f, 0x0a, 0x0a, 0x41, 0x70, - 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1b, - 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0b, 0x41, - 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x22, 0x8f, 0x01, 0x0a, 0x03, 0x50, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, - 0x73, 0x22, 0x43, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x19, - 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, - 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, - 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x19, 0x0a, 0x15, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x41, 0x56, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, - 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x4f, 0x57, - 0x4d, 0x41, 0x4e, 0x10, 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, - 0x62, 0x2f, 0x70, 0x32, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x22, 0xb1, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, + 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, + 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, + 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xb6, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x6c, + 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, + 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, + 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x22, 0xe1, 0x01, 0x0a, 0x05, 0x43, 0x68, 0x69, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, + 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x15, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, + 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x34, 0x0a, + 0x16, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x14, 0x61, + 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x49, 0x64, 0x73, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x7f, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, + 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, + 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, + 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, + 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x43, 0x0a, 0x09, + 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, + 0x73, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, + 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x56, 0x41, 0x4c, + 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x4e, 0x47, 0x49, 0x4e, + 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x4f, 0x57, 0x4d, 0x41, 0x4e, 0x10, 0x02, + 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, + 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, + 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x70, 0x32, 0x70, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3083,6 +3104,7 @@ func file_p2p_p2p_proto_init() { } file_p2p_p2p_proto_msgTypes[0].OneofWrappers = []interface{}{ (*Message_CompressedGzip)(nil), + (*Message_CompressedZstd)(nil), (*Message_Ping)(nil), (*Message_Pong)(nil), (*Message_Version)(nil), diff --git a/snow/networking/sender/sender_test.go b/snow/networking/sender/sender_test.go index 037fc3eb874..d84d76398a4 100644 --- a/snow/networking/sender/sender_test.go +++ b/snow/networking/sender/sender_test.go @@ -28,6 +28,7 @@ import ( "github.com/ava-labs/avalanchego/snow/networking/tracker" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/subnets" + "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/math/meter" "github.com/ava-labs/avalanchego/utils/resource" @@ -72,7 +73,7 @@ func TestTimeout(t *testing.T) { mc, err := message.NewCreator( metrics, "dummyNamespace", - true, + compression.GzipCompression, // TODO support zstd 10*time.Second, ) require.NoError(err) @@ -332,7 +333,7 @@ func TestReliableMessages(t *testing.T) { mc, err := message.NewCreator( metrics, "dummyNamespace", - true, + compression.GzipCompression, // TODO support zstd 10*time.Second, ) require.NoError(t, err) @@ -468,7 +469,7 @@ func TestReliableMessagesToMyself(t *testing.T) { mc, err := message.NewCreator( metrics, "dummyNamespace", - true, + compression.GzipCompression, 10*time.Second, ) require.NoError(t, err) diff --git a/utils/compression/compressor.go b/utils/compression/compressor.go index 5cc4d95beef..3884d0d5aaf 100644 --- a/utils/compression/compressor.go +++ b/utils/compression/compressor.go @@ -3,6 +3,14 @@ package compression +type CompressionType byte + +const ( + NoCompression CompressionType = iota + 1 + GzipCompression + ZstdCompression +) + // Compressor compresss and decompresses messages. // Decompress is the inverse of Compress. // Decompress(Compress(msg)) == msg. diff --git a/utils/compression/zstd_compressor.go b/utils/compression/zstd_compressor.go index 71114fe771f..6865cdc5742 100644 --- a/utils/compression/zstd_compressor.go +++ b/utils/compression/zstd_compressor.go @@ -13,13 +13,12 @@ func NewZstdCompressor() Compressor { return &zstdCompressor{} } -type zstdCompressor struct { -} +type zstdCompressor struct{} -func (c *zstdCompressor) Compress(msg []byte) ([]byte, error) { +func (*zstdCompressor) Compress(msg []byte) ([]byte, error) { return zstd.Compress(nil, msg) } -func (c *zstdCompressor) Decompress(msg []byte) ([]byte, error) { +func (*zstdCompressor) Decompress(msg []byte) ([]byte, error) { return zstd.Decompress(nil, msg) } diff --git a/utils/constants/networking.go b/utils/constants/networking.go index 3a4f441a02b..068b525c6ed 100644 --- a/utils/constants/networking.go +++ b/utils/constants/networking.go @@ -7,6 +7,7 @@ import ( "math" "time" + "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/units" ) @@ -54,7 +55,8 @@ const ( DefaultNetworkTimeoutCoefficient = 2 DefaultNetworkReadHandshakeTimeout = 15 * time.Second - DefaultNetworkCompressionEnabled = true + DefaultNetworkCompressionEnabled = true // TODO remove + DefaultNetworkCompressionType = compression.GzipCompression DefaultNetworkMaxClockDifference = time.Minute DefaultNetworkAllowPrivateIPs = true DefaultNetworkRequireValidatorToConnect = false diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 13b6515dc81..8549731c9a7 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -40,6 +40,7 @@ import ( "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/subnets" + "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" @@ -1721,7 +1722,7 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { chainRouter := &router.ChainRouter{} metrics := prometheus.NewRegistry() - mc, err := message.NewCreator(metrics, "dummyNamespace", true, 10*time.Second) + mc, err := message.NewCreator(metrics, "dummyNamespace", compression.GzipCompression, 10*time.Second) require.NoError(err) err = chainRouter.Initialize( From 4a659b0e6439e756282f5ebbbfabd698962fbead Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Thu, 2 Mar 2023 16:45:57 -0500 Subject: [PATCH 04/54] rename compressionType to Type --- message/creator.go | 2 +- message/messages.go | 4 ++-- message/messages_test.go | 2 +- message/outbound_msg_builder.go | 4 ++-- utils/compression/compressor.go | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/message/creator.go b/message/creator.go index dd599796322..11bd3691a64 100644 --- a/message/creator.go +++ b/message/creator.go @@ -26,7 +26,7 @@ type creator struct { func NewCreator( metrics prometheus.Registerer, parentNamespace string, - compressionType compression.CompressionType, + compressionType compression.Type, maxMessageTimeout time.Duration, ) (Creator, error) { namespace := fmt.Sprintf("%s_codec", parentNamespace) diff --git a/message/messages.go b/message/messages.go index f199fbef77d..babb3028282 100644 --- a/message/messages.go +++ b/message/messages.go @@ -174,7 +174,7 @@ func newMsgBuilder( func (mb *msgBuilder) marshal( uncompressedMsg *p2p.Message, - compressionType compression.CompressionType, + compressionType compression.Type, ) ([]byte, int, time.Duration, error) { uncompressedMsgBytes, err := proto.Marshal(uncompressedMsg) if err != nil { @@ -273,7 +273,7 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, bool, int, time.Duratio return m, true, bytesSavedCompression, decompressTook, nil } -func (mb *msgBuilder) createOutbound(m *p2p.Message, compressionType compression.CompressionType, bypassThrottling bool) (*outboundMessage, error) { +func (mb *msgBuilder) createOutbound(m *p2p.Message, compressionType compression.Type, bypassThrottling bool) (*outboundMessage, error) { b, saved, compressTook, err := mb.marshal(m, compressionType) if err != nil { return nil, err diff --git a/message/messages_test.go b/message/messages_test.go index 632f56bd4c0..f91e32eebe1 100644 --- a/message/messages_test.go +++ b/message/messages_test.go @@ -52,7 +52,7 @@ func TestMessage(t *testing.T) { desc string op Op msg *p2p.Message - compressionType compression.CompressionType + compressionType compression.Type bypassThrottling bool bytesSaved bool // if true, outbound message saved bytes must be non-zero }{ diff --git a/message/outbound_msg_builder.go b/message/outbound_msg_builder.go index 988aee99369..9e14da07f3a 100644 --- a/message/outbound_msg_builder.go +++ b/message/outbound_msg_builder.go @@ -172,14 +172,14 @@ type OutboundMsgBuilder interface { } type outMsgBuilder struct { - compressionType compression.CompressionType + compressionType compression.Type builder *msgBuilder } // Use "message.NewCreator" to import this function // since we do not expose "msgBuilder" yet -func newOutboundBuilder(compressionType compression.CompressionType, builder *msgBuilder) OutboundMsgBuilder { +func newOutboundBuilder(compressionType compression.Type, builder *msgBuilder) OutboundMsgBuilder { return &outMsgBuilder{ compressionType: compressionType, builder: builder, diff --git a/utils/compression/compressor.go b/utils/compression/compressor.go index 3884d0d5aaf..8a5e4ec17c7 100644 --- a/utils/compression/compressor.go +++ b/utils/compression/compressor.go @@ -3,10 +3,10 @@ package compression -type CompressionType byte +type Type byte const ( - NoCompression CompressionType = iota + 1 + NoCompression Type = iota + 1 GzipCompression ZstdCompression ) From c6de9279deff44e96c436b9880d18ae6f20ba719 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Thu, 2 Mar 2023 16:59:45 -0500 Subject: [PATCH 05/54] fix metric --- message/messages.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/message/messages.go b/message/messages.go index babb3028282..3bd6d885f8d 100644 --- a/message/messages.go +++ b/message/messages.go @@ -26,7 +26,8 @@ var ( _ InboundMessage = (*inboundMessage)(nil) _ OutboundMessage = (*outboundMessage)(nil) - errTwoCompressionTypes = errors.New("message is compressed with both gzip and zstd") + errMultipleCompressionTypes = errors.New("message is compressed with multiple compression types") + errUnknownCompressionType = errors.New("message is compressed with an unknown compression type") ) // InboundMessage represents a set of fields for an inbound message @@ -217,6 +218,8 @@ func (mb *msgBuilder) marshal( CompressedZstd: compressedBytes, }, } + default: + return nil, 0, 0, errUnknownCompressionType } compressedMsgBytes, err := proto.Marshal(&compressedMsg) @@ -242,26 +245,29 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, bool, int, time.Duratio return m, false, 0, 0, nil } if len(gzipCompressed) > 0 && len(zstdCompressed) > 0 { - return nil, true, 0, 0, errTwoCompressionTypes + return nil, true, 0, 0, errMultipleCompressionTypes } startTime := time.Now() var ( - decompressed []byte - err error + bytesSavedCompression int + decompressed []byte + err error ) if len(gzipCompressed) > 0 { decompressed, err = mb.gzipCompressor.Decompress(gzipCompressed) if err != nil { return nil, true, 0, 0, err } + bytesSavedCompression = len(decompressed) - len(gzipCompressed) } if len(zstdCompressed) > 0 { decompressed, err = mb.zstdCompressor.Decompress(zstdCompressed) if err != nil { return nil, true, 0, 0, err } + bytesSavedCompression = len(decompressed) - len(zstdCompressed) } if err := proto.Unmarshal(decompressed, m); err != nil { @@ -269,7 +275,6 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, bool, int, time.Duratio } decompressTook := time.Since(startTime) - bytesSavedCompression := len(decompressed) - len(gzipCompressed) return m, true, bytesSavedCompression, decompressTook, nil } From 13eb890f3358021904e75383116c973da7f0c7e9 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Thu, 2 Mar 2023 17:20:47 -0500 Subject: [PATCH 06/54] WIP remove CompressionEnabled and add --network-compression-type --- config/config.go | 11 +++++- config/flags.go | 2 + config/keys.go | 3 +- network/config.go | 8 ++-- network/network_test.go | 2 +- network/test_network.go | 2 +- node/node.go | 1 - utils/compression/compressor.go | 8 ---- utils/compression/type.go | 67 +++++++++++++++++++++++++++++++++ utils/constants/networking.go | 2 +- 10 files changed, 88 insertions(+), 18 deletions(-) create mode 100644 utils/compression/type.go diff --git a/config/config.go b/config/config.go index e7f891f7a16..0f484aa88ab 100644 --- a/config/config.go +++ b/config/config.go @@ -36,6 +36,7 @@ import ( "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/subnets" "github.com/ava-labs/avalanchego/trace" + "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/dynamicip" @@ -59,7 +60,9 @@ const ( ) var ( - deprecatedKeys = map[string]string{} + deprecatedKeys = map[string]string{ + NetworkCompressionEnabledKey: fmt.Sprintf("use --%s instead", NetworkCompressionTypeKey), + } errInvalidStakerWeights = errors.New("staking weights must be positive") errStakingDisableOnPublicNetwork = errors.New("staking disabled on public network") @@ -295,6 +298,10 @@ func getNetworkConfig(v *viper.Viper, stakingEnabled bool, halflife time.Duratio upgradeCooldown := v.GetDuration(InboundConnUpgradeThrottlerCooldownKey) upgradeCooldownInSeconds := upgradeCooldown.Seconds() maxRecentConnsUpgraded := int(math.Ceil(maxInboundConnsPerSec * upgradeCooldownInSeconds)) + compressionType, err := compression.TypeFromString(v.GetString(NetworkCompressionTypeKey)) + if err != nil { + return network.Config{}, err + } config := network.Config{ // Throttling ThrottlerConfig: network.ThrottlerConfig{ @@ -369,7 +376,7 @@ func getNetworkConfig(v *viper.Viper, stakingEnabled bool, halflife time.Duratio }, MaxClockDifference: v.GetDuration(NetworkMaxClockDifferenceKey), - CompressionEnabled: v.GetBool(NetworkCompressionEnabledKey), + CompressionType: compressionType, PingFrequency: v.GetDuration(NetworkPingFrequencyKey), AllowPrivateIPs: v.GetBool(NetworkAllowPrivateIPsKey), UptimeMetricFreq: v.GetDuration(UptimeMetricFreqKey), diff --git a/config/flags.go b/config/flags.go index bd5f4a937aa..d3f0809895b 100644 --- a/config/flags.go +++ b/config/flags.go @@ -143,6 +143,8 @@ func addNodeFlags(fs *flag.FlagSet) { fs.Duration(NetworkPingFrequencyKey, constants.DefaultPingFrequency, "Frequency of pinging other peers") fs.Bool(NetworkCompressionEnabledKey, constants.DefaultNetworkCompressionEnabled, "If true, compress certain outbound messages. This node will be able to parse compressed inbound messages regardless of this flag's value") + fs.String(NetworkCompressionTypeKey, constants.DefaultNetworkCompressionType.String(), "Preferred compression type for outbound messages. If a peer doesn't support it, a different compression type will be used for that peer") + fs.Duration(NetworkMaxClockDifferenceKey, constants.DefaultNetworkMaxClockDifference, "Max allowed clock difference value between this node and peers") fs.Bool(NetworkAllowPrivateIPsKey, constants.DefaultNetworkAllowPrivateIPs, "Allows the node to initiate outbound connection attempts to peers with private IPs") fs.Bool(NetworkRequireValidatorToConnectKey, constants.DefaultNetworkRequireValidatorToConnect, "If true, this node will only maintain a connection with another node if this node is a validator, the other node is a validator, or the other node is a beacon") diff --git a/config/keys.go b/config/keys.go index 8c65f20c9f2..9ee0b6abc7e 100644 --- a/config/keys.go +++ b/config/keys.go @@ -94,7 +94,8 @@ const ( NetworkPingTimeoutKey = "network-ping-timeout" NetworkPingFrequencyKey = "network-ping-frequency" NetworkMaxReconnectDelayKey = "network-max-reconnect-delay" - NetworkCompressionEnabledKey = "network-compression-enabled" + NetworkCompressionEnabledKey = "network-compression-enabled" // TODO this is deprecated. Eventually remove it and constants.DefaultNetworkCompressionEnabled + NetworkCompressionTypeKey = "network-compression-type" NetworkMaxClockDifferenceKey = "network-max-clock-difference" NetworkAllowPrivateIPsKey = "network-allow-private-ips" NetworkRequireValidatorToConnectKey = "network-require-validator-to-connect" diff --git a/network/config.go b/network/config.go index eaca1c2d7d3..4aeddf9bc53 100644 --- a/network/config.go +++ b/network/config.go @@ -15,6 +15,7 @@ import ( "github.com/ava-labs/avalanchego/snow/networking/tracker" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/ips" "github.com/ava-labs/avalanchego/utils/set" ) @@ -125,9 +126,10 @@ type Config struct { PingFrequency time.Duration `json:"pingFrequency"` AllowPrivateIPs bool `json:"allowPrivateIPs"` - // CompressionEnabled will compress available outbound messages when set to - // true. - CompressionEnabled bool `json:"compressionEnabled"` + // The preferred compression type to use when compressing outbound messages. + // If a peer doesn't support this compression type, the message will be + // compressed with a different compression type or not at all. + CompressionType compression.Type `json:"compressionType"` // TLSKey is this node's TLS key that is used to sign IPs. TLSKey crypto.Signer `json:"-"` diff --git a/network/network_test.go b/network/network_test.go index 5783ba929dc..6297bb8d318 100644 --- a/network/network_test.go +++ b/network/network_test.go @@ -111,7 +111,7 @@ var ( PingFrequency: constants.DefaultPingFrequency, AllowPrivateIPs: true, - CompressionEnabled: true, + CompressionType: constants.DefaultNetworkCompressionType, UptimeCalculator: uptime.NewManager(uptime.NewTestState()), UptimeMetricFreq: 30 * time.Second, diff --git a/network/test_network.go b/network/test_network.go index 09bc6e45d81..ce95725ea2c 100644 --- a/network/test_network.go +++ b/network/test_network.go @@ -163,7 +163,7 @@ func NewTestNetwork( }, MaxClockDifference: constants.DefaultNetworkMaxClockDifference, - CompressionEnabled: constants.DefaultNetworkCompressionEnabled, + CompressionType: constants.DefaultNetworkCompressionType, PingFrequency: constants.DefaultPingFrequency, AllowPrivateIPs: constants.DefaultNetworkAllowPrivateIPs, UptimeMetricFreq: constants.DefaultUptimeMetricFreq, diff --git a/node/node.go b/node/node.go index 78246a62397..25669a04d9d 100644 --- a/node/node.go +++ b/node/node.go @@ -1279,7 +1279,6 @@ func (n *Node) Initialize( n.msgCreator, err = message.NewCreator( n.MetricsRegisterer, n.networkNamespace, - // n.Config.NetworkConfig.CompressionEnabled, TODO add config for this compression.GzipCompression, n.Config.NetworkConfig.MaximumInboundMessageTimeout, ) diff --git a/utils/compression/compressor.go b/utils/compression/compressor.go index 8a5e4ec17c7..5cc4d95beef 100644 --- a/utils/compression/compressor.go +++ b/utils/compression/compressor.go @@ -3,14 +3,6 @@ package compression -type Type byte - -const ( - NoCompression Type = iota + 1 - GzipCompression - ZstdCompression -) - // Compressor compresss and decompresses messages. // Decompress is the inverse of Compress. // Decompress(Compress(msg)) == msg. diff --git a/utils/compression/type.go b/utils/compression/type.go new file mode 100644 index 00000000000..b404f680b2d --- /dev/null +++ b/utils/compression/type.go @@ -0,0 +1,67 @@ +// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package compression + +import ( + "errors" + "strings" +) + +var errUnknownCompressionType = errors.New("unknown compression type") + +type Type byte + +const ( + NoCompression Type = iota + 1 + GzipCompression + ZstdCompression +) + +func (t Type) String() string { + switch t { + case NoCompression: + return "none" + case GzipCompression: + return "gzip" + case ZstdCompression: + return "zstd" + default: + return "unknown" + } +} + +func TypeFromString(s string) (Type, error) { + switch s { + case NoCompression.String(): + return NoCompression, nil + case GzipCompression.String(): + return GzipCompression, nil + case ZstdCompression.String(): + return ZstdCompression, nil + default: + return NoCompression, errUnknownCompressionType + } +} + +func (t Type) MarshalJSON() ([]byte, error) { + var b strings.Builder + _, err := b.WriteString("\"") + if err != nil { + return nil, err + } + switch t { + case NoCompression, GzipCompression, ZstdCompression: + _, err = b.WriteString(t.String()) + default: + err = errUnknownCompressionType + } + if err != nil { + return nil, err + } + _, err = b.WriteString("\"") + if err != nil { + return nil, err + } + return []byte(b.String()), nil +} diff --git a/utils/constants/networking.go b/utils/constants/networking.go index 068b525c6ed..e33de4ec965 100644 --- a/utils/constants/networking.go +++ b/utils/constants/networking.go @@ -55,7 +55,7 @@ const ( DefaultNetworkTimeoutCoefficient = 2 DefaultNetworkReadHandshakeTimeout = 15 * time.Second - DefaultNetworkCompressionEnabled = true // TODO remove + DefaultNetworkCompressionEnabled = true // TODO remove when NetworkCompressionEnabledKey is removed DefaultNetworkCompressionType = compression.GzipCompression DefaultNetworkMaxClockDifference = time.Minute DefaultNetworkAllowPrivateIPs = true From bc55ea4fab0b522fc80db1f21567823bc693e8ab Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Thu, 2 Mar 2023 17:21:48 -0500 Subject: [PATCH 07/54] rename types --- message/compression_benchmark_test.go | 2 +- message/messages.go | 8 ++-- message/messages_benchmark_test.go | 2 +- message/messages_test.go | 68 +++++++++++++-------------- message/outbound_msg_builder.go | 26 +++++----- message/outbound_msg_builder_test.go | 2 +- network/network_test.go | 2 +- network/peer/peer_test.go | 2 +- network/peer/test_peer.go | 2 +- node/node.go | 2 +- snow/networking/sender/sender_test.go | 6 +-- utils/compression/type.go | 28 +++++------ utils/constants/networking.go | 2 +- vms/platformvm/vm_test.go | 2 +- 14 files changed, 77 insertions(+), 77 deletions(-) diff --git a/message/compression_benchmark_test.go b/message/compression_benchmark_test.go index d2a1374b302..82dcafa43bf 100644 --- a/message/compression_benchmark_test.go +++ b/message/compression_benchmark_test.go @@ -26,7 +26,7 @@ func init() { if err != nil { panic(err) } - builder := newOutboundBuilder(compression.NoCompression, innerBuilder) // Note compression disabled + builder := newOutboundBuilder(compression.TypeNone, innerBuilder) // Note compression disabled pingMsg, err := builder.Ping() if err != nil { diff --git a/message/messages.go b/message/messages.go index 3bd6d885f8d..eb64375a3fe 100644 --- a/message/messages.go +++ b/message/messages.go @@ -182,7 +182,7 @@ func (mb *msgBuilder) marshal( return nil, 0, 0, err } - if compressionType == compression.NoCompression { + if compressionType == compression.TypeNone { return uncompressedMsgBytes, 0, 0, nil } @@ -197,7 +197,7 @@ func (mb *msgBuilder) marshal( var compressedMsg p2p.Message switch compressionType { - case compression.GzipCompression: + case compression.TypeGzip: compressedBytes, err := mb.gzipCompressor.Compress(uncompressedMsgBytes) if err != nil { return nil, 0, 0, err @@ -208,7 +208,7 @@ func (mb *msgBuilder) marshal( }, } - case compression.ZstdCompression: + case compression.TypeZstd: compressedBytes, err := mb.zstdCompressor.Compress(uncompressedMsgBytes) if err != nil { return nil, 0, 0, err @@ -289,7 +289,7 @@ func (mb *msgBuilder) createOutbound(m *p2p.Message, compressionType compression return nil, err } - if compressionType != compression.NoCompression { + if compressionType != compression.TypeNone { mb.compressTimeMetrics[op].Observe(float64(compressTook)) } diff --git a/message/messages_benchmark_test.go b/message/messages_benchmark_test.go index 7f66b7766f6..e5cf2ce293e 100644 --- a/message/messages_benchmark_test.go +++ b/message/messages_benchmark_test.go @@ -71,7 +71,7 @@ func BenchmarkMarshalVersion(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { if useBuilder { - _, err = codec.createOutbound(&msg, compression.NoCompression, false) + _, err = codec.createOutbound(&msg, compression.TypeNone, false) } else { _, err = proto.Marshal(&msg) } diff --git a/message/messages_test.go b/message/messages_test.go index f91e32eebe1..dab4767a780 100644 --- a/message/messages_test.go +++ b/message/messages_test.go @@ -64,7 +64,7 @@ func TestMessage(t *testing.T) { Ping: &p2p.Ping{}, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -78,7 +78,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -98,7 +98,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -119,7 +119,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -141,7 +141,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -163,7 +163,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.GzipCompression, // TODO support zstd + compressionType: compression.TypeGzip, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -182,7 +182,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: false, bytesSaved: false, }, @@ -198,7 +198,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -214,7 +214,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -230,7 +230,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.GzipCompression, // TODO support zstd + compressionType: compression.TypeGzip, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -247,7 +247,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -264,7 +264,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.GzipCompression, // TODO support zstd + compressionType: compression.TypeGzip, // TODO support zstd bypassThrottling: true, bytesSaved: false, }, @@ -280,7 +280,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -296,7 +296,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.GzipCompression, // TODO support zstd + compressionType: compression.TypeGzip, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -313,7 +313,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -330,7 +330,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -348,7 +348,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -365,7 +365,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -383,7 +383,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -400,7 +400,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -417,7 +417,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.GzipCompression, // TODO support zstd + compressionType: compression.TypeGzip, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -435,7 +435,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -452,7 +452,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -469,7 +469,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.GzipCompression, // TODO support zstd + compressionType: compression.TypeGzip, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -487,7 +487,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -505,7 +505,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.GzipCompression, // TODO support zstd + compressionType: compression.TypeGzip, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -523,7 +523,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -540,7 +540,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -557,7 +557,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -574,7 +574,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.GzipCompression, // TODO support zstd + compressionType: compression.TypeGzip, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -590,7 +590,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -606,7 +606,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.GzipCompression, // TODO support zstd + compressionType: compression.TypeGzip, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, @@ -621,7 +621,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.NoCompression, + compressionType: compression.TypeNone, bypassThrottling: true, bytesSaved: false, }, @@ -636,7 +636,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.GzipCompression, // TODO support zstd + compressionType: compression.TypeGzip, // TODO support zstd bypassThrottling: true, bytesSaved: true, }, diff --git a/message/outbound_msg_builder.go b/message/outbound_msg_builder.go index 9e14da07f3a..5ae6e656868 100644 --- a/message/outbound_msg_builder.go +++ b/message/outbound_msg_builder.go @@ -193,7 +193,7 @@ func (b *outMsgBuilder) Ping() (OutboundMessage, error) { Ping: &p2p.Ping{}, }, }, - compression.NoCompression, + compression.TypeNone, false, ) } @@ -211,7 +211,7 @@ func (b *outMsgBuilder) Pong( }, }, }, - compression.NoCompression, + compression.TypeNone, false, ) } @@ -242,7 +242,7 @@ func (b *outMsgBuilder) Version( }, }, }, - compression.NoCompression, + compression.TypeNone, true, ) } @@ -281,7 +281,7 @@ func (b *outMsgBuilder) PeerListAck(peerAcks []*p2p.PeerAck) (OutboundMessage, e }, }, }, - compression.NoCompression, + compression.TypeNone, false, ) } @@ -301,7 +301,7 @@ func (b *outMsgBuilder) GetStateSummaryFrontier( }, }, }, - compression.NoCompression, + compression.TypeNone, false, ) } @@ -387,7 +387,7 @@ func (b *outMsgBuilder) GetAcceptedFrontier( }, }, }, - compression.NoCompression, + compression.TypeNone, false, ) } @@ -411,7 +411,7 @@ func (b *outMsgBuilder) AcceptedFrontier( }, }, }, - compression.NoCompression, + compression.TypeNone, false, ) } @@ -437,7 +437,7 @@ func (b *outMsgBuilder) GetAccepted( }, }, }, - compression.NoCompression, + compression.TypeNone, false, ) } @@ -461,7 +461,7 @@ func (b *outMsgBuilder) Accepted( }, }, }, - compression.NoCompression, + compression.TypeNone, false, ) } @@ -485,7 +485,7 @@ func (b *outMsgBuilder) GetAncestors( }, }, }, - compression.NoCompression, + compression.TypeNone, false, ) } @@ -531,7 +531,7 @@ func (b *outMsgBuilder) Get( }, }, }, - compression.NoCompression, + compression.TypeNone, false, ) } @@ -601,7 +601,7 @@ func (b *outMsgBuilder) PullQuery( }, }, }, - compression.NoCompression, + compression.TypeNone, false, ) } @@ -629,7 +629,7 @@ func (b *outMsgBuilder) Chits( }, }, }, - compression.NoCompression, + compression.TypeNone, false, ) } diff --git a/message/outbound_msg_builder_test.go b/message/outbound_msg_builder_test.go index 6d019c0bfb8..53a7c9f158e 100644 --- a/message/outbound_msg_builder_test.go +++ b/message/outbound_msg_builder_test.go @@ -26,7 +26,7 @@ func Test_newOutboundBuilder(t *testing.T) { ) require.NoError(err) - builder := newOutboundBuilder(compression.GzipCompression /*compress*/, mb) // TODO support zstd + builder := newOutboundBuilder(compression.TypeGzip /*compress*/, mb) // TODO support zstd outMsg, err := builder.GetAcceptedStateSummary( ids.GenerateTestID(), diff --git a/network/network_test.go b/network/network_test.go index 6297bb8d318..e1faf06bceb 100644 --- a/network/network_test.go +++ b/network/network_test.go @@ -186,7 +186,7 @@ func newMessageCreator(t *testing.T) message.Creator { mc, err := message.NewCreator( prometheus.NewRegistry(), "", - compression.GzipCompression, // TODO support zstd + compression.TypeGzip, // TODO support zstd 10*time.Second, ) require.NoError(t, err) diff --git a/network/peer/peer_test.go b/network/peer/peer_test.go index 84b53d7f79f..673240d5020 100644 --- a/network/peer/peer_test.go +++ b/network/peer/peer_test.go @@ -52,7 +52,7 @@ func newMessageCreator(t *testing.T) message.Creator { mc, err := message.NewCreator( prometheus.NewRegistry(), "", - compression.GzipCompression, // TODO support zstd + compression.TypeGzip, // TODO support zstd 10*time.Second, ) require.NoError(t, err) diff --git a/network/peer/test_peer.go b/network/peer/test_peer.go index 32ebf541a47..e86eeb5815c 100644 --- a/network/peer/test_peer.go +++ b/network/peer/test_peer.go @@ -72,7 +72,7 @@ func StartTestPeer( mc, err := message.NewCreator( prometheus.NewRegistry(), "", - compression.GzipCompression, // TODO support zstd + compression.TypeGzip, // TODO support zstd 10*time.Second, ) if err != nil { diff --git a/node/node.go b/node/node.go index 25669a04d9d..435a2714816 100644 --- a/node/node.go +++ b/node/node.go @@ -1279,7 +1279,7 @@ func (n *Node) Initialize( n.msgCreator, err = message.NewCreator( n.MetricsRegisterer, n.networkNamespace, - compression.GzipCompression, + compression.TypeGzip, n.Config.NetworkConfig.MaximumInboundMessageTimeout, ) if err != nil { diff --git a/snow/networking/sender/sender_test.go b/snow/networking/sender/sender_test.go index d84d76398a4..d9e806bce73 100644 --- a/snow/networking/sender/sender_test.go +++ b/snow/networking/sender/sender_test.go @@ -73,7 +73,7 @@ func TestTimeout(t *testing.T) { mc, err := message.NewCreator( metrics, "dummyNamespace", - compression.GzipCompression, // TODO support zstd + compression.TypeGzip, // TODO support zstd 10*time.Second, ) require.NoError(err) @@ -333,7 +333,7 @@ func TestReliableMessages(t *testing.T) { mc, err := message.NewCreator( metrics, "dummyNamespace", - compression.GzipCompression, // TODO support zstd + compression.TypeGzip, // TODO support zstd 10*time.Second, ) require.NoError(t, err) @@ -469,7 +469,7 @@ func TestReliableMessagesToMyself(t *testing.T) { mc, err := message.NewCreator( metrics, "dummyNamespace", - compression.GzipCompression, + compression.TypeGzip, 10*time.Second, ) require.NoError(t, err) diff --git a/utils/compression/type.go b/utils/compression/type.go index b404f680b2d..1502b77acfc 100644 --- a/utils/compression/type.go +++ b/utils/compression/type.go @@ -13,18 +13,18 @@ var errUnknownCompressionType = errors.New("unknown compression type") type Type byte const ( - NoCompression Type = iota + 1 - GzipCompression - ZstdCompression + TypeNone Type = iota + 1 + TypeGzip + TypeZstd ) func (t Type) String() string { switch t { - case NoCompression: + case TypeNone: return "none" - case GzipCompression: + case TypeGzip: return "gzip" - case ZstdCompression: + case TypeZstd: return "zstd" default: return "unknown" @@ -33,14 +33,14 @@ func (t Type) String() string { func TypeFromString(s string) (Type, error) { switch s { - case NoCompression.String(): - return NoCompression, nil - case GzipCompression.String(): - return GzipCompression, nil - case ZstdCompression.String(): - return ZstdCompression, nil + case TypeNone.String(): + return TypeNone, nil + case TypeGzip.String(): + return TypeGzip, nil + case TypeZstd.String(): + return TypeZstd, nil default: - return NoCompression, errUnknownCompressionType + return TypeNone, errUnknownCompressionType } } @@ -51,7 +51,7 @@ func (t Type) MarshalJSON() ([]byte, error) { return nil, err } switch t { - case NoCompression, GzipCompression, ZstdCompression: + case TypeNone, TypeGzip, TypeZstd: _, err = b.WriteString(t.String()) default: err = errUnknownCompressionType diff --git a/utils/constants/networking.go b/utils/constants/networking.go index e33de4ec965..312b244db4a 100644 --- a/utils/constants/networking.go +++ b/utils/constants/networking.go @@ -56,7 +56,7 @@ const ( DefaultNetworkReadHandshakeTimeout = 15 * time.Second DefaultNetworkCompressionEnabled = true // TODO remove when NetworkCompressionEnabledKey is removed - DefaultNetworkCompressionType = compression.GzipCompression + DefaultNetworkCompressionType = compression.TypeGzip DefaultNetworkMaxClockDifference = time.Minute DefaultNetworkAllowPrivateIPs = true DefaultNetworkRequireValidatorToConnect = false diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 8549731c9a7..e2e89a12bd9 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -1722,7 +1722,7 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { chainRouter := &router.ChainRouter{} metrics := prometheus.NewRegistry() - mc, err := message.NewCreator(metrics, "dummyNamespace", compression.GzipCompression, 10*time.Second) + mc, err := message.NewCreator(metrics, "dummyNamespace", compression.TypeGzip, 10*time.Second) require.NoError(err) err = chainRouter.Initialize( From 400a918f44888396e8ee71c6015be3507e79faed Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Fri, 3 Mar 2023 10:29:05 -0500 Subject: [PATCH 08/54] add zstd compression/decompression metrics --- message/messages.go | 81 ++++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 27 deletions(-) diff --git a/message/messages.go b/message/messages.go index eb64375a3fe..ecfd01c8198 100644 --- a/message/messages.go +++ b/message/messages.go @@ -124,11 +124,13 @@ func (m *outboundMessage) BytesSavedCompression() int { // TODO: add other compression algorithms with extended interface type msgBuilder struct { - gzipCompressor compression.Compressor - zstdCompressor compression.Compressor + gzipCompressor compression.Compressor + gzipCompressTimeMetrics map[Op]metric.Averager + gzipDecompressTimeMetrics map[Op]metric.Averager - compressTimeMetrics map[Op]metric.Averager - decompressTimeMetrics map[Op]metric.Averager + zstdCompressor compression.Compressor + zstdCompressTimeMetrics map[Op]metric.Averager + zstdDecompressTimeMetrics map[Op]metric.Averager maxMessageTimeout time.Duration } @@ -144,28 +146,44 @@ func newMsgBuilder( } mb := &msgBuilder{ - gzipCompressor: cpr, - zstdCompressor: compression.NewZstdCompressor(), + gzipCompressor: cpr, + gzipCompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), + gzipDecompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), - compressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), - decompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), + zstdCompressor: compression.NewZstdCompressor(), + zstdCompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), + zstdDecompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), maxMessageTimeout: maxMessageTimeout, } errs := wrappers.Errs{} for _, op := range ExternalOps { - mb.compressTimeMetrics[op] = metric.NewAveragerWithErrs( + mb.gzipCompressTimeMetrics[op] = metric.NewAveragerWithErrs( namespace, - fmt.Sprintf("%s_compress_time", op), - fmt.Sprintf("time (in ns) to compress %s messages", op), + fmt.Sprintf("gzip_%s_compress_time", op), + fmt.Sprintf("time (in ns) to compress %s messages with gzip", op), metrics, &errs, ) - mb.decompressTimeMetrics[op] = metric.NewAveragerWithErrs( + mb.gzipDecompressTimeMetrics[op] = metric.NewAveragerWithErrs( namespace, - fmt.Sprintf("%s_decompress_time", op), - fmt.Sprintf("time (in ns) to decompress %s messages", op), + fmt.Sprintf("gzip_%s_decompress_time", op), + fmt.Sprintf("time (in ns) to decompress %s messages with gzip", op), + metrics, + &errs, + ) + mb.zstdCompressTimeMetrics[op] = metric.NewAveragerWithErrs( + namespace, + fmt.Sprintf("zstd_%s_compress_time", op), + fmt.Sprintf("time (in ns) to compress %s messages with zstd", op), + metrics, + &errs, + ) + mb.zstdDecompressTimeMetrics[op] = metric.NewAveragerWithErrs( + namespace, + fmt.Sprintf("zstd_%s_decompress_time", op), + fmt.Sprintf("time (in ns) to decompress %s messages with zstd", op), metrics, &errs, ) @@ -232,50 +250,53 @@ func (mb *msgBuilder) marshal( return compressedMsgBytes, bytesSaved, compressTook, nil } -func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, bool, int, time.Duration, error) { +func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, compression.Type, int, time.Duration, error) { m := new(p2p.Message) if err := proto.Unmarshal(b, m); err != nil { - return nil, false, 0, 0, err + return nil, compression.TypeNone, 0, 0, err } gzipCompressed := m.GetCompressedGzip() zstdCompressed := m.GetCompressedZstd() if len(gzipCompressed) == 0 && len(zstdCompressed) == 0 { // The message wasn't compressed - return m, false, 0, 0, nil + return m, compression.TypeNone, 0, 0, nil } if len(gzipCompressed) > 0 && len(zstdCompressed) > 0 { - return nil, true, 0, 0, errMultipleCompressionTypes + return nil, compression.TypeNone, 0, 0, errMultipleCompressionTypes } startTime := time.Now() var ( bytesSavedCompression int + compressionType compression.Type decompressed []byte err error ) if len(gzipCompressed) > 0 { + compressionType = compression.TypeGzip decompressed, err = mb.gzipCompressor.Decompress(gzipCompressed) if err != nil { - return nil, true, 0, 0, err + return nil, compression.TypeGzip, 0, 0, err } bytesSavedCompression = len(decompressed) - len(gzipCompressed) } if len(zstdCompressed) > 0 { + compressionType = compression.TypeZstd decompressed, err = mb.zstdCompressor.Decompress(zstdCompressed) if err != nil { - return nil, true, 0, 0, err + return nil, compression.TypeZstd, 0, 0, err } bytesSavedCompression = len(decompressed) - len(zstdCompressed) } if err := proto.Unmarshal(decompressed, m); err != nil { - return nil, true, 0, 0, err + return nil, compression.TypeNone, 0, 0, err } decompressTook := time.Since(startTime) - return m, true, bytesSavedCompression, decompressTook, nil + return m, compressionType, bytesSavedCompression, decompressTook, nil } func (mb *msgBuilder) createOutbound(m *p2p.Message, compressionType compression.Type, bypassThrottling bool) (*outboundMessage, error) { @@ -289,8 +310,11 @@ func (mb *msgBuilder) createOutbound(m *p2p.Message, compressionType compression return nil, err } - if compressionType != compression.TypeNone { - mb.compressTimeMetrics[op].Observe(float64(compressTook)) + switch compressionType { + case compression.TypeGzip: + mb.gzipCompressTimeMetrics[op].Observe(float64(compressTook)) + case compression.TypeZstd: + mb.zstdCompressTimeMetrics[op].Observe(float64(compressTook)) } return &outboundMessage{ @@ -306,7 +330,7 @@ func (mb *msgBuilder) parseInbound( nodeID ids.NodeID, onFinishedHandling func(), ) (*inboundMessage, error) { - m, wasCompressed, bytesSavedCompression, decompressTook, err := mb.unmarshal(bytes) + m, compressionType, bytesSavedCompression, decompressTook, err := mb.unmarshal(bytes) if err != nil { return nil, err } @@ -321,8 +345,11 @@ func (mb *msgBuilder) parseInbound( return nil, err } - if wasCompressed { - mb.decompressTimeMetrics[op].Observe(float64(decompressTook)) + switch compressionType { + case compression.TypeGzip: + mb.gzipDecompressTimeMetrics[op].Observe(float64(decompressTook)) + case compression.TypeZstd: + mb.zstdDecompressTimeMetrics[op].Observe(float64(decompressTook)) } expiration := mockable.MaxTime From 38e7a123a46eb55bf59a76bb5ee0e5454a23d9b4 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Fri, 3 Mar 2023 13:14:09 -0500 Subject: [PATCH 09/54] don't allow 2 network compression flags --- config/config.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/config/config.go b/config/config.go index 0f484aa88ab..e94867c16c7 100644 --- a/config/config.go +++ b/config/config.go @@ -298,10 +298,28 @@ func getNetworkConfig(v *viper.Viper, stakingEnabled bool, halflife time.Duratio upgradeCooldown := v.GetDuration(InboundConnUpgradeThrottlerCooldownKey) upgradeCooldownInSeconds := upgradeCooldown.Seconds() maxRecentConnsUpgraded := int(math.Ceil(maxInboundConnsPerSec * upgradeCooldownInSeconds)) - compressionType, err := compression.TypeFromString(v.GetString(NetworkCompressionTypeKey)) - if err != nil { - return network.Config{}, err + + var ( + compressionType compression.Type + err error + ) + if v.IsSet(NetworkCompressionTypeKey) { + if v.IsSet(NetworkCompressionEnabledKey) { + return network.Config{}, fmt.Errorf("cannot set both %q and %q", NetworkCompressionTypeKey, NetworkCompressionEnabledKey) + } + + compressionType, err = compression.TypeFromString(v.GetString(NetworkCompressionTypeKey)) + if err != nil { + return network.Config{}, err + } + } else { + if v.GetBool(NetworkCompressionEnabledKey) { + compressionType = constants.DefaultNetworkCompressionType + } else { + compressionType = compression.TypeNone + } } + config := network.Config{ // Throttling ThrottlerConfig: network.ThrottlerConfig{ From 3850c793885c7ca9211caf0d7188702ba74e31cf Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Fri, 3 Mar 2023 13:38:54 -0500 Subject: [PATCH 10/54] remove benchmark --- message/compression_benchmark_test.go | 127 -------------------------- 1 file changed, 127 deletions(-) delete mode 100644 message/compression_benchmark_test.go diff --git a/message/compression_benchmark_test.go b/message/compression_benchmark_test.go deleted file mode 100644 index 82dcafa43bf..00000000000 --- a/message/compression_benchmark_test.go +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package message - -import ( - "math" - "net" - "testing" - "time" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/proto/pb/p2p" - "github.com/ava-labs/avalanchego/utils" - "github.com/ava-labs/avalanchego/utils/compression" - "github.com/ava-labs/avalanchego/utils/hashing" - "github.com/ava-labs/avalanchego/utils/ips" - "github.com/prometheus/client_golang/prometheus" -) - -// TODO only use messages that are actually compressed on the wire -var msgs = map[string][]byte{} - -func init() { - innerBuilder, err := newMsgBuilder("", prometheus.NewRegistry(), 10*time.Second) - if err != nil { - panic(err) - } - builder := newOutboundBuilder(compression.TypeNone, innerBuilder) // Note compression disabled - - pingMsg, err := builder.Ping() - if err != nil { - panic(err) - } - msgs["ping"] = pingMsg.Bytes() - - pongMsg, err := builder.Pong(100, []*p2p.SubnetUptime{ - { - SubnetId: utils.RandomBytes(hashing.HashLen), - Uptime: 3, - }, - }) - if err != nil { - panic(err) - } - msgs["pong"] = pongMsg.Bytes() - - versionMsg, err := builder.Version( - 1, - uint64(time.Now().Unix()), - ips.IPPort{ - IP: net.IPv4(127, 0, 0, 1), - Port: 9651, - }, - "v1.0.0", - uint64(time.Now().Unix()), - utils.RandomBytes(256), - []ids.ID{ids.GenerateTestID()}, - ) - if err != nil { - panic(err) - } - msgs["version"] = versionMsg.Bytes() - - chitsMsg, err := builder.Chits( - ids.GenerateTestID(), - 12341234, - []ids.ID{ids.GenerateTestID()}, - []ids.ID{ids.GenerateTestID()}, - p2p.EngineType_ENGINE_TYPE_SNOWMAN, - ) - if err != nil { - panic(err) - } - msgs["chits"] = chitsMsg.Bytes() - - peerListAckMsg, err := builder.PeerListAck([]*p2p.PeerAck{ - { - TxId: utils.RandomBytes(hashing.HashLen), - Timestamp: uint64(time.Now().Unix()), - }, - { - TxId: utils.RandomBytes(hashing.HashLen), - Timestamp: uint64(time.Now().Unix()), - }, - { - TxId: utils.RandomBytes(hashing.HashLen), - Timestamp: uint64(time.Now().Unix()), - }, - }) - if err != nil { - panic(err) - } - msgs["peerListAck"] = peerListAckMsg.Bytes() -} - -func BenchmarkCompressor(b *testing.B) { - zstdCompressor := compression.NewZstdCompressor() - gzipCompressor, err := compression.NewGzipCompressor(math.MaxUint32) - if err != nil { - b.Fatal(err) - } - - compressors := map[string]compression.Compressor{ - "zstd": zstdCompressor, - "gzip": gzipCompressor, - } - - for compressorName, compressor := range compressors { - for msgName, msg := range msgs { - b.Run(compressorName+" "+msgName, func(b *testing.B) { - var bytesSaved int - for i := 0; i < b.N; i++ { - compressed, err := compressor.Compress(msg) - if err != nil { - b.Fatal(err) - } - // if _, err := compressor.Decompress(compressed); err != nil { - // b.Fatal(err) - // } - bytesSaved += len(msg) - len(compressed) - } - b.ReportMetric(float64(bytesSaved)/float64(b.N), "bytes_saved/op") - }) - } - } -} From 6065be8850f7152853a6738935ca0f16e24dfa09 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Fri, 3 Mar 2023 14:22:49 -0500 Subject: [PATCH 11/54] cleanup --- message/messages.go | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/message/messages.go b/message/messages.go index ecfd01c8198..9acf0191d27 100644 --- a/message/messages.go +++ b/message/messages.go @@ -256,6 +256,7 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, compression.Type, int, return nil, compression.TypeNone, 0, 0, err } + // Figure out what compression type, if any, was used to compress the message. gzipCompressed := m.GetCompressedGzip() zstdCompressed := m.GetCompressedZstd() if len(gzipCompressed) == 0 && len(zstdCompressed) == 0 { @@ -266,30 +267,25 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, compression.Type, int, return nil, compression.TypeNone, 0, 0, errMultipleCompressionTypes } - startTime := time.Now() - var ( - bytesSavedCompression int - compressionType compression.Type - decompressed []byte - err error + compressionType compression.Type + compressor compression.Compressor ) if len(gzipCompressed) > 0 { compressionType = compression.TypeGzip - decompressed, err = mb.gzipCompressor.Decompress(gzipCompressed) - if err != nil { - return nil, compression.TypeGzip, 0, 0, err - } - bytesSavedCompression = len(decompressed) - len(gzipCompressed) - } - if len(zstdCompressed) > 0 { + compressor = mb.gzipCompressor + } else { compressionType = compression.TypeZstd - decompressed, err = mb.zstdCompressor.Decompress(zstdCompressed) - if err != nil { - return nil, compression.TypeZstd, 0, 0, err - } - bytesSavedCompression = len(decompressed) - len(zstdCompressed) + compressor = mb.zstdCompressor + } + + startTime := time.Now() + + decompressed, err := compressor.Decompress(gzipCompressed) + if err != nil { + return nil, compression.TypeGzip, 0, 0, err } + bytesSavedCompression := len(decompressed) - len(gzipCompressed) if err := proto.Unmarshal(decompressed, m); err != nil { return nil, compression.TypeNone, 0, 0, err From d7c5d52723898c0efb017a80aa642534f267f1db Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 7 Mar 2023 15:26:25 -0500 Subject: [PATCH 12/54] don't use zstd until v1.10 --- config/config.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/config/config.go b/config/config.go index e94867c16c7..3a712b740e5 100644 --- a/config/config.go +++ b/config/config.go @@ -48,6 +48,7 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/storage" "github.com/ava-labs/avalanchego/utils/timer" + "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/proposervm" @@ -81,6 +82,7 @@ var ( errMissingStakingSigningKeyFile = errors.New("missing staking signing key file") errTracingEndpointEmpty = fmt.Errorf("%s cannot be empty", TracingEndpointKey) errPluginDirNotADirectory = errors.New("plugin dir is not a directory") + errZstdNotSupported = errors.New("zstd compression not yet supported") ) func getConsensusConfig(v *viper.Viper) avalanche.Parameters { @@ -320,6 +322,12 @@ func getNetworkConfig(v *viper.Viper, stakingEnabled bool, halflife time.Duratio } } + version110 := &version.Semantic{Major: 1, Minor: 10, Patch: 0} + if compressionType == compression.TypeZstd && version.Current.Compare(version110) < 0 { + // TODO change this to check for v1.10 upgrade time instead of version. + // TODO remove after all nodes are on v1.10. + return network.Config{}, errZstdNotSupported + } config := network.Config{ // Throttling ThrottlerConfig: network.ThrottlerConfig{ From 385ba27d069a6fbc45b4a0baff581c1a0d6a360c Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 7 Mar 2023 15:31:27 -0500 Subject: [PATCH 13/54] tweak error message --- config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/config.go b/config/config.go index 3a712b740e5..ca390b4e363 100644 --- a/config/config.go +++ b/config/config.go @@ -82,7 +82,7 @@ var ( errMissingStakingSigningKeyFile = errors.New("missing staking signing key file") errTracingEndpointEmpty = fmt.Errorf("%s cannot be empty", TracingEndpointKey) errPluginDirNotADirectory = errors.New("plugin dir is not a directory") - errZstdNotSupported = errors.New("zstd compression not yet supported") + errZstdNotSupported = errors.New("zstd compression not supported until v1.10") ) func getConsensusConfig(v *viper.Viper) avalanche.Parameters { From 37bcf39a41892757ad0913b0ae0da919875c3ecd Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 7 Mar 2023 15:38:38 -0500 Subject: [PATCH 14/54] nit --- message/messages.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/message/messages.go b/message/messages.go index 9acf0191d27..a86a724ca56 100644 --- a/message/messages.go +++ b/message/messages.go @@ -200,21 +200,19 @@ func (mb *msgBuilder) marshal( return nil, 0, 0, err } - if compressionType == compression.TypeNone { - return uncompressedMsgBytes, 0, 0, nil - } - // If compression is enabled, we marshal twice: // 1. the original message // 2. the message with compressed bytes // // This recursive packing allows us to avoid an extra compression on/off // field in the message. - startTime := time.Now() - - var compressedMsg p2p.Message - + var ( + startTime = time.Now() + compressedMsg p2p.Message + ) switch compressionType { + case compression.TypeNone: + return uncompressedMsgBytes, 0, 0, nil case compression.TypeGzip: compressedBytes, err := mb.gzipCompressor.Compress(uncompressedMsgBytes) if err != nil { From 81afb719d4030c4ac9e4f6b1b99f07c5afacbcf5 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 7 Mar 2023 15:44:10 -0500 Subject: [PATCH 15/54] nits --- message/messages.go | 53 ++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/message/messages.go b/message/messages.go index a86a724ca56..75b33098362 100644 --- a/message/messages.go +++ b/message/messages.go @@ -248,31 +248,29 @@ func (mb *msgBuilder) marshal( return compressedMsgBytes, bytesSaved, compressTook, nil } -func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, compression.Type, int, time.Duration, error) { +func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, error) { m := new(p2p.Message) if err := proto.Unmarshal(b, m); err != nil { - return nil, compression.TypeNone, 0, 0, err + return nil, 0, err } // Figure out what compression type, if any, was used to compress the message. - gzipCompressed := m.GetCompressedGzip() - zstdCompressed := m.GetCompressedZstd() - if len(gzipCompressed) == 0 && len(zstdCompressed) == 0 { - // The message wasn't compressed - return m, compression.TypeNone, 0, 0, nil - } - if len(gzipCompressed) > 0 && len(zstdCompressed) > 0 { - return nil, compression.TypeNone, 0, 0, errMultipleCompressionTypes - } - var ( compressionType compression.Type compressor compression.Compressor + gzipCompressed = m.GetCompressedGzip() + zstdCompressed = m.GetCompressedZstd() ) - if len(gzipCompressed) > 0 { + switch { + case len(gzipCompressed) == 0 && len(zstdCompressed) == 0: + // The message wasn't compressed + return m, 0, nil + case len(gzipCompressed) > 0 && len(zstdCompressed) > 0: + return nil, 0, errMultipleCompressionTypes + case len(gzipCompressed) > 0: compressionType = compression.TypeGzip compressor = mb.gzipCompressor - } else { + case len(zstdCompressed) > 0: compressionType = compression.TypeZstd compressor = mb.zstdCompressor } @@ -281,16 +279,28 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, compression.Type, int, decompressed, err := compressor.Decompress(gzipCompressed) if err != nil { - return nil, compression.TypeGzip, 0, 0, err + return nil, 0, err } bytesSavedCompression := len(decompressed) - len(gzipCompressed) if err := proto.Unmarshal(decompressed, m); err != nil { - return nil, compression.TypeNone, 0, 0, err + return nil, 0, err } decompressTook := time.Since(startTime) - return m, compressionType, bytesSavedCompression, decompressTook, nil + // Record decompression time metric + op, err := ToOp(m) + if err != nil { + return nil, 0, err + } + switch compressionType { + case compression.TypeGzip: + mb.gzipDecompressTimeMetrics[op].Observe(float64(decompressTook)) + case compression.TypeZstd: + mb.zstdDecompressTimeMetrics[op].Observe(float64(decompressTook)) + } + + return m, bytesSavedCompression, nil } func (mb *msgBuilder) createOutbound(m *p2p.Message, compressionType compression.Type, bypassThrottling bool) (*outboundMessage, error) { @@ -324,7 +334,7 @@ func (mb *msgBuilder) parseInbound( nodeID ids.NodeID, onFinishedHandling func(), ) (*inboundMessage, error) { - m, compressionType, bytesSavedCompression, decompressTook, err := mb.unmarshal(bytes) + m, bytesSavedCompression, err := mb.unmarshal(bytes) if err != nil { return nil, err } @@ -339,13 +349,6 @@ func (mb *msgBuilder) parseInbound( return nil, err } - switch compressionType { - case compression.TypeGzip: - mb.gzipDecompressTimeMetrics[op].Observe(float64(decompressTook)) - case compression.TypeZstd: - mb.zstdDecompressTimeMetrics[op].Observe(float64(decompressTook)) - } - expiration := mockable.MaxTime if deadline, ok := GetDeadline(msg); ok { deadline = math.Min(deadline, mb.maxMessageTimeout) From 4da5f21f14b570bf5893f74ad2515b9d24e0591c Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 7 Mar 2023 15:46:59 -0500 Subject: [PATCH 16/54] nits --- message/outbound_msg_builder_test.go | 2 +- network/config.go | 5 ++- utils/compression/compression_bechmark.go | 38 ----------------------- 3 files changed, 3 insertions(+), 42 deletions(-) delete mode 100644 utils/compression/compression_bechmark.go diff --git a/message/outbound_msg_builder_test.go b/message/outbound_msg_builder_test.go index 53a7c9f158e..4625bde7c6d 100644 --- a/message/outbound_msg_builder_test.go +++ b/message/outbound_msg_builder_test.go @@ -26,7 +26,7 @@ func Test_newOutboundBuilder(t *testing.T) { ) require.NoError(err) - builder := newOutboundBuilder(compression.TypeGzip /*compress*/, mb) // TODO support zstd + builder := newOutboundBuilder(compression.TypeGzip, mb) // TODO support zstd outMsg, err := builder.GetAcceptedStateSummary( ids.GenerateTestID(), diff --git a/network/config.go b/network/config.go index 4aeddf9bc53..675fc63324e 100644 --- a/network/config.go +++ b/network/config.go @@ -126,9 +126,8 @@ type Config struct { PingFrequency time.Duration `json:"pingFrequency"` AllowPrivateIPs bool `json:"allowPrivateIPs"` - // The preferred compression type to use when compressing outbound messages. - // If a peer doesn't support this compression type, the message will be - // compressed with a different compression type or not at all. + // The compression type to use when compressing outbound messages. + // Assumes all peers support this compression type. CompressionType compression.Type `json:"compressionType"` // TLSKey is this node's TLS key that is used to sign IPs. diff --git a/utils/compression/compression_bechmark.go b/utils/compression/compression_bechmark.go deleted file mode 100644 index 4f3470da0a3..00000000000 --- a/utils/compression/compression_bechmark.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package compression - -import ( - "testing" - - "github.com/ava-labs/avalanchego/proto/pb/p2p" - "google.golang.org/protobuf/proto" -) - -var msgs = [][]byte{} - -func init() { - pingMsg := p2p.Message{ - Message: &p2p.Message_Ping{ - Ping: &p2p.Ping{}, - }, - } - pingMsgBytes, err := proto.Marshal(&pingMsg) - if err != nil { - panic(err) - } - msgs = append(msgs, pingMsgBytes) -} - -func BenchmarkCompressor(b *testing.B, compressor Compressor, msg []byte) { - for i := 0; i < b.N; i++ { - compressed, err := compressor.Compress(msg) - if err != nil { - b.Fatal(err) - } - if _, err := compressor.Decompress(compressed); err != nil { - b.Fatal(err) - } - } -} From d9b778cbc47d8e289c8d9eeaa3b2230d35060a55 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 8 Mar 2023 09:36:11 -0500 Subject: [PATCH 17/54] flag wording nit --- config/flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/flags.go b/config/flags.go index d3f0809895b..df3885fb4e1 100644 --- a/config/flags.go +++ b/config/flags.go @@ -143,7 +143,7 @@ func addNodeFlags(fs *flag.FlagSet) { fs.Duration(NetworkPingFrequencyKey, constants.DefaultPingFrequency, "Frequency of pinging other peers") fs.Bool(NetworkCompressionEnabledKey, constants.DefaultNetworkCompressionEnabled, "If true, compress certain outbound messages. This node will be able to parse compressed inbound messages regardless of this flag's value") - fs.String(NetworkCompressionTypeKey, constants.DefaultNetworkCompressionType.String(), "Preferred compression type for outbound messages. If a peer doesn't support it, a different compression type will be used for that peer") + fs.String(NetworkCompressionTypeKey, constants.DefaultNetworkCompressionType.String(), "Preferred compression type for outbound messages") fs.Duration(NetworkMaxClockDifferenceKey, constants.DefaultNetworkMaxClockDifference, "Max allowed clock difference value between this node and peers") fs.Bool(NetworkAllowPrivateIPsKey, constants.DefaultNetworkAllowPrivateIPs, "Allows the node to initiate outbound connection attempts to peers with private IPs") From 41bc6c500bc77438ba5acc5c509d6fc89df542de Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 8 Mar 2023 10:16:30 -0500 Subject: [PATCH 18/54] add zstd tests; fix bugs --- message/messages.go | 7 +- message/messages_test.go | 211 +++++++++++++++++++++++++++++++++++---- 2 files changed, 196 insertions(+), 22 deletions(-) diff --git a/message/messages.go b/message/messages.go index 75b33098362..71429d18beb 100644 --- a/message/messages.go +++ b/message/messages.go @@ -258,6 +258,7 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, error) { var ( compressionType compression.Type compressor compression.Compressor + compressedBytes []byte gzipCompressed = m.GetCompressedGzip() zstdCompressed = m.GetCompressedZstd() ) @@ -270,18 +271,20 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, error) { case len(gzipCompressed) > 0: compressionType = compression.TypeGzip compressor = mb.gzipCompressor + compressedBytes = gzipCompressed case len(zstdCompressed) > 0: compressionType = compression.TypeZstd compressor = mb.zstdCompressor + compressedBytes = zstdCompressed } startTime := time.Now() - decompressed, err := compressor.Decompress(gzipCompressed) + decompressed, err := compressor.Decompress(compressedBytes) if err != nil { return nil, 0, err } - bytesSavedCompression := len(decompressed) - len(gzipCompressed) + bytesSavedCompression := len(decompressed) - len(compressedBytes) if err := proto.Unmarshal(decompressed, m); err != nil { return nil, 0, err diff --git a/message/messages_test.go b/message/messages_test.go index dab4767a780..2eda19f0e4f 100644 --- a/message/messages_test.go +++ b/message/messages_test.go @@ -146,7 +146,7 @@ func TestMessage(t *testing.T) { bytesSaved: false, }, { - desc: "peer_list message with compression", + desc: "peer_list message with gzip compression", op: PeerListOp, msg: &p2p.Message{ Message: &p2p.Message_PeerList{ @@ -163,7 +163,29 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.TypeGzip, // TODO support zstd + compressionType: compression.TypeGzip, + bypassThrottling: true, + bytesSaved: true, + }, + { + desc: "peer_list message with zstd compression", + op: PeerListOp, + msg: &p2p.Message{ + Message: &p2p.Message_PeerList{ + PeerList: &p2p.PeerList{ + ClaimedIpPorts: []*p2p.ClaimedIpPort{ + { + X509Certificate: testTLSCert.Certificate[0], + IpAddr: []byte(net.IPv6zero), + IpPort: 9651, + Timestamp: uint64(nowUnix), + Signature: compressibleContainers[0], + }, + }, + }, + }, + }, + compressionType: compression.TypeZstd, bypassThrottling: true, bytesSaved: true, }, @@ -219,7 +241,7 @@ func TestMessage(t *testing.T) { bytesSaved: false, }, { - desc: "state_summary_frontier message with compression", + desc: "state_summary_frontier message with gzip compression", op: StateSummaryFrontierOp, msg: &p2p.Message{ Message: &p2p.Message_StateSummaryFrontier_{ @@ -230,7 +252,23 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.TypeGzip, // TODO support zstd + compressionType: compression.TypeGzip, + bypassThrottling: true, + bytesSaved: true, + }, + { + desc: "state_summary_frontier message with zstd compression", + op: StateSummaryFrontierOp, + msg: &p2p.Message{ + Message: &p2p.Message_StateSummaryFrontier_{ + StateSummaryFrontier_: &p2p.StateSummaryFrontier{ + ChainId: testID[:], + RequestId: 1, + Summary: compressibleContainers[0], + }, + }, + }, + compressionType: compression.TypeZstd, bypassThrottling: true, bytesSaved: true, }, @@ -252,7 +290,7 @@ func TestMessage(t *testing.T) { bytesSaved: false, }, { - desc: "get_accepted_state_summary message with compression", + desc: "get_accepted_state_summary message with gzip compression", op: GetAcceptedStateSummaryOp, msg: &p2p.Message{ Message: &p2p.Message_GetAcceptedStateSummary{ @@ -264,10 +302,27 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.TypeGzip, // TODO support zstd + compressionType: compression.TypeGzip, bypassThrottling: true, bytesSaved: false, }, + { + desc: "get_accepted_state_summary message with zstd compression", + op: GetAcceptedStateSummaryOp, + msg: &p2p.Message{ + Message: &p2p.Message_GetAcceptedStateSummary{ + GetAcceptedStateSummary: &p2p.GetAcceptedStateSummary{ + ChainId: testID[:], + RequestId: 1, + Deadline: 1, + Heights: []uint64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + }, + }, + }, + compressionType: compression.TypeZstd, + bypassThrottling: true, + bytesSaved: true, + }, { desc: "accepted_state_summary message with no compression", op: AcceptedStateSummaryOp, @@ -285,7 +340,23 @@ func TestMessage(t *testing.T) { bytesSaved: false, }, { - desc: "accepted_state_summary message with compression", + desc: "accepted_state_summary message with gzip compression", + op: AcceptedStateSummaryOp, + msg: &p2p.Message{ + Message: &p2p.Message_AcceptedStateSummary_{ + AcceptedStateSummary_: &p2p.AcceptedStateSummary{ + ChainId: testID[:], + RequestId: 1, + SummaryIds: [][]byte{testID[:], testID[:], testID[:], testID[:], testID[:], testID[:], testID[:], testID[:], testID[:]}, + }, + }, + }, + compressionType: compression.TypeGzip, + bypassThrottling: true, + bytesSaved: true, + }, + { + desc: "accepted_state_summary message with zstd compression", op: AcceptedStateSummaryOp, msg: &p2p.Message{ Message: &p2p.Message_AcceptedStateSummary_{ @@ -296,7 +367,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.TypeGzip, // TODO support zstd + compressionType: compression.TypeZstd, bypassThrottling: true, bytesSaved: true, }, @@ -405,7 +476,7 @@ func TestMessage(t *testing.T) { bytesSaved: false, }, { - desc: "ancestors message with compression", + desc: "ancestors message with gzip compression", op: AncestorsOp, msg: &p2p.Message{ Message: &p2p.Message_Ancestors_{ @@ -417,7 +488,24 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.TypeGzip, // TODO support zstd + compressionType: compression.TypeGzip, + bypassThrottling: true, + bytesSaved: true, + }, + { + desc: "ancestors message with zstd compression", + op: AncestorsOp, + msg: &p2p.Message{ + Message: &p2p.Message_Ancestors_{ + Ancestors_: &p2p.Ancestors{ + ChainId: testID[:], + RequestId: 12345, + Containers: compressibleContainers, + EngineType: p2p.EngineType_ENGINE_TYPE_AVALANCHE, + }, + }, + }, + compressionType: compression.TypeZstd, bypassThrottling: true, bytesSaved: true, }, @@ -457,7 +545,7 @@ func TestMessage(t *testing.T) { bytesSaved: false, }, { - desc: "put message with compression", + desc: "put message with gzip compression", op: PutOp, msg: &p2p.Message{ Message: &p2p.Message_Put{ @@ -469,7 +557,24 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.TypeGzip, // TODO support zstd + compressionType: compression.TypeGzip, + bypassThrottling: true, + bytesSaved: true, + }, + { + desc: "put message with zstd compression", + op: PutOp, + msg: &p2p.Message{ + Message: &p2p.Message_Put{ + Put: &p2p.Put{ + ChainId: testID[:], + RequestId: 1, + Container: compressibleContainers[0], + EngineType: p2p.EngineType_ENGINE_TYPE_AVALANCHE, + }, + }, + }, + compressionType: compression.TypeZstd, bypassThrottling: true, bytesSaved: true, }, @@ -492,7 +597,25 @@ func TestMessage(t *testing.T) { bytesSaved: false, }, { - desc: "push_query message with compression", + desc: "push_query message with gzip compression", + op: PushQueryOp, + msg: &p2p.Message{ + Message: &p2p.Message_PushQuery{ + PushQuery: &p2p.PushQuery{ + ChainId: testID[:], + RequestId: 1, + Deadline: 1, + Container: compressibleContainers[0], + EngineType: p2p.EngineType_ENGINE_TYPE_AVALANCHE, + }, + }, + }, + compressionType: compression.TypeGzip, + bypassThrottling: true, + bytesSaved: true, + }, + { + desc: "push_query message with zstd compression", op: PushQueryOp, msg: &p2p.Message{ Message: &p2p.Message_PushQuery{ @@ -505,7 +628,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.TypeGzip, // TODO support zstd + compressionType: compression.TypeZstd, bypassThrottling: true, bytesSaved: true, }, @@ -562,7 +685,7 @@ func TestMessage(t *testing.T) { bytesSaved: false, }, { - desc: "app_request message with compression", + desc: "app_request message with gzip compression", op: AppRequestOp, msg: &p2p.Message{ Message: &p2p.Message_AppRequest{ @@ -574,7 +697,24 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.TypeGzip, // TODO support zstd + compressionType: compression.TypeGzip, + bypassThrottling: true, + bytesSaved: true, + }, + { + desc: "app_request message with zstd compression", + op: AppRequestOp, + msg: &p2p.Message{ + Message: &p2p.Message_AppRequest{ + AppRequest: &p2p.AppRequest{ + ChainId: testID[:], + RequestId: 1, + Deadline: 1, + AppBytes: compressibleContainers[0], + }, + }, + }, + compressionType: compression.TypeZstd, bypassThrottling: true, bytesSaved: true, }, @@ -595,7 +735,7 @@ func TestMessage(t *testing.T) { bytesSaved: false, }, { - desc: "app_response message with compression", + desc: "app_response message with gzip compression", op: AppResponseOp, msg: &p2p.Message{ Message: &p2p.Message_AppResponse{ @@ -606,7 +746,23 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.TypeGzip, // TODO support zstd + compressionType: compression.TypeGzip, + bypassThrottling: true, + bytesSaved: true, + }, + { + desc: "app_response message with zstd compression", + op: AppResponseOp, + msg: &p2p.Message{ + Message: &p2p.Message_AppResponse{ + AppResponse: &p2p.AppResponse{ + ChainId: testID[:], + RequestId: 1, + AppBytes: compressibleContainers[0], + }, + }, + }, + compressionType: compression.TypeZstd, bypassThrottling: true, bytesSaved: true, }, @@ -626,7 +782,22 @@ func TestMessage(t *testing.T) { bytesSaved: false, }, { - desc: "app_gossip message with compression", + desc: "app_gossip message with gzip compression", + op: AppGossipOp, + msg: &p2p.Message{ + Message: &p2p.Message_AppGossip{ + AppGossip: &p2p.AppGossip{ + ChainId: testID[:], + AppBytes: compressibleContainers[0], + }, + }, + }, + compressionType: compression.TypeGzip, + bypassThrottling: true, + bytesSaved: true, + }, + { + desc: "app_gossip message with zstd compression", op: AppGossipOp, msg: &p2p.Message{ Message: &p2p.Message_AppGossip{ @@ -636,7 +807,7 @@ func TestMessage(t *testing.T) { }, }, }, - compressionType: compression.TypeGzip, // TODO support zstd + compressionType: compression.TypeZstd, bypassThrottling: true, bytesSaved: true, }, From 11c171de0a9b5addd2df8b520af3da3ed342b723 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 8 Mar 2023 10:50:45 -0500 Subject: [PATCH 19/54] consolidate metrics --- message/messages.go | 63 ++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/message/messages.go b/message/messages.go index 71429d18beb..87bf3327ae1 100644 --- a/message/messages.go +++ b/message/messages.go @@ -194,12 +194,17 @@ func newMsgBuilder( func (mb *msgBuilder) marshal( uncompressedMsg *p2p.Message, compressionType compression.Type, -) ([]byte, int, time.Duration, error) { +) ([]byte, int, Op, error) { uncompressedMsgBytes, err := proto.Marshal(uncompressedMsg) if err != nil { return nil, 0, 0, err } + op, err := ToOp(uncompressedMsg) + if err != nil { + return nil, 0, 0, err + } + // If compression is enabled, we marshal twice: // 1. the original message // 2. the message with compressed bytes @@ -212,7 +217,7 @@ func (mb *msgBuilder) marshal( ) switch compressionType { case compression.TypeNone: - return uncompressedMsgBytes, 0, 0, nil + return uncompressedMsgBytes, 0, op, nil case compression.TypeGzip: compressedBytes, err := mb.gzipCompressor.Compress(uncompressedMsgBytes) if err != nil { @@ -244,14 +249,21 @@ func (mb *msgBuilder) marshal( } compressTook := time.Since(startTime) + switch compressionType { + case compression.TypeGzip: + mb.gzipCompressTimeMetrics[op].Observe(float64(compressTook)) + case compression.TypeZstd: + mb.zstdCompressTimeMetrics[op].Observe(float64(compressTook)) + } + bytesSaved := len(uncompressedMsgBytes) - len(compressedMsgBytes) - return compressedMsgBytes, bytesSaved, compressTook, nil + return compressedMsgBytes, bytesSaved, op, nil } -func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, error) { +func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, Op, error) { m := new(p2p.Message) if err := proto.Unmarshal(b, m); err != nil { - return nil, 0, err + return nil, 0, 0, err } // Figure out what compression type, if any, was used to compress the message. @@ -264,10 +276,14 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, error) { ) switch { case len(gzipCompressed) == 0 && len(zstdCompressed) == 0: + op, err := ToOp(m) + if err != nil { + return nil, 0, 0, err + } // The message wasn't compressed - return m, 0, nil + return m, 0, op, nil case len(gzipCompressed) > 0 && len(zstdCompressed) > 0: - return nil, 0, errMultipleCompressionTypes + return nil, 0, 0, errMultipleCompressionTypes case len(gzipCompressed) > 0: compressionType = compression.TypeGzip compressor = mb.gzipCompressor @@ -282,19 +298,19 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, error) { decompressed, err := compressor.Decompress(compressedBytes) if err != nil { - return nil, 0, err + return nil, 0, 0, err } bytesSavedCompression := len(decompressed) - len(compressedBytes) if err := proto.Unmarshal(decompressed, m); err != nil { - return nil, 0, err + return nil, 0, 0, err } decompressTook := time.Since(startTime) // Record decompression time metric op, err := ToOp(m) if err != nil { - return nil, 0, err + return nil, 0, 0, err } switch compressionType { case compression.TypeGzip: @@ -303,27 +319,15 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, error) { mb.zstdDecompressTimeMetrics[op].Observe(float64(decompressTook)) } - return m, bytesSavedCompression, nil + return m, bytesSavedCompression, op, nil } func (mb *msgBuilder) createOutbound(m *p2p.Message, compressionType compression.Type, bypassThrottling bool) (*outboundMessage, error) { - b, saved, compressTook, err := mb.marshal(m, compressionType) + b, saved, op, err := mb.marshal(m, compressionType) if err != nil { return nil, err } - op, err := ToOp(m) - if err != nil { - return nil, err - } - - switch compressionType { - case compression.TypeGzip: - mb.gzipCompressTimeMetrics[op].Observe(float64(compressTook)) - case compression.TypeZstd: - mb.zstdCompressTimeMetrics[op].Observe(float64(compressTook)) - } - return &outboundMessage{ bypassThrottling: bypassThrottling, op: op, @@ -337,15 +341,16 @@ func (mb *msgBuilder) parseInbound( nodeID ids.NodeID, onFinishedHandling func(), ) (*inboundMessage, error) { - m, bytesSavedCompression, err := mb.unmarshal(bytes) + m, bytesSavedCompression, op, err := mb.unmarshal(bytes) if err != nil { return nil, err } - op, err := ToOp(m) - if err != nil { - return nil, err - } + // TODO remove + // op, err := ToOp(m) + // if err != nil { + // return nil, err + // } msg, err := Unwrap(m) if err != nil { From ddd35eec94cbb6d0d18c77184736abd594721743 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 8 Mar 2023 10:53:31 -0500 Subject: [PATCH 20/54] remove old todo --- message/messages.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/message/messages.go b/message/messages.go index 87bf3327ae1..020a397f8c4 100644 --- a/message/messages.go +++ b/message/messages.go @@ -346,12 +346,6 @@ func (mb *msgBuilder) parseInbound( return nil, err } - // TODO remove - // op, err := ToOp(m) - // if err != nil { - // return nil, err - // } - msg, err := Unwrap(m) if err != nil { return nil, err From 6dd3f2523f28c34f9c9aa8066f04f4ff119af914 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 8 Mar 2023 10:57:19 -0500 Subject: [PATCH 21/54] update test --- message/outbound_msg_builder_test.go | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/message/outbound_msg_builder_test.go b/message/outbound_msg_builder_test.go index 4625bde7c6d..4097f793bd1 100644 --- a/message/outbound_msg_builder_test.go +++ b/message/outbound_msg_builder_test.go @@ -26,15 +26,20 @@ func Test_newOutboundBuilder(t *testing.T) { ) require.NoError(err) - builder := newOutboundBuilder(compression.TypeGzip, mb) // TODO support zstd - - outMsg, err := builder.GetAcceptedStateSummary( - ids.GenerateTestID(), - 12345, - time.Hour, - []uint64{1000, 2000}, - ) - require.NoError(err) - - t.Logf("outbound message built with size %d", len(outMsg.Bytes())) + for _, compressionType := range []compression.Type{ + compression.TypeNone, + compression.TypeGzip, + compression.TypeZstd, + } { + builder := newOutboundBuilder(compressionType, mb) + + outMsg, err := builder.GetAcceptedStateSummary( + ids.GenerateTestID(), + 12345, + time.Hour, + []uint64{1000, 2000}, + ) + require.NoError(err) + t.Logf("outbound message with compression type %s built message with size %d", compressionType, len(outMsg.Bytes())) + } } From eab48790e75221c536a0737150db61510d414ae5 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 8 Mar 2023 10:58:39 -0500 Subject: [PATCH 22/54] update tests --- network/network_test.go | 3 +-- network/peer/peer_test.go | 3 +-- network/peer/test_peer.go | 3 +-- snow/networking/sender/sender_test.go | 5 +++-- vms/platformvm/vm_test.go | 3 +-- 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/network/network_test.go b/network/network_test.go index e1faf06bceb..8ec78d8c2a0 100644 --- a/network/network_test.go +++ b/network/network_test.go @@ -26,7 +26,6 @@ import ( "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/subnets" - "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/ips" "github.com/ava-labs/avalanchego/utils/logging" @@ -186,7 +185,7 @@ func newMessageCreator(t *testing.T) message.Creator { mc, err := message.NewCreator( prometheus.NewRegistry(), "", - compression.TypeGzip, // TODO support zstd + constants.DefaultNetworkCompressionType, 10*time.Second, ) require.NoError(t, err) diff --git a/network/peer/peer_test.go b/network/peer/peer_test.go index 673240d5020..6a341abddda 100644 --- a/network/peer/peer_test.go +++ b/network/peer/peer_test.go @@ -23,7 +23,6 @@ import ( "github.com/ava-labs/avalanchego/snow/networking/tracker" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" - "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/ips" "github.com/ava-labs/avalanchego/utils/logging" @@ -52,7 +51,7 @@ func newMessageCreator(t *testing.T) message.Creator { mc, err := message.NewCreator( prometheus.NewRegistry(), "", - compression.TypeGzip, // TODO support zstd + constants.DefaultNetworkCompressionType, 10*time.Second, ) require.NoError(t, err) diff --git a/network/peer/test_peer.go b/network/peer/test_peer.go index e86eeb5815c..8e6aff5a0b4 100644 --- a/network/peer/test_peer.go +++ b/network/peer/test_peer.go @@ -18,7 +18,6 @@ import ( "github.com/ava-labs/avalanchego/snow/networking/tracker" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" - "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/ips" "github.com/ava-labs/avalanchego/utils/logging" @@ -72,7 +71,7 @@ func StartTestPeer( mc, err := message.NewCreator( prometheus.NewRegistry(), "", - compression.TypeGzip, // TODO support zstd + constants.DefaultNetworkCompressionType, 10*time.Second, ) if err != nil { diff --git a/snow/networking/sender/sender_test.go b/snow/networking/sender/sender_test.go index d9e806bce73..74b0b2520c5 100644 --- a/snow/networking/sender/sender_test.go +++ b/snow/networking/sender/sender_test.go @@ -29,6 +29,7 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/subnets" "github.com/ava-labs/avalanchego/utils/compression" + "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/math/meter" "github.com/ava-labs/avalanchego/utils/resource" @@ -73,7 +74,7 @@ func TestTimeout(t *testing.T) { mc, err := message.NewCreator( metrics, "dummyNamespace", - compression.TypeGzip, // TODO support zstd + constants.DefaultNetworkCompressionType, 10*time.Second, ) require.NoError(err) @@ -333,7 +334,7 @@ func TestReliableMessages(t *testing.T) { mc, err := message.NewCreator( metrics, "dummyNamespace", - compression.TypeGzip, // TODO support zstd + constants.DefaultNetworkCompressionType, 10*time.Second, ) require.NoError(t, err) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index e2e89a12bd9..f5bcc549cb8 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -40,7 +40,6 @@ import ( "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/subnets" - "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" @@ -1722,7 +1721,7 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { chainRouter := &router.ChainRouter{} metrics := prometheus.NewRegistry() - mc, err := message.NewCreator(metrics, "dummyNamespace", compression.TypeGzip, 10*time.Second) + mc, err := message.NewCreator(metrics, "dummyNamespace", constants.DefaultNetworkCompressionType, 10*time.Second) require.NoError(err) err = chainRouter.Initialize( From 1ad19c11e3510dc4a6bd992ff75ed108a7bef00e Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 8 Mar 2023 12:51:03 -0500 Subject: [PATCH 23/54] add tests --- utils/compression/gzip_compressor_test.go | 104 ++++++++++++++-------- utils/compression/type.go | 14 +-- utils/compression/type_test.go | 57 ++++++++++++ 3 files changed, 126 insertions(+), 49 deletions(-) create mode 100644 utils/compression/type_test.go diff --git a/utils/compression/gzip_compressor_test.go b/utils/compression/gzip_compressor_test.go index 062074273cf..38557bd762b 100644 --- a/utils/compression/gzip_compressor_test.go +++ b/utils/compression/gzip_compressor_test.go @@ -13,41 +13,52 @@ import ( "github.com/ava-labs/avalanchego/utils/units" ) -func TestGzipCompressDecompress(t *testing.T) { - data := make([]byte, 4096) - for i := 0; i < len(data); i++ { - data[i] = byte(rand.Intn(256)) // #nosec G404 +func TestCompressDecompress(t *testing.T) { + for _, compressionType := range []Type{TypeNone, TypeGzip, TypeZstd} { + t.Run(compressionType.String(), func(t *testing.T) { + data := make([]byte, 4096) + for i := 0; i < len(data); i++ { + data[i] = byte(rand.Intn(256)) // #nosec G404 + } + + data2 := make([]byte, 4096) + for i := 0; i < len(data); i++ { + data2[i] = byte(rand.Intn(256)) // #nosec G404 + } + + var compressor Compressor + switch compressionType { + case TypeNone: + compressor = &noCompressor{} + case TypeGzip: + var err error + compressor, err = NewGzipCompressor(2 * units.MiB) // Max message size. Can't import due to cycle. + require.NoError(t, err) + case TypeZstd: + compressor = NewZstdCompressor() + default: + t.Fatal("Unknown compression type") + } + + dataCompressed, err := compressor.Compress(data) + require.NoError(t, err) + + data2Compressed, err := compressor.Compress(data2) + require.NoError(t, err) + + dataDecompressed, err := compressor.Decompress(dataCompressed) + require.NoError(t, err) + require.EqualValues(t, data, dataDecompressed) + + data2Decompressed, err := compressor.Decompress(data2Compressed) + require.NoError(t, err) + require.EqualValues(t, data2, data2Decompressed) + + dataDecompressed, err = compressor.Decompress(dataCompressed) + require.NoError(t, err) + require.EqualValues(t, data, dataDecompressed) + }) } - - data2 := make([]byte, 4096) - for i := 0; i < len(data); i++ { - data2[i] = byte(rand.Intn(256)) // #nosec G404 - } - - compressor, err := NewGzipCompressor(2 * units.MiB) - require.NoError(t, err) - - dataCompressed, err := compressor.Compress(data) - require.NoError(t, err) - - data2Compressed, err := compressor.Compress(data2) - require.NoError(t, err) - - dataDecompressed, err := compressor.Decompress(dataCompressed) - require.NoError(t, err) - require.EqualValues(t, data, dataDecompressed) - - data2Decompressed, err := compressor.Decompress(data2Compressed) - require.NoError(t, err) - require.EqualValues(t, data2, data2Decompressed) - - dataDecompressed, err = compressor.Decompress(dataCompressed) - require.NoError(t, err) - require.EqualValues(t, data, dataDecompressed) - - nonGzipData := []byte{1, 2, 3} - _, err = compressor.Decompress(nonGzipData) - require.Error(t, err) } func TestGzipSizeLimiting(t *testing.T) { @@ -78,16 +89,33 @@ func TestNewGzipCompressorWithInvalidLimit(t *testing.T) { } func FuzzGzipCompressor(f *testing.F) { + fuzzHelper(f, TypeGzip) +} + +func FuzzZstdCompressor(f *testing.F) { + fuzzHelper(f, TypeZstd) +} + +func fuzzHelper(f *testing.F, compressionType Type) { + var compressor Compressor + switch compressionType { + case TypeGzip: + var err error + compressor, err = NewGzipCompressor(2 * units.MiB) // Max message size. Can't import due to cycle. + require.NoError(f, err) + case TypeZstd: + compressor = NewZstdCompressor() + default: + f.Fatal("Unknown compression type") + } + f.Fuzz(func(t *testing.T, data []byte) { require := require.New(t) - if len(data) > 2*units.MiB { + if len(data) > 2*units.MiB && compressionType == TypeGzip { t.SkipNow() } - compressor, err := NewGzipCompressor(2 * units.MiB) - require.NoError(err) - compressed, err := compressor.Compress(data) require.NoError(err) diff --git a/utils/compression/type.go b/utils/compression/type.go index 1502b77acfc..c2a6f7a0459 100644 --- a/utils/compression/type.go +++ b/utils/compression/type.go @@ -46,21 +46,13 @@ func TypeFromString(s string) (Type, error) { func (t Type) MarshalJSON() ([]byte, error) { var b strings.Builder - _, err := b.WriteString("\"") - if err != nil { + if _, err := b.WriteString("\""); err != nil { return nil, err } - switch t { - case TypeNone, TypeGzip, TypeZstd: - _, err = b.WriteString(t.String()) - default: - err = errUnknownCompressionType - } - if err != nil { + if _, err := b.WriteString(t.String()); err != nil { return nil, err } - _, err = b.WriteString("\"") - if err != nil { + if _, err := b.WriteString("\""); err != nil { return nil, err } return []byte(b.String()), nil diff --git a/utils/compression/type_test.go b/utils/compression/type_test.go new file mode 100644 index 00000000000..aec47d6005a --- /dev/null +++ b/utils/compression/type_test.go @@ -0,0 +1,57 @@ +// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package compression + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestTypeString(t *testing.T) { + for _, compressionType := range []Type{TypeNone, TypeGzip, TypeZstd} { + s := compressionType.String() + parsedType, err := TypeFromString(s) + require.NoError(t, err) + require.Equal(t, compressionType, parsedType) + } + + _, err := TypeFromString("unknown") + require.Error(t, err) +} + +func TestTypeMarshalJSON(t *testing.T) { + type test struct { + Type Type + expected string + } + + tests := []test{ + { + Type: TypeNone, + expected: "\"none\"", + }, + { + Type: TypeGzip, + expected: "\"gzip\"", + }, + { + Type: TypeZstd, + expected: "\"zstd\"", + }, + { + Type: Type(0), + expected: "\"unknown\"", + }, + } + + for _, tt := range tests { + t.Run(tt.Type.String(), func(t *testing.T) { + b, err := tt.Type.MarshalJSON() + require.NoError(t, err) + require.Equal(t, tt.expected, string(b)) + }) + } + +} From 6b29cfc21ff545844100674251d96552c49562b6 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 8 Mar 2023 13:19:05 -0500 Subject: [PATCH 24/54] appease linter --- utils/compression/type_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/utils/compression/type_test.go b/utils/compression/type_test.go index aec47d6005a..c6aa07593eb 100644 --- a/utils/compression/type_test.go +++ b/utils/compression/type_test.go @@ -53,5 +53,4 @@ func TestTypeMarshalJSON(t *testing.T) { require.Equal(t, tt.expected, string(b)) }) } - } From 9526ba9ce521ac954b4d66dee4a3155761fe9a05 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 15 Mar 2023 14:18:43 -0400 Subject: [PATCH 25/54] nits --- message/messages_test.go | 1 - message/outbound_msg_builder_test.go | 25 +++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/message/messages_test.go b/message/messages_test.go index c49dd97e419..8176c1108ec 100644 --- a/message/messages_test.go +++ b/message/messages_test.go @@ -497,7 +497,6 @@ func TestMessage(t *testing.T) { ChainId: testID[:], RequestId: 12345, Containers: compressibleContainers, - EngineType: p2p.EngineType_ENGINE_TYPE_AVALANCHE, }, }, }, diff --git a/message/outbound_msg_builder_test.go b/message/outbound_msg_builder_test.go index 4097f793bd1..7a82c9e8a17 100644 --- a/message/outbound_msg_builder_test.go +++ b/message/outbound_msg_builder_test.go @@ -17,29 +17,30 @@ import ( func Test_newOutboundBuilder(t *testing.T) { t.Parallel() - require := require.New(t) mb, err := newMsgBuilder( "test", prometheus.NewRegistry(), 10*time.Second, ) - require.NoError(err) + require.NoError(t, err) for _, compressionType := range []compression.Type{ compression.TypeNone, compression.TypeGzip, compression.TypeZstd, } { - builder := newOutboundBuilder(compressionType, mb) - - outMsg, err := builder.GetAcceptedStateSummary( - ids.GenerateTestID(), - 12345, - time.Hour, - []uint64{1000, 2000}, - ) - require.NoError(err) - t.Logf("outbound message with compression type %s built message with size %d", compressionType, len(outMsg.Bytes())) + t.Run(compressionType.String(), func(t *testing.T) { + builder := newOutboundBuilder(compressionType, mb) + + outMsg, err := builder.GetAcceptedStateSummary( + ids.GenerateTestID(), + 12345, + time.Hour, + []uint64{1000, 2000}, + ) + require.NoError(t, err) + t.Logf("outbound message with compression type %s built message with size %d", compressionType, len(outMsg.Bytes())) + }) } } From 483f040f95ebc8993cdf05cda058221f8c31ed3c Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 21 Mar 2023 09:50:14 -0400 Subject: [PATCH 26/54] use default compression type in tests --- node/node.go | 3 +-- snow/networking/sender/sender_test.go | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/node/node.go b/node/node.go index 4835aa810e7..17284e50426 100644 --- a/node/node.go +++ b/node/node.go @@ -56,7 +56,6 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/trace" "github.com/ava-labs/avalanchego/utils" - "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/filesystem" @@ -1291,7 +1290,7 @@ func (n *Node) Initialize( n.msgCreator, err = message.NewCreator( n.MetricsRegisterer, n.networkNamespace, - compression.TypeGzip, + constants.DefaultNetworkCompressionType, n.Config.NetworkConfig.MaximumInboundMessageTimeout, ) if err != nil { diff --git a/snow/networking/sender/sender_test.go b/snow/networking/sender/sender_test.go index d55adb687c1..8fcc2bad1c3 100644 --- a/snow/networking/sender/sender_test.go +++ b/snow/networking/sender/sender_test.go @@ -28,7 +28,6 @@ import ( "github.com/ava-labs/avalanchego/snow/networking/tracker" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/subnets" - "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/math/meter" @@ -470,7 +469,7 @@ func TestReliableMessagesToMyself(t *testing.T) { mc, err := message.NewCreator( metrics, "dummyNamespace", - compression.TypeGzip, + constants.DefaultNetworkCompressionType, 10*time.Second, ) require.NoError(t, err) From 6b3f9a35197c11adfedea55c4409a2344c7e45ee Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 21 Mar 2023 10:04:16 -0400 Subject: [PATCH 27/54] flag nit --- config/flags.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/flags.go b/config/flags.go index eb2a9ddda9d..bc23a12d836 100644 --- a/config/flags.go +++ b/config/flags.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/genesis" "github.com/ava-labs/avalanchego/trace" + "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/ulimit" "github.com/ava-labs/avalanchego/utils/units" @@ -143,7 +144,7 @@ func addNodeFlags(fs *flag.FlagSet) { fs.Duration(NetworkPingFrequencyKey, constants.DefaultPingFrequency, "Frequency of pinging other peers") fs.Bool(NetworkCompressionEnabledKey, constants.DefaultNetworkCompressionEnabled, "If true, compress certain outbound messages. This node will be able to parse compressed inbound messages regardless of this flag's value") - fs.String(NetworkCompressionTypeKey, constants.DefaultNetworkCompressionType.String(), "Preferred compression type for outbound messages") + fs.String(NetworkCompressionTypeKey, constants.DefaultNetworkCompressionType.String(), fmt.Sprintf("Compression type for outbound messages. Must be one of [%s, %s, %s]", compression.TypeGzip, compression.TypeZstd, compression.TypeNone)) fs.Duration(NetworkMaxClockDifferenceKey, constants.DefaultNetworkMaxClockDifference, "Max allowed clock difference value between this node and peers") fs.Bool(NetworkAllowPrivateIPsKey, constants.DefaultNetworkAllowPrivateIPs, "Allows the node to initiate outbound connection attempts to peers with private IPs") From 5325c6b8741bbd2113a77d01699895ab02e59701 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 21 Mar 2023 15:42:51 -0400 Subject: [PATCH 28/54] only allow zstd after cortina --- config/config.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/config/config.go b/config/config.go index 8393ff0ef2c..3ba6072c928 100644 --- a/config/config.go +++ b/config/config.go @@ -300,7 +300,12 @@ func getGossipConfig(v *viper.Viper) subnets.GossipConfig { } } -func getNetworkConfig(v *viper.Viper, stakingEnabled bool, halflife time.Duration) (network.Config, error) { +func getNetworkConfig( + v *viper.Viper, + stakingEnabled bool, + halflife time.Duration, + networkID uint32, // TODO remove after cortina upgrade +) (network.Config, error) { // Set the max number of recent inbound connections upgraded to be // equal to the max number of inbound connections per second. maxInboundConnsPerSec := v.GetFloat64(InboundThrottlerMaxConnsPerSecKey) @@ -329,10 +334,12 @@ func getNetworkConfig(v *viper.Viper, stakingEnabled bool, halflife time.Duratio } } - version110 := &version.Semantic{Major: 1, Minor: 10, Patch: 0} - if compressionType == compression.TypeZstd && version.Current.Compare(version110) < 0 { - // TODO change this to check for v1.10 upgrade time instead of version. - // TODO remove after all nodes are on v1.10. + cortinaTime, ok := version.CortinaTimes[networkID] + if !ok { + cortinaTime = version.CortinaDefaultTime + } + if compressionType == compression.TypeZstd && !time.Now().After(cortinaTime) { + // TODO remove after cortina upgrade return network.Config{}, errZstdNotSupported } config := network.Config{ @@ -1371,7 +1378,7 @@ func GetNodeConfig(v *viper.Viper) (node.Config, error) { } // Network Config - nodeConfig.NetworkConfig, err = getNetworkConfig(v, nodeConfig.EnableStaking, healthCheckAveragerHalflife) + nodeConfig.NetworkConfig, err = getNetworkConfig(v, nodeConfig.EnableStaking, healthCheckAveragerHalflife, nodeConfig.NetworkID) if err != nil { return node.Config{}, err } From b401ea69c3c2cf54df6f8ffa1e177448a63950db Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Mon, 3 Apr 2023 09:28:26 -0400 Subject: [PATCH 29/54] address PR comments --- config/config.go | 5 +---- message/creator.go | 3 ++- utils/compression/type.go | 6 +++--- utils/compression/type_test.go | 10 +++++----- utils/compression/zstd_compressor.go | 2 +- 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/config/config.go b/config/config.go index d36c822da8d..70a1c782fce 100644 --- a/config/config.go +++ b/config/config.go @@ -341,10 +341,7 @@ func getNetworkConfig( } } - cortinaTime, ok := version.CortinaTimes[networkID] - if !ok { - cortinaTime = version.CortinaDefaultTime - } + cortinaTime := version.GetCortinaTime(networkID) if compressionType == compression.TypeZstd && !time.Now().After(cortinaTime) { // TODO remove after cortina upgrade return network.Config{}, errZstdNotSupported diff --git a/message/creator.go b/message/creator.go index 4ebd28c18a8..a822d43d758 100644 --- a/message/creator.go +++ b/message/creator.go @@ -7,8 +7,9 @@ import ( "fmt" "time" - "github.com/ava-labs/avalanchego/utils/compression" "github.com/prometheus/client_golang/prometheus" + + "github.com/ava-labs/avalanchego/utils/compression" ) var _ Creator = (*creator)(nil) diff --git a/utils/compression/type.go b/utils/compression/type.go index c2a6f7a0459..fd58a21f70f 100644 --- a/utils/compression/type.go +++ b/utils/compression/type.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package compression @@ -46,13 +46,13 @@ func TypeFromString(s string) (Type, error) { func (t Type) MarshalJSON() ([]byte, error) { var b strings.Builder - if _, err := b.WriteString("\""); err != nil { + if _, err := b.WriteString(`"`); err != nil { return nil, err } if _, err := b.WriteString(t.String()); err != nil { return nil, err } - if _, err := b.WriteString("\""); err != nil { + if _, err := b.WriteString(`"`); err != nil { return nil, err } return []byte(b.String()), nil diff --git a/utils/compression/type_test.go b/utils/compression/type_test.go index c6aa07593eb..aa9a47f3ad9 100644 --- a/utils/compression/type_test.go +++ b/utils/compression/type_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package compression @@ -30,19 +30,19 @@ func TestTypeMarshalJSON(t *testing.T) { tests := []test{ { Type: TypeNone, - expected: "\"none\"", + expected: `"none"`, }, { Type: TypeGzip, - expected: "\"gzip\"", + expected: `"gzip"`, }, { Type: TypeZstd, - expected: "\"zstd\"", + expected: `"zstd"`, }, { Type: Type(0), - expected: "\"unknown\"", + expected: `"unknown"`, }, } diff --git a/utils/compression/zstd_compressor.go b/utils/compression/zstd_compressor.go index 6865cdc5742..3a6e96dccc2 100644 --- a/utils/compression/zstd_compressor.go +++ b/utils/compression/zstd_compressor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package compression From b0225da91750c684f366f263c506f8294daa351a Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Mon, 3 Apr 2023 09:39:14 -0400 Subject: [PATCH 30/54] remove switch --- message/messages.go | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/message/messages.go b/message/messages.go index 3b5cec75724..f6c72489924 100644 --- a/message/messages.go +++ b/message/messages.go @@ -268,11 +268,11 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, Op, error) { // Figure out what compression type, if any, was used to compress the message. var ( - compressionType compression.Type - compressor compression.Compressor - compressedBytes []byte - gzipCompressed = m.GetCompressedGzip() - zstdCompressed = m.GetCompressedZstd() + opToDecompressTimeMetrics map[Op]metric.Averager + compressor compression.Compressor + compressedBytes []byte + gzipCompressed = m.GetCompressedGzip() + zstdCompressed = m.GetCompressedZstd() ) switch { case len(gzipCompressed) == 0 && len(zstdCompressed) == 0: @@ -285,11 +285,11 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, Op, error) { case len(gzipCompressed) > 0 && len(zstdCompressed) > 0: return nil, 0, 0, errMultipleCompressionTypes case len(gzipCompressed) > 0: - compressionType = compression.TypeGzip + opToDecompressTimeMetrics = mb.gzipDecompressTimeMetrics compressor = mb.gzipCompressor compressedBytes = gzipCompressed case len(zstdCompressed) > 0: - compressionType = compression.TypeZstd + opToDecompressTimeMetrics = mb.zstdDecompressTimeMetrics compressor = mb.zstdCompressor compressedBytes = zstdCompressed } @@ -312,11 +312,9 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, Op, error) { if err != nil { return nil, 0, 0, err } - switch compressionType { - case compression.TypeGzip: - mb.gzipDecompressTimeMetrics[op].Observe(float64(decompressTook)) - case compression.TypeZstd: - mb.zstdDecompressTimeMetrics[op].Observe(float64(decompressTook)) + if decompressTimeMetric, ok := opToDecompressTimeMetrics[op]; ok { + // This case should always execute, but check just in case. + decompressTimeMetric.Observe(float64(decompressTook)) } return m, bytesSavedCompression, op, nil From 8472760dec2d89f2e233e12b9911d1a1f5f02d11 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Mon, 3 Apr 2023 09:51:56 -0400 Subject: [PATCH 31/54] add max message size test --- .../{gzip_compressor_test.go => compressor_test.go} | 12 ++++++++++++ 1 file changed, 12 insertions(+) rename utils/compression/{gzip_compressor_test.go => compressor_test.go} (88%) diff --git a/utils/compression/gzip_compressor_test.go b/utils/compression/compressor_test.go similarity index 88% rename from utils/compression/gzip_compressor_test.go rename to utils/compression/compressor_test.go index c9219b030a0..f5cfdcab6ba 100644 --- a/utils/compression/gzip_compressor_test.go +++ b/utils/compression/compressor_test.go @@ -57,6 +57,18 @@ func TestCompressDecompress(t *testing.T) { dataDecompressed, err = compressor.Decompress(dataCompressed) require.NoError(t, err) require.EqualValues(t, data, dataDecompressed) + + maxMessage := make([]byte, 2*units.MiB) // Max message size. Can't import due to cycle. + _, err = rand.Read(maxMessage) // #nosec G404 + require.NoError(t, err) + + maxMessageCompressed, err := compressor.Compress(maxMessage) + require.NoError(t, err) + + maxMessageDecompressed, err := compressor.Decompress(maxMessageCompressed) + require.NoError(t, err) + + require.EqualValues(t, maxMessage, maxMessageDecompressed) }) } } From 0e6141140f9e367a2560c9c6a8ad884c9aee65db Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Mon, 3 Apr 2023 10:34:03 -0400 Subject: [PATCH 32/54] add max message size to zstd --- message/messages.go | 2 +- utils/compression/compressor_test.go | 21 ++++++++++++--------- utils/compression/gzip_compressor.go | 6 ++++-- utils/compression/zstd_compressor.go | 28 ++++++++++++++++++++++------ 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/message/messages.go b/message/messages.go index f6c72489924..72a6ea1c254 100644 --- a/message/messages.go +++ b/message/messages.go @@ -150,7 +150,7 @@ func newMsgBuilder( gzipCompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), gzipDecompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), - zstdCompressor: compression.NewZstdCompressor(), + zstdCompressor: compression.NewZstdCompressor(constants.DefaultMaxMessageSize), zstdCompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), zstdDecompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), diff --git a/utils/compression/compressor_test.go b/utils/compression/compressor_test.go index f5cfdcab6ba..8d01d7c8977 100644 --- a/utils/compression/compressor_test.go +++ b/utils/compression/compressor_test.go @@ -13,6 +13,8 @@ import ( "github.com/ava-labs/avalanchego/utils/units" ) +const maxMessageSize = 2 * units.MiB // Max message size. Can't import due to cycle. + func TestCompressDecompress(t *testing.T) { for _, compressionType := range []Type{TypeNone, TypeGzip, TypeZstd} { t.Run(compressionType.String(), func(t *testing.T) { @@ -32,10 +34,10 @@ func TestCompressDecompress(t *testing.T) { compressor = &noCompressor{} case TypeGzip: var err error - compressor, err = NewGzipCompressor(2 * units.MiB) // Max message size. Can't import due to cycle. + compressor, err = NewGzipCompressor(maxMessageSize) require.NoError(t, err) case TypeZstd: - compressor = NewZstdCompressor() + compressor = NewZstdCompressor(maxMessageSize) default: t.Fatal("Unknown compression type") } @@ -74,14 +76,14 @@ func TestCompressDecompress(t *testing.T) { } func TestGzipSizeLimiting(t *testing.T) { - data := make([]byte, 3*units.MiB) - compressor, err := NewGzipCompressor(2 * units.MiB) + compressor, err := NewGzipCompressor(maxMessageSize) require.NoError(t, err) + data := make([]byte, maxMessageSize+1) _, err = compressor.Compress(data) // should be too large require.Error(t, err) - compressor2, err := NewGzipCompressor(4 * units.MiB) + compressor2, err := NewGzipCompressor(2 * maxMessageSize) require.NoError(t, err) dataCompressed, err := compressor2.Compress(data) @@ -113,10 +115,10 @@ func fuzzHelper(f *testing.F, compressionType Type) { switch compressionType { case TypeGzip: var err error - compressor, err = NewGzipCompressor(2 * units.MiB) // Max message size. Can't import due to cycle. + compressor, err = NewGzipCompressor(maxMessageSize) require.NoError(f, err) case TypeZstd: - compressor = NewZstdCompressor() + compressor = NewZstdCompressor(maxMessageSize) default: f.Fatal("Unknown compression type") } @@ -124,8 +126,9 @@ func fuzzHelper(f *testing.F, compressionType Type) { f.Fuzz(func(t *testing.T, data []byte) { require := require.New(t) - if len(data) > 2*units.MiB && compressionType == TypeGzip { - t.SkipNow() + if len(data) > 2*units.MiB { + _, err := compressor.Compress(data) + require.Error(err) } compressed, err := compressor.Compress(data) diff --git a/utils/compression/gzip_compressor.go b/utils/compression/gzip_compressor.go index a603d036a08..3bec05f55e1 100644 --- a/utils/compression/gzip_compressor.go +++ b/utils/compression/gzip_compressor.go @@ -19,6 +19,8 @@ var ( _ Compressor = (*gzipCompressor)(nil) ErrInvalidMaxSizeGzipCompressor = errors.New("invalid gzip compressor max size") + ErrDecompressedMsgTooLarge = errors.New("decompressed msg too large") + ErrMsgTooLarge = errors.New("msg too large to be compressed") ) type gzipCompressor struct { @@ -36,7 +38,7 @@ type gzipCompressor struct { // Compress [msg] and returns the compressed bytes. func (g *gzipCompressor) Compress(msg []byte) ([]byte, error) { if int64(len(msg)) > g.maxSize { - return nil, fmt.Errorf("msg length (%d) > maximum msg length (%d)", len(msg), g.maxSize) + return nil, fmt.Errorf("%w: (%d) > (%d)", ErrMsgTooLarge, len(msg), g.maxSize) } g.lock.Lock() @@ -76,7 +78,7 @@ func (g *gzipCompressor) Decompress(msg []byte) ([]byte, error) { return nil, err } if int64(len(decompressed)) > g.maxSize { - return nil, fmt.Errorf("msg length > maximum msg length (%d)", g.maxSize) + return nil, fmt.Errorf("%w: (%d) > (%d)", ErrDecompressedMsgTooLarge, len(decompressed), g.maxSize) } return decompressed, g.gzipReader.Close() } diff --git a/utils/compression/zstd_compressor.go b/utils/compression/zstd_compressor.go index 3a6e96dccc2..c5e7955042f 100644 --- a/utils/compression/zstd_compressor.go +++ b/utils/compression/zstd_compressor.go @@ -4,21 +4,37 @@ package compression import ( + "fmt" + "github.com/DataDog/zstd" ) var _ Compressor = (*zstdCompressor)(nil) -func NewZstdCompressor() Compressor { - return &zstdCompressor{} +func NewZstdCompressor(maxSize int64) Compressor { + return &zstdCompressor{ + maxSize: maxSize, + } } -type zstdCompressor struct{} +type zstdCompressor struct { + maxSize int64 +} -func (*zstdCompressor) Compress(msg []byte) ([]byte, error) { +func (z *zstdCompressor) Compress(msg []byte) ([]byte, error) { + if int64(len(msg)) > z.maxSize { + return nil, fmt.Errorf("%w: (%d) > (%d)", ErrMsgTooLarge, len(msg), z.maxSize) + } return zstd.Compress(nil, msg) } -func (*zstdCompressor) Decompress(msg []byte) ([]byte, error) { - return zstd.Decompress(nil, msg) +func (z *zstdCompressor) Decompress(msg []byte) ([]byte, error) { + decompressed, err := zstd.Decompress(nil, msg) + if err != nil { + return nil, err + } + if int64(len(decompressed)) > z.maxSize { + return nil, fmt.Errorf("%w: (%d) > (%d)", ErrDecompressedMsgTooLarge, len(decompressed), z.maxSize) + } + return decompressed, nil } From 32d8d3727e97777d73066a98e9db056c9a0a90f5 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Mon, 3 Apr 2023 10:37:40 -0400 Subject: [PATCH 33/54] add test --- utils/compression/compressor_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/utils/compression/compressor_test.go b/utils/compression/compressor_test.go index 8d01d7c8977..807c5a845b8 100644 --- a/utils/compression/compressor_test.go +++ b/utils/compression/compressor_test.go @@ -93,6 +93,22 @@ func TestGzipSizeLimiting(t *testing.T) { require.Error(t, err) } +func TestZstdSizeLimiting(t *testing.T) { + compressor := NewZstdCompressor(maxMessageSize) + + data := make([]byte, maxMessageSize+1) + _, err := compressor.Compress(data) // should be too large + require.Error(t, err) + + compressor2 := NewZstdCompressor(2 * maxMessageSize) + + dataCompressed, err := compressor2.Compress(data) + require.NoError(t, err) + + _, err = compressor.Decompress(dataCompressed) // should be too large + require.Error(t, err) +} + // Attempts to create gzip compressor with math.MaxInt64 // which leads to undefined decompress behavior due to integer overflow // in limit reader creation. From db6504a43178c258f5255284fff34ed560c5556e Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 4 Apr 2023 12:38:11 -0400 Subject: [PATCH 34/54] remove switch --- message/messages.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/message/messages.go b/message/messages.go index 72a6ea1c254..0533ef09616 100644 --- a/message/messages.go +++ b/message/messages.go @@ -212,8 +212,9 @@ func (mb *msgBuilder) marshal( // This recursive packing allows us to avoid an extra compression on/off // field in the message. var ( - startTime = time.Now() - compressedMsg p2p.Message + startTime = time.Now() + compressedMsg p2p.Message + opToDecompressTimeMetrics map[Op]metric.Averager ) switch compressionType { case compression.TypeNone: @@ -228,7 +229,7 @@ func (mb *msgBuilder) marshal( CompressedGzip: compressedBytes, }, } - + opToDecompressTimeMetrics = mb.gzipDecompressTimeMetrics case compression.TypeZstd: compressedBytes, err := mb.zstdCompressor.Compress(uncompressedMsgBytes) if err != nil { @@ -239,6 +240,7 @@ func (mb *msgBuilder) marshal( CompressedZstd: compressedBytes, }, } + opToDecompressTimeMetrics = mb.zstdDecompressTimeMetrics default: return nil, 0, 0, errUnknownCompressionType } @@ -249,11 +251,9 @@ func (mb *msgBuilder) marshal( } compressTook := time.Since(startTime) - switch compressionType { - case compression.TypeGzip: - mb.gzipCompressTimeMetrics[op].Observe(float64(compressTook)) - case compression.TypeZstd: - mb.zstdCompressTimeMetrics[op].Observe(float64(compressTook)) + if decompressTimeMetric, ok := opToDecompressTimeMetrics[op]; ok { + // This case should always execute, but check just in case. + decompressTimeMetric.Observe(float64(compressTook)) } bytesSaved := len(uncompressedMsgBytes) - len(compressedMsgBytes) From 53df4c667e1a6e8c060c144bb541e2ff05d6980b Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 4 Apr 2023 15:03:27 -0400 Subject: [PATCH 35/54] use stream interface for Decompress to avoid unzip bomb --- utils/compression/zstd_compressor.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/utils/compression/zstd_compressor.go b/utils/compression/zstd_compressor.go index c5e7955042f..ce422d5e594 100644 --- a/utils/compression/zstd_compressor.go +++ b/utils/compression/zstd_compressor.go @@ -4,7 +4,9 @@ package compression import ( + "bytes" "fmt" + "io" "github.com/DataDog/zstd" ) @@ -19,6 +21,7 @@ func NewZstdCompressor(maxSize int64) Compressor { type zstdCompressor struct { maxSize int64 + reader bytes.Reader } func (z *zstdCompressor) Compress(msg []byte) ([]byte, error) { @@ -29,7 +32,15 @@ func (z *zstdCompressor) Compress(msg []byte) ([]byte, error) { } func (z *zstdCompressor) Decompress(msg []byte) ([]byte, error) { - decompressed, err := zstd.Decompress(nil, msg) + z.reader.Reset(msg) + reader := zstd.NewReader(&z.reader) + defer reader.Close() + + // We allow [io.LimitReader] to read up to [z.maxSize + 1] bytes, so that if + // the decompressed payload is greater than the maximum size, this function + // will return the appropriate error instead of an incomplete byte slice. + limitReader := io.LimitReader(reader, z.maxSize+1) + decompressed, err := io.ReadAll(limitReader) if err != nil { return nil, err } From adbc82ad8c67e0a33a4d0b2224ed4109193506af Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 4 Apr 2023 15:07:19 -0400 Subject: [PATCH 36/54] fix copy pasta bug --- message/messages.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/message/messages.go b/message/messages.go index 0533ef09616..7275e7a3a4e 100644 --- a/message/messages.go +++ b/message/messages.go @@ -212,9 +212,9 @@ func (mb *msgBuilder) marshal( // This recursive packing allows us to avoid an extra compression on/off // field in the message. var ( - startTime = time.Now() - compressedMsg p2p.Message - opToDecompressTimeMetrics map[Op]metric.Averager + startTime = time.Now() + compressedMsg p2p.Message + opToCompressTimeMetrics map[Op]metric.Averager ) switch compressionType { case compression.TypeNone: @@ -229,7 +229,7 @@ func (mb *msgBuilder) marshal( CompressedGzip: compressedBytes, }, } - opToDecompressTimeMetrics = mb.gzipDecompressTimeMetrics + opToCompressTimeMetrics = mb.gzipCompressTimeMetrics case compression.TypeZstd: compressedBytes, err := mb.zstdCompressor.Compress(uncompressedMsgBytes) if err != nil { @@ -240,7 +240,7 @@ func (mb *msgBuilder) marshal( CompressedZstd: compressedBytes, }, } - opToDecompressTimeMetrics = mb.zstdDecompressTimeMetrics + opToCompressTimeMetrics = mb.zstdCompressTimeMetrics default: return nil, 0, 0, errUnknownCompressionType } @@ -251,9 +251,9 @@ func (mb *msgBuilder) marshal( } compressTook := time.Since(startTime) - if decompressTimeMetric, ok := opToDecompressTimeMetrics[op]; ok { + if compressTimeMetric, ok := opToCompressTimeMetrics[op]; ok { // This case should always execute, but check just in case. - decompressTimeMetric.Observe(float64(compressTook)) + compressTimeMetric.Observe(float64(compressTook)) } bytesSaved := len(uncompressedMsgBytes) - len(compressedMsgBytes) From e510398d8fae3c6d3e6643fa35a3761a71bd6a7d Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 4 Apr 2023 15:10:10 -0400 Subject: [PATCH 37/54] move switch case to default --- message/messages.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/message/messages.go b/message/messages.go index 7275e7a3a4e..bc3fdb6e5d4 100644 --- a/message/messages.go +++ b/message/messages.go @@ -275,13 +275,6 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, Op, error) { zstdCompressed = m.GetCompressedZstd() ) switch { - case len(gzipCompressed) == 0 && len(zstdCompressed) == 0: - op, err := ToOp(m) - if err != nil { - return nil, 0, 0, err - } - // The message wasn't compressed - return m, 0, op, nil case len(gzipCompressed) > 0 && len(zstdCompressed) > 0: return nil, 0, 0, errMultipleCompressionTypes case len(gzipCompressed) > 0: @@ -292,6 +285,13 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, Op, error) { opToDecompressTimeMetrics = mb.zstdDecompressTimeMetrics compressor = mb.zstdCompressor compressedBytes = zstdCompressed + default: + // The message wasn't compressed + op, err := ToOp(m) + if err != nil { + return nil, 0, 0, err + } + return m, 0, op, nil } startTime := time.Now() From 82d7f688424da70b21b35501196d2e44e3e7a0ab Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 4 Apr 2023 15:11:49 -0400 Subject: [PATCH 38/54] remove impossible switch case --- message/messages.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/message/messages.go b/message/messages.go index bc3fdb6e5d4..d82783ebfb7 100644 --- a/message/messages.go +++ b/message/messages.go @@ -275,8 +275,6 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, Op, error) { zstdCompressed = m.GetCompressedZstd() ) switch { - case len(gzipCompressed) > 0 && len(zstdCompressed) > 0: - return nil, 0, 0, errMultipleCompressionTypes case len(gzipCompressed) > 0: opToDecompressTimeMetrics = mb.gzipDecompressTimeMetrics compressor = mb.gzipCompressor From bdcf189ae5be0f85340c771f71552f9c28e7b95d Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 4 Apr 2023 15:17:15 -0400 Subject: [PATCH 39/54] appease linter --- message/messages.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/message/messages.go b/message/messages.go index d82783ebfb7..580723296eb 100644 --- a/message/messages.go +++ b/message/messages.go @@ -26,8 +26,7 @@ var ( _ InboundMessage = (*inboundMessage)(nil) _ OutboundMessage = (*outboundMessage)(nil) - errMultipleCompressionTypes = errors.New("message is compressed with multiple compression types") - errUnknownCompressionType = errors.New("message is compressed with an unknown compression type") + errUnknownCompressionType = errors.New("message is compressed with an unknown compression type") ) // InboundMessage represents a set of fields for an inbound message From b91159d885b9a2213712237788b2a72fef93f2f1 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 4 Apr 2023 15:57:48 -0400 Subject: [PATCH 40/54] make reader a local var --- utils/compression/zstd_compressor.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/utils/compression/zstd_compressor.go b/utils/compression/zstd_compressor.go index ce422d5e594..cf2134ff7ed 100644 --- a/utils/compression/zstd_compressor.go +++ b/utils/compression/zstd_compressor.go @@ -21,7 +21,6 @@ func NewZstdCompressor(maxSize int64) Compressor { type zstdCompressor struct { maxSize int64 - reader bytes.Reader } func (z *zstdCompressor) Compress(msg []byte) ([]byte, error) { @@ -32,8 +31,7 @@ func (z *zstdCompressor) Compress(msg []byte) ([]byte, error) { } func (z *zstdCompressor) Decompress(msg []byte) ([]byte, error) { - z.reader.Reset(msg) - reader := zstd.NewReader(&z.reader) + reader := zstd.NewReader(bytes.NewReader(msg)) defer reader.Close() // We allow [io.LimitReader] to read up to [z.maxSize + 1] bytes, so that if From c259199a1728b498191bc60ca4afeab2226f2b3b Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 4 Apr 2023 15:58:36 -0400 Subject: [PATCH 41/54] return nit --- message/messages.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/message/messages.go b/message/messages.go index 580723296eb..d96b7fb63f4 100644 --- a/message/messages.go +++ b/message/messages.go @@ -285,10 +285,7 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, Op, error) { default: // The message wasn't compressed op, err := ToOp(m) - if err != nil { - return nil, 0, 0, err - } - return m, 0, op, nil + return m, 0, op, err } startTime := time.Now() From 9105741090d183a06b30f92bd4d815ff3aafb50f Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 4 Apr 2023 16:09:10 -0400 Subject: [PATCH 42/54] add invalid max size check to zstd compressor creation --- message/messages.go | 10 ++-- utils/compression/compressor_test.go | 81 +++++++++++++++------------- utils/compression/gzip_compressor.go | 8 +-- utils/compression/zstd_compressor.go | 13 ++++- 4 files changed, 67 insertions(+), 45 deletions(-) diff --git a/message/messages.go b/message/messages.go index d96b7fb63f4..8a56c19d232 100644 --- a/message/messages.go +++ b/message/messages.go @@ -139,17 +139,21 @@ func newMsgBuilder( metrics prometheus.Registerer, maxMessageTimeout time.Duration, ) (*msgBuilder, error) { - cpr, err := compression.NewGzipCompressor(constants.DefaultMaxMessageSize) + gzipCompressor, err := compression.NewGzipCompressor(constants.DefaultMaxMessageSize) + if err != nil { + return nil, err + } + zstdCompressor, err := compression.NewZstdCompressor(constants.DefaultMaxMessageSize) if err != nil { return nil, err } mb := &msgBuilder{ - gzipCompressor: cpr, + gzipCompressor: gzipCompressor, gzipCompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), gzipDecompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), - zstdCompressor: compression.NewZstdCompressor(constants.DefaultMaxMessageSize), + zstdCompressor: zstdCompressor, zstdCompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), zstdDecompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), diff --git a/utils/compression/compressor_test.go b/utils/compression/compressor_test.go index 807c5a845b8..31459eaa215 100644 --- a/utils/compression/compressor_test.go +++ b/utils/compression/compressor_test.go @@ -28,7 +28,10 @@ func TestCompressDecompress(t *testing.T) { data2[i] = byte(rand.Intn(256)) // #nosec G404 } - var compressor Compressor + var ( + compressor Compressor + err error + ) switch compressionType { case TypeNone: compressor = &noCompressor{} @@ -37,9 +40,10 @@ func TestCompressDecompress(t *testing.T) { compressor, err = NewGzipCompressor(maxMessageSize) require.NoError(t, err) case TypeZstd: - compressor = NewZstdCompressor(maxMessageSize) + compressor, err = NewZstdCompressor(maxMessageSize) + require.NoError(t, err) default: - t.Fatal("Unknown compression type") + require.FailNow(t, "Unknown compression type") } dataCompressed, err := compressor.Compress(data) @@ -76,46 +80,48 @@ func TestCompressDecompress(t *testing.T) { } func TestGzipSizeLimiting(t *testing.T) { - compressor, err := NewGzipCompressor(maxMessageSize) - require.NoError(t, err) - - data := make([]byte, maxMessageSize+1) - _, err = compressor.Compress(data) // should be too large - require.Error(t, err) - - compressor2, err := NewGzipCompressor(2 * maxMessageSize) - require.NoError(t, err) - - dataCompressed, err := compressor2.Compress(data) - require.NoError(t, err) - - _, err = compressor.Decompress(dataCompressed) // should be too large - require.Error(t, err) -} + compressorFuncs := map[string]func(int64) (Compressor, error){ + "gzip": NewGzipCompressor, + "zstd": NewZstdCompressor, + } -func TestZstdSizeLimiting(t *testing.T) { - compressor := NewZstdCompressor(maxMessageSize) + for name, compressorFunc := range compressorFuncs { + t.Run(name, func(t *testing.T) { + compressor, err := compressorFunc(maxMessageSize) + require.NoError(t, err) - data := make([]byte, maxMessageSize+1) - _, err := compressor.Compress(data) // should be too large - require.Error(t, err) + data := make([]byte, maxMessageSize+1) + _, err = compressor.Compress(data) // should be too large + require.Error(t, err) - compressor2 := NewZstdCompressor(2 * maxMessageSize) + compressor2, err := compressorFunc(2 * maxMessageSize) + require.NoError(t, err) - dataCompressed, err := compressor2.Compress(data) - require.NoError(t, err) + dataCompressed, err := compressor2.Compress(data) + require.NoError(t, err) - _, err = compressor.Decompress(dataCompressed) // should be too large - require.Error(t, err) + _, err = compressor.Decompress(dataCompressed) // should be too large + require.Error(t, err) + }) + } } // Attempts to create gzip compressor with math.MaxInt64 // which leads to undefined decompress behavior due to integer overflow // in limit reader creation. -func TestNewGzipCompressorWithInvalidLimit(t *testing.T) { - require := require.New(t) - _, err := NewGzipCompressor(math.MaxInt64) - require.ErrorIs(err, ErrInvalidMaxSizeGzipCompressor) +func TestNewCompressorWithInvalidLimit(t *testing.T) { + compressorFuncs := map[string]func(int64) (Compressor, error){ + "gzip": NewGzipCompressor, + "zstd": NewZstdCompressor, + } + + for name, compressorFunc := range compressorFuncs { + t.Run(name, func(t *testing.T) { + require := require.New(t) + _, err := compressorFunc(math.MaxInt64) + require.ErrorIs(err, ErrInvalidMaxSizeCompressor) + }) + } } func FuzzGzipCompressor(f *testing.F) { @@ -127,14 +133,17 @@ func FuzzZstdCompressor(f *testing.F) { } func fuzzHelper(f *testing.F, compressionType Type) { - var compressor Compressor + var ( + compressor Compressor + err error + ) switch compressionType { case TypeGzip: - var err error compressor, err = NewGzipCompressor(maxMessageSize) require.NoError(f, err) case TypeZstd: - compressor = NewZstdCompressor(maxMessageSize) + compressor, err = NewZstdCompressor(maxMessageSize) + require.NoError(f, err) default: f.Fatal("Unknown compression type") } diff --git a/utils/compression/gzip_compressor.go b/utils/compression/gzip_compressor.go index 3bec05f55e1..036cd8d4576 100644 --- a/utils/compression/gzip_compressor.go +++ b/utils/compression/gzip_compressor.go @@ -18,9 +18,9 @@ import ( var ( _ Compressor = (*gzipCompressor)(nil) - ErrInvalidMaxSizeGzipCompressor = errors.New("invalid gzip compressor max size") - ErrDecompressedMsgTooLarge = errors.New("decompressed msg too large") - ErrMsgTooLarge = errors.New("msg too large to be compressed") + ErrInvalidMaxSizeCompressor = errors.New("invalid gzip compressor max size") + ErrDecompressedMsgTooLarge = errors.New("decompressed msg too large") + ErrMsgTooLarge = errors.New("msg too large to be compressed") ) type gzipCompressor struct { @@ -90,7 +90,7 @@ func NewGzipCompressor(maxSize int64) (Compressor, error) { // if the max size + 1 overflows, "io.LimitReader" reads nothing // returning 0 byte for the decompress call // require max size Date: Tue, 4 Apr 2023 18:19:23 -0400 Subject: [PATCH 43/54] Parallelize gzip compression --- utils/compression/gzip_compressor.go | 46 +++++----------------- utils/compression/gzip_compressor_test.go | 47 +++++++++++++++++++++++ 2 files changed, 57 insertions(+), 36 deletions(-) diff --git a/utils/compression/gzip_compressor.go b/utils/compression/gzip_compressor.go index a603d036a08..61d2811e405 100644 --- a/utils/compression/gzip_compressor.go +++ b/utils/compression/gzip_compressor.go @@ -10,9 +10,6 @@ import ( "fmt" "io" "math" - "sync" - - "golang.org/x/exp/slices" ) var ( @@ -23,14 +20,6 @@ var ( type gzipCompressor struct { maxSize int64 - - lock sync.Mutex - - writeBuffer *bytes.Buffer - gzipWriter *gzip.Writer - - bytesReader *bytes.Reader - gzipReader *gzip.Reader } // Compress [msg] and returns the compressed bytes. @@ -39,37 +28,29 @@ func (g *gzipCompressor) Compress(msg []byte) ([]byte, error) { return nil, fmt.Errorf("msg length (%d) > maximum msg length (%d)", len(msg), g.maxSize) } - g.lock.Lock() - defer g.lock.Unlock() - - g.writeBuffer.Reset() - g.gzipWriter.Reset(g.writeBuffer) - if _, err := g.gzipWriter.Write(msg); err != nil { + var writeBuffer bytes.Buffer + gzipWriter := gzip.NewWriter(&writeBuffer) + if _, err := gzipWriter.Write(msg); err != nil { return nil, err } - if err := g.gzipWriter.Close(); err != nil { + if err := gzipWriter.Close(); err != nil { return nil, err } - - compressed := g.writeBuffer.Bytes() - compressedCopy := slices.Clone(compressed) - return compressedCopy, nil + return writeBuffer.Bytes(), nil } // Decompress decompresses [msg]. func (g *gzipCompressor) Decompress(msg []byte) ([]byte, error) { - g.lock.Lock() - defer g.lock.Unlock() - - g.bytesReader.Reset(msg) - if err := g.gzipReader.Reset(g.bytesReader); err != nil { + bytesReader := bytes.NewReader(msg) + gzipReader, err := gzip.NewReader(bytesReader) + if err != nil { return nil, err } // We allow [io.LimitReader] to read up to [g.maxSize + 1] bytes, so that if // the decompressed payload is greater than the maximum size, this function // will return the appropriate error instead of an incomplete byte slice. - limitedReader := io.LimitReader(g.gzipReader, g.maxSize+1) + limitedReader := io.LimitReader(gzipReader, g.maxSize+1) decompressed, err := io.ReadAll(limitedReader) if err != nil { @@ -78,7 +59,7 @@ func (g *gzipCompressor) Decompress(msg []byte) ([]byte, error) { if int64(len(decompressed)) > g.maxSize { return nil, fmt.Errorf("msg length > maximum msg length (%d)", g.maxSize) } - return decompressed, g.gzipReader.Close() + return decompressed, gzipReader.Close() } // NewGzipCompressor returns a new gzip Compressor that compresses @@ -91,14 +72,7 @@ func NewGzipCompressor(maxSize int64) (Compressor, error) { return nil, ErrInvalidMaxSizeGzipCompressor } - var buf bytes.Buffer return &gzipCompressor{ maxSize: maxSize, - - writeBuffer: &buf, - gzipWriter: gzip.NewWriter(&buf), - - bytesReader: &bytes.Reader{}, - gzipReader: &gzip.Reader{}, }, nil } diff --git a/utils/compression/gzip_compressor_test.go b/utils/compression/gzip_compressor_test.go index 143784b9766..a8d211f143b 100644 --- a/utils/compression/gzip_compressor_test.go +++ b/utils/compression/gzip_compressor_test.go @@ -4,12 +4,14 @@ package compression import ( + "fmt" "math" "math/rand" "testing" "github.com/stretchr/testify/require" + "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/units" ) @@ -97,3 +99,48 @@ func FuzzGzipCompressor(f *testing.F) { require.Equal(data, decompressed) }) } + +func BenchmarkGzipCompress(b *testing.B) { + sizes := []int{ + 0, + 256, + units.KiB, + units.MiB, + } + for _, size := range sizes { + bytes := utils.RandomBytes(size) + compressor, err := NewGzipCompressor(2 * units.MiB) + require.NoError(b, err) + + b.Run(fmt.Sprintf("%d", size), func(b *testing.B) { + for n := 0; n < b.N; n++ { + _, err := compressor.Compress(bytes) + require.NoError(b, err) + } + }) + } +} + +func BenchmarkGzipDecompress(b *testing.B) { + sizes := []int{ + 0, + 256, + units.KiB, + units.MiB, + } + for _, size := range sizes { + bytes := utils.RandomBytes(size) + compressor, err := NewGzipCompressor(2 * units.MiB) + require.NoError(b, err) + + compressedBytes, err := compressor.Compress(bytes) + require.NoError(b, err) + + b.Run(fmt.Sprintf("%d", size), func(b *testing.B) { + for n := 0; n < b.N; n++ { + _, err := compressor.Decompress(compressedBytes) + require.NoError(b, err) + } + }) + } +} From c6f4800062bc32d095fd0de1d1ee33ca36c4d256 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 5 Apr 2023 09:47:23 -0400 Subject: [PATCH 44/54] log warning for unknown op during metrics observation --- message/creator.go | 3 +++ message/inbound_msg_builder_test.go | 2 ++ message/messages.go | 18 ++++++++++++++++-- message/messages_benchmark_test.go | 5 +++-- message/messages_test.go | 4 ++++ message/outbound_msg_builder_test.go | 2 ++ network/network_test.go | 1 + network/peer/peer_test.go | 1 + network/peer/test_peer.go | 1 + network/test_network.go | 1 + node/node.go | 1 + snow/networking/sender/sender_test.go | 3 +++ vms/platformvm/vm_test.go | 2 +- 13 files changed, 39 insertions(+), 5 deletions(-) diff --git a/message/creator.go b/message/creator.go index a822d43d758..f1a6def2b21 100644 --- a/message/creator.go +++ b/message/creator.go @@ -10,6 +10,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/ava-labs/avalanchego/utils/compression" + "github.com/ava-labs/avalanchego/utils/logging" ) var _ Creator = (*creator)(nil) @@ -25,6 +26,7 @@ type creator struct { } func NewCreator( + log logging.Logger, metrics prometheus.Registerer, parentNamespace string, compressionType compression.Type, @@ -32,6 +34,7 @@ func NewCreator( ) (Creator, error) { namespace := fmt.Sprintf("%s_codec", parentNamespace) builder, err := newMsgBuilder( + log, namespace, metrics, maxMessageTimeout, diff --git a/message/inbound_msg_builder_test.go b/message/inbound_msg_builder_test.go index 9eb604b408a..667a205d1df 100644 --- a/message/inbound_msg_builder_test.go +++ b/message/inbound_msg_builder_test.go @@ -13,6 +13,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/proto/pb/p2p" + "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/timer/mockable" ) @@ -21,6 +22,7 @@ func Test_newMsgBuilder(t *testing.T) { require := require.New(t) mb, err := newMsgBuilder( + logging.NoLog{}, "test", prometheus.NewRegistry(), 10*time.Second, diff --git a/message/messages.go b/message/messages.go index 8a56c19d232..bdaec43bbc6 100644 --- a/message/messages.go +++ b/message/messages.go @@ -9,6 +9,7 @@ import ( "time" "github.com/prometheus/client_golang/prometheus" + "go.uber.org/zap" "google.golang.org/protobuf/proto" @@ -16,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/proto/pb/p2p" "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/utils/metric" "github.com/ava-labs/avalanchego/utils/timer/mockable" @@ -123,6 +125,8 @@ func (m *outboundMessage) BytesSavedCompression() int { // TODO: add other compression algorithms with extended interface type msgBuilder struct { + log logging.Logger + gzipCompressor compression.Compressor gzipCompressTimeMetrics map[Op]metric.Averager gzipDecompressTimeMetrics map[Op]metric.Averager @@ -135,6 +139,7 @@ type msgBuilder struct { } func newMsgBuilder( + log logging.Logger, namespace string, metrics prometheus.Registerer, maxMessageTimeout time.Duration, @@ -149,6 +154,8 @@ func newMsgBuilder( } mb := &msgBuilder{ + log: log, + gzipCompressor: gzipCompressor, gzipCompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), gzipDecompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), @@ -255,8 +262,13 @@ func (mb *msgBuilder) marshal( compressTook := time.Since(startTime) if compressTimeMetric, ok := opToCompressTimeMetrics[op]; ok { - // This case should always execute, but check just in case. compressTimeMetric.Observe(float64(compressTook)) + } else { + // Should never happen + mb.log.Warn("no compression metric found for op", + zap.Stringer("op", op), + zap.Stringer("compressionType", compressionType), + ) } bytesSaved := len(uncompressedMsgBytes) - len(compressedMsgBytes) @@ -311,8 +323,10 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, Op, error) { return nil, 0, 0, err } if decompressTimeMetric, ok := opToDecompressTimeMetrics[op]; ok { - // This case should always execute, but check just in case. decompressTimeMetric.Observe(float64(decompressTook)) + } else { + // Should never happen + mb.log.Warn("no decompression metric found for op", zap.Stringer("op", op)) } return m, bytesSavedCompression, op, nil diff --git a/message/messages_benchmark_test.go b/message/messages_benchmark_test.go index 100bbe1e406..f87493fc024 100644 --- a/message/messages_benchmark_test.go +++ b/message/messages_benchmark_test.go @@ -18,6 +18,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/proto/pb/p2p" "github.com/ava-labs/avalanchego/utils/compression" + "github.com/ava-labs/avalanchego/utils/logging" ) var ( @@ -63,7 +64,7 @@ func BenchmarkMarshalVersion(b *testing.B) { useBuilder := os.Getenv("USE_BUILDER") != "" - codec, err := newMsgBuilder("", prometheus.NewRegistry(), 10*time.Second) + codec, err := newMsgBuilder(logging.NoLog{}, "", prometheus.NewRegistry(), 10*time.Second) require.NoError(err) b.Logf("proto length %d-byte (use builder %v)", msgLen, useBuilder) @@ -120,7 +121,7 @@ func BenchmarkUnmarshalVersion(b *testing.B) { require.NoError(err) useBuilder := os.Getenv("USE_BUILDER") != "" - codec, err := newMsgBuilder("", prometheus.NewRegistry(), 10*time.Second) + codec, err := newMsgBuilder(logging.NoLog{}, "", prometheus.NewRegistry(), 10*time.Second) require.NoError(err) b.StartTimer() diff --git a/message/messages_test.go b/message/messages_test.go index 6c92672923d..c04e3ea44dd 100644 --- a/message/messages_test.go +++ b/message/messages_test.go @@ -19,6 +19,7 @@ import ( "github.com/ava-labs/avalanchego/proto/pb/p2p" "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils/compression" + "github.com/ava-labs/avalanchego/utils/logging" ) func TestMessage(t *testing.T) { @@ -27,6 +28,7 @@ func TestMessage(t *testing.T) { require := require.New(t) mb, err := newMsgBuilder( + logging.NoLog{}, "test", prometheus.NewRegistry(), 5*time.Second, @@ -831,6 +833,7 @@ func TestEmptyInboundMessage(t *testing.T) { require := require.New(t) mb, err := newMsgBuilder( + logging.NoLog{}, "test", prometheus.NewRegistry(), 5*time.Second, @@ -851,6 +854,7 @@ func TestNilInboundMessage(t *testing.T) { require := require.New(t) mb, err := newMsgBuilder( + logging.NoLog{}, "test", prometheus.NewRegistry(), 5*time.Second, diff --git a/message/outbound_msg_builder_test.go b/message/outbound_msg_builder_test.go index fcc39f7c4ac..50f273bf4b1 100644 --- a/message/outbound_msg_builder_test.go +++ b/message/outbound_msg_builder_test.go @@ -13,12 +13,14 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/compression" + "github.com/ava-labs/avalanchego/utils/logging" ) func Test_newOutboundBuilder(t *testing.T) { t.Parallel() mb, err := newMsgBuilder( + logging.NoLog{}, "test", prometheus.NewRegistry(), 10*time.Second, diff --git a/network/network_test.go b/network/network_test.go index 1881b283686..63efee693d3 100644 --- a/network/network_test.go +++ b/network/network_test.go @@ -183,6 +183,7 @@ func newMessageCreator(t *testing.T) message.Creator { t.Helper() mc, err := message.NewCreator( + logging.NoLog{}, prometheus.NewRegistry(), "", constants.DefaultNetworkCompressionType, diff --git a/network/peer/peer_test.go b/network/peer/peer_test.go index 1b942cc8d37..653a0c616e2 100644 --- a/network/peer/peer_test.go +++ b/network/peer/peer_test.go @@ -49,6 +49,7 @@ func newMessageCreator(t *testing.T) message.Creator { t.Helper() mc, err := message.NewCreator( + logging.NoLog{}, prometheus.NewRegistry(), "", constants.DefaultNetworkCompressionType, diff --git a/network/peer/test_peer.go b/network/peer/test_peer.go index ef2feeeceb3..d813a16a563 100644 --- a/network/peer/test_peer.go +++ b/network/peer/test_peer.go @@ -70,6 +70,7 @@ func StartTestPeer( } mc, err := message.NewCreator( + logging.NoLog{}, prometheus.NewRegistry(), "", constants.DefaultNetworkCompressionType, diff --git a/network/test_network.go b/network/test_network.go index 487f628c1cf..296108b714d 100644 --- a/network/test_network.go +++ b/network/test_network.go @@ -79,6 +79,7 @@ func NewTestNetwork( ) (Network, error) { metrics := prometheus.NewRegistry() msgCreator, err := message.NewCreator( + logging.NoLog{}, metrics, "", constants.DefaultNetworkCompressionType, diff --git a/node/node.go b/node/node.go index 60d0fcead11..08868d28c6c 100644 --- a/node/node.go +++ b/node/node.go @@ -1303,6 +1303,7 @@ func (n *Node) Initialize( // message.Creator currently record metrics under network namespace n.networkNamespace = "network" n.msgCreator, err = message.NewCreator( + n.Log, n.MetricsRegisterer, n.networkNamespace, constants.DefaultNetworkCompressionType, diff --git a/snow/networking/sender/sender_test.go b/snow/networking/sender/sender_test.go index 3cbe692c3dc..db20b12b3c4 100644 --- a/snow/networking/sender/sender_test.go +++ b/snow/networking/sender/sender_test.go @@ -71,6 +71,7 @@ func TestTimeout(t *testing.T) { metrics := prometheus.NewRegistry() mc, err := message.NewCreator( + logging.NoLog{}, metrics, "dummyNamespace", constants.DefaultNetworkCompressionType, @@ -342,6 +343,7 @@ func TestReliableMessages(t *testing.T) { metrics := prometheus.NewRegistry() mc, err := message.NewCreator( + logging.NoLog{}, metrics, "dummyNamespace", constants.DefaultNetworkCompressionType, @@ -489,6 +491,7 @@ func TestReliableMessagesToMyself(t *testing.T) { metrics := prometheus.NewRegistry() mc, err := message.NewCreator( + logging.NoLog{}, metrics, "dummyNamespace", constants.DefaultNetworkCompressionType, diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index f02d2ad30a1..f7b679d9a63 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -1721,7 +1721,7 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { chainRouter := &router.ChainRouter{} metrics := prometheus.NewRegistry() - mc, err := message.NewCreator(metrics, "dummyNamespace", constants.DefaultNetworkCompressionType, 10*time.Second) + mc, err := message.NewCreator(logging.NoLog{}, metrics, "dummyNamespace", constants.DefaultNetworkCompressionType, 10*time.Second) require.NoError(err) err = chainRouter.Initialize( From 8ad1cb6c0fee79d0dd52ef634c8967ef218700eb Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 5 Apr 2023 11:28:44 -0400 Subject: [PATCH 45/54] use sync.Pool of gzip writer --- utils/compression/gzip_compressor.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/utils/compression/gzip_compressor.go b/utils/compression/gzip_compressor.go index fa79c26a707..b3f0b2febe6 100644 --- a/utils/compression/gzip_compressor.go +++ b/utils/compression/gzip_compressor.go @@ -10,6 +10,7 @@ import ( "fmt" "io" "math" + "sync" ) var ( @@ -21,7 +22,8 @@ var ( ) type gzipCompressor struct { - maxSize int64 + maxSize int64 + gzipWriterPool sync.Pool } // Compress [msg] and returns the compressed bytes. @@ -31,11 +33,14 @@ func (g *gzipCompressor) Compress(msg []byte) ([]byte, error) { } var writeBuffer bytes.Buffer - gzipWriter := gzip.NewWriter(&writeBuffer) + gzipWriter := g.gzipWriterPool.Get().(*gzip.Writer) + gzipWriter.Reset(&writeBuffer) + defer g.gzipWriterPool.Put(gzipWriter) + if _, err := gzipWriter.Write(msg); err != nil { return nil, err } - if err := gzipWriter.Close(); err != nil { + if err := gzipWriter.Flush(); err != nil { return nil, err } return writeBuffer.Bytes(), nil @@ -76,5 +81,10 @@ func NewGzipCompressor(maxSize int64) (Compressor, error) { return &gzipCompressor{ maxSize: maxSize, + gzipWriterPool: sync.Pool{ + New: func() interface{} { + return gzip.NewWriter(nil) + }, + }, }, nil } From 8c499afd2abd59179cee068a7400f50704550c97 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 5 Apr 2023 11:42:08 -0400 Subject: [PATCH 46/54] gzipWriter.Flush() --> gzipWriter.Close() --- utils/compression/gzip_compressor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/compression/gzip_compressor.go b/utils/compression/gzip_compressor.go index b3f0b2febe6..a17c46f6d6a 100644 --- a/utils/compression/gzip_compressor.go +++ b/utils/compression/gzip_compressor.go @@ -40,7 +40,7 @@ func (g *gzipCompressor) Compress(msg []byte) ([]byte, error) { if _, err := gzipWriter.Write(msg); err != nil { return nil, err } - if err := gzipWriter.Flush(); err != nil { + if err := gzipWriter.Close(); err != nil { return nil, err } return writeBuffer.Bytes(), nil From 812a37dfb3ca09a737c3f5b2fabf6cb9f9f87e97 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 5 Apr 2023 13:50:12 -0400 Subject: [PATCH 47/54] test cleanup --- utils/compression/compressor_test.go | 61 ++++++++++++---------------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/utils/compression/compressor_test.go b/utils/compression/compressor_test.go index 31459eaa215..b972cf4badc 100644 --- a/utils/compression/compressor_test.go +++ b/utils/compression/compressor_test.go @@ -15,8 +15,20 @@ import ( const maxMessageSize = 2 * units.MiB // Max message size. Can't import due to cycle. +var newCompressorFuncs = map[Type]func(maxSize int64) (Compressor, error){ + TypeNone: func(int64) (Compressor, error) { + return NewNoCompressor(), nil + }, + TypeGzip: func(maxSize int64) (Compressor, error) { + return NewGzipCompressor(maxSize) + }, + TypeZstd: func(maxSize int64) (Compressor, error) { + return NewZstdCompressor(maxSize) + }, +} + func TestCompressDecompress(t *testing.T) { - for _, compressionType := range []Type{TypeNone, TypeGzip, TypeZstd} { + for compressionType, newCompressorFunc := range newCompressorFuncs { t.Run(compressionType.String(), func(t *testing.T) { data := make([]byte, 4096) for i := 0; i < len(data); i++ { @@ -28,23 +40,8 @@ func TestCompressDecompress(t *testing.T) { data2[i] = byte(rand.Intn(256)) // #nosec G404 } - var ( - compressor Compressor - err error - ) - switch compressionType { - case TypeNone: - compressor = &noCompressor{} - case TypeGzip: - var err error - compressor, err = NewGzipCompressor(maxMessageSize) - require.NoError(t, err) - case TypeZstd: - compressor, err = NewZstdCompressor(maxMessageSize) - require.NoError(t, err) - default: - require.FailNow(t, "Unknown compression type") - } + compressor, err := newCompressorFunc(maxMessageSize) + require.NoError(t, err) dataCompressed, err := compressor.Compress(data) require.NoError(t, err) @@ -79,14 +76,12 @@ func TestCompressDecompress(t *testing.T) { } } -func TestGzipSizeLimiting(t *testing.T) { - compressorFuncs := map[string]func(int64) (Compressor, error){ - "gzip": NewGzipCompressor, - "zstd": NewZstdCompressor, - } - - for name, compressorFunc := range compressorFuncs { - t.Run(name, func(t *testing.T) { +func TestSizeLimiting(t *testing.T) { + for compressionType, compressorFunc := range newCompressorFuncs { + if compressionType == TypeNone { + continue + } + t.Run(compressionType.String(), func(t *testing.T) { compressor, err := compressorFunc(maxMessageSize) require.NoError(t, err) @@ -106,17 +101,15 @@ func TestGzipSizeLimiting(t *testing.T) { } } -// Attempts to create gzip compressor with math.MaxInt64 +// Attempts to create a compressor with math.MaxInt64 // which leads to undefined decompress behavior due to integer overflow // in limit reader creation. func TestNewCompressorWithInvalidLimit(t *testing.T) { - compressorFuncs := map[string]func(int64) (Compressor, error){ - "gzip": NewGzipCompressor, - "zstd": NewZstdCompressor, - } - - for name, compressorFunc := range compressorFuncs { - t.Run(name, func(t *testing.T) { + for compressionType, compressorFunc := range newCompressorFuncs { + if compressionType == TypeNone { + continue + } + t.Run(compressionType.String(), func(t *testing.T) { require := require.New(t) _, err := compressorFunc(math.MaxInt64) require.ErrorIs(err, ErrInvalidMaxSizeCompressor) From a0c1ddadab24ed3d6b6d757e7d4d4028a1412c05 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 5 Apr 2023 14:59:53 -0400 Subject: [PATCH 48/54] appease linter --- utils/compression/compressor_test.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/utils/compression/compressor_test.go b/utils/compression/compressor_test.go index b972cf4badc..0ba58ab30f3 100644 --- a/utils/compression/compressor_test.go +++ b/utils/compression/compressor_test.go @@ -16,15 +16,11 @@ import ( const maxMessageSize = 2 * units.MiB // Max message size. Can't import due to cycle. var newCompressorFuncs = map[Type]func(maxSize int64) (Compressor, error){ - TypeNone: func(int64) (Compressor, error) { + TypeNone: func(int64) (Compressor, error) { //nolint return NewNoCompressor(), nil }, - TypeGzip: func(maxSize int64) (Compressor, error) { - return NewGzipCompressor(maxSize) - }, - TypeZstd: func(maxSize int64) (Compressor, error) { - return NewZstdCompressor(maxSize) - }, + TypeGzip: NewGzipCompressor, + TypeZstd: NewZstdCompressor, } func TestCompressDecompress(t *testing.T) { From 26e723557865a54a9690399769a5efd35434d41e Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 5 Apr 2023 16:10:46 -0400 Subject: [PATCH 49/54] remove magic number --- utils/compression/compressor_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/compression/compressor_test.go b/utils/compression/compressor_test.go index 0ba58ab30f3..61b41c0f9fb 100644 --- a/utils/compression/compressor_test.go +++ b/utils/compression/compressor_test.go @@ -57,8 +57,8 @@ func TestCompressDecompress(t *testing.T) { require.NoError(t, err) require.EqualValues(t, data, dataDecompressed) - maxMessage := make([]byte, 2*units.MiB) // Max message size. Can't import due to cycle. - _, err = rand.Read(maxMessage) // #nosec G404 + maxMessage := make([]byte, maxMessageSize) // Max message size. Can't import due to cycle. + _, err = rand.Read(maxMessage) // #nosec G404 require.NoError(t, err) maxMessageCompressed, err := compressor.Compress(maxMessage) @@ -140,7 +140,7 @@ func fuzzHelper(f *testing.F, compressionType Type) { f.Fuzz(func(t *testing.T, data []byte) { require := require.New(t) - if len(data) > 2*units.MiB { + if len(data) > maxMessageSize { _, err := compressor.Compress(data) require.Error(err) } From 436685b7000589b160e0c85a4709c1836939ca92 Mon Sep 17 00:00:00 2001 From: Stephen Date: Wed, 5 Apr 2023 16:48:07 -0400 Subject: [PATCH 50/54] imports nit --- message/messages.go | 1 + 1 file changed, 1 insertion(+) diff --git a/message/messages.go b/message/messages.go index bdaec43bbc6..8d5ba0ce538 100644 --- a/message/messages.go +++ b/message/messages.go @@ -9,6 +9,7 @@ import ( "time" "github.com/prometheus/client_golang/prometheus" + "go.uber.org/zap" "google.golang.org/protobuf/proto" From b40e14b17c0f41a05babde475ed3c837935fbb95 Mon Sep 17 00:00:00 2001 From: Stephen Date: Wed, 5 Apr 2023 16:50:34 -0400 Subject: [PATCH 51/54] nit --- message/messages.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/message/messages.go b/message/messages.go index 8d5ba0ce538..99ac9dc6c4b 100644 --- a/message/messages.go +++ b/message/messages.go @@ -327,7 +327,9 @@ func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, Op, error) { decompressTimeMetric.Observe(float64(decompressTook)) } else { // Should never happen - mb.log.Warn("no decompression metric found for op", zap.Stringer("op", op)) + mb.log.Warn("no decompression metric found for op", + zap.Stringer("op", op), + ) } return m, bytesSavedCompression, op, nil From 0c0a396c629bfde81a3868f83da05a553db165ba Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 5 Apr 2023 16:55:00 -0400 Subject: [PATCH 52/54] test nits --- utils/compression/compressor_test.go | 100 +++++++++------------------ 1 file changed, 33 insertions(+), 67 deletions(-) diff --git a/utils/compression/compressor_test.go b/utils/compression/compressor_test.go index 16a3b4b4577..9d059bac8d6 100644 --- a/utils/compression/compressor_test.go +++ b/utils/compression/compressor_test.go @@ -157,92 +157,58 @@ func fuzzHelper(f *testing.F, compressionType Type) { }) } -func BenchmarkGzipCompress(b *testing.B) { +func BenchmarkCompress(b *testing.B) { sizes := []int{ 0, 256, units.KiB, units.MiB, + maxMessageSize, } - for _, size := range sizes { - bytes := utils.RandomBytes(size) - compressor, err := NewGzipCompressor(2 * units.MiB) - require.NoError(b, err) - - b.Run(fmt.Sprintf("%d", size), func(b *testing.B) { - for n := 0; n < b.N; n++ { - _, err := compressor.Compress(bytes) + for compressionType, newCompressorFunc := range newCompressorFuncs { + if compressionType == TypeNone { + continue + } + for _, size := range sizes { + b.Run(fmt.Sprintf("%s_%d", compressionType, size), func(b *testing.B) { + bytes := utils.RandomBytes(size) + compressor, err := newCompressorFunc(maxMessageSize) require.NoError(b, err) - } - }) + for n := 0; n < b.N; n++ { + _, err := compressor.Compress(bytes) + require.NoError(b, err) + } + }) + } } } -func BenchmarkGzipDecompress(b *testing.B) { +func BenchmarkDecompress(b *testing.B) { sizes := []int{ 0, 256, units.KiB, units.MiB, + maxMessageSize, } - for _, size := range sizes { - bytes := utils.RandomBytes(size) - compressor, err := NewGzipCompressor(2 * units.MiB) - require.NoError(b, err) - - compressedBytes, err := compressor.Compress(bytes) - require.NoError(b, err) - - b.Run(fmt.Sprintf("%d", size), func(b *testing.B) { - for n := 0; n < b.N; n++ { - _, err := compressor.Decompress(compressedBytes) + for compressionType, newCompressorFunc := range newCompressorFuncs { + if compressionType == TypeNone { + continue + } + for _, size := range sizes { + b.Run(fmt.Sprintf("%s_%d", compressionType, size), func(b *testing.B) { + bytes := utils.RandomBytes(size) + compressor, err := newCompressorFunc(maxMessageSize) require.NoError(b, err) - } - }) - } -} -func BenchmarkZstdCompress(b *testing.B) { - sizes := []int{ - 0, - 256, - units.KiB, - units.MiB, - } - for _, size := range sizes { - bytes := utils.RandomBytes(size) - compressor, err := NewZstdCompressor(2 * units.MiB) - require.NoError(b, err) - - b.Run(fmt.Sprintf("%d", size), func(b *testing.B) { - for n := 0; n < b.N; n++ { - _, err := compressor.Compress(bytes) + compressedBytes, err := compressor.Compress(bytes) require.NoError(b, err) - } - }) - } -} -func BenchmarkZstdDecompress(b *testing.B) { - sizes := []int{ - 0, - 256, - units.KiB, - units.MiB, - } - for _, size := range sizes { - bytes := utils.RandomBytes(size) - compressor, err := NewZstdCompressor(2 * units.MiB) - require.NoError(b, err) - - compressedBytes, err := compressor.Compress(bytes) - require.NoError(b, err) - - b.Run(fmt.Sprintf("%d", size), func(b *testing.B) { - for n := 0; n < b.N; n++ { - _, err := compressor.Decompress(compressedBytes) - require.NoError(b, err) - } - }) + for n := 0; n < b.N; n++ { + _, err := compressor.Decompress(compressedBytes) + require.NoError(b, err) + } + }) + } } } From 0fca08a43548e3e48c093b140d8a9baaaab5ebc2 Mon Sep 17 00:00:00 2001 From: Stephen Date: Wed, 5 Apr 2023 17:00:06 -0400 Subject: [PATCH 53/54] nits --- utils/compression/compressor_test.go | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/utils/compression/compressor_test.go b/utils/compression/compressor_test.go index 9d059bac8d6..8d8adaf7741 100644 --- a/utils/compression/compressor_test.go +++ b/utils/compression/compressor_test.go @@ -6,7 +6,6 @@ package compression import ( "fmt" "math" - "math/rand" "testing" "github.com/stretchr/testify/require" @@ -28,15 +27,8 @@ var newCompressorFuncs = map[Type]func(maxSize int64) (Compressor, error){ func TestCompressDecompress(t *testing.T) { for compressionType, newCompressorFunc := range newCompressorFuncs { t.Run(compressionType.String(), func(t *testing.T) { - data := make([]byte, 4096) - for i := 0; i < len(data); i++ { - data[i] = byte(rand.Intn(256)) // #nosec G404 - } - - data2 := make([]byte, 4096) - for i := 0; i < len(data); i++ { - data2[i] = byte(rand.Intn(256)) // #nosec G404 - } + data := utils.RandomBytes(4096) + data2 := utils.RandomBytes(4096) compressor, err := newCompressorFunc(maxMessageSize) require.NoError(t, err) @@ -59,10 +51,7 @@ func TestCompressDecompress(t *testing.T) { require.NoError(t, err) require.EqualValues(t, data, dataDecompressed) - maxMessage := make([]byte, maxMessageSize) // Max message size. Can't import due to cycle. - _, err = rand.Read(maxMessage) // #nosec G404 - require.NoError(t, err) - + maxMessage := utils.RandomBytes(maxMessageSize) maxMessageCompressed, err := compressor.Compress(maxMessage) require.NoError(t, err) From dfc909d5c5beb9cdcbb09042ab255c8968e7ce54 Mon Sep 17 00:00:00 2001 From: Stephen Date: Wed, 5 Apr 2023 17:03:24 -0400 Subject: [PATCH 54/54] nit --- utils/compression/compressor_test.go | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/utils/compression/compressor_test.go b/utils/compression/compressor_test.go index 61b41c0f9fb..4ba60dd90d4 100644 --- a/utils/compression/compressor_test.go +++ b/utils/compression/compressor_test.go @@ -5,18 +5,18 @@ package compression import ( "math" - "math/rand" "testing" "github.com/stretchr/testify/require" + "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/units" ) const maxMessageSize = 2 * units.MiB // Max message size. Can't import due to cycle. var newCompressorFuncs = map[Type]func(maxSize int64) (Compressor, error){ - TypeNone: func(int64) (Compressor, error) { //nolint + TypeNone: func(int64) (Compressor, error) { //nolint:unparam // an error is needed to be returned to compile return NewNoCompressor(), nil }, TypeGzip: NewGzipCompressor, @@ -26,15 +26,8 @@ var newCompressorFuncs = map[Type]func(maxSize int64) (Compressor, error){ func TestCompressDecompress(t *testing.T) { for compressionType, newCompressorFunc := range newCompressorFuncs { t.Run(compressionType.String(), func(t *testing.T) { - data := make([]byte, 4096) - for i := 0; i < len(data); i++ { - data[i] = byte(rand.Intn(256)) // #nosec G404 - } - - data2 := make([]byte, 4096) - for i := 0; i < len(data); i++ { - data2[i] = byte(rand.Intn(256)) // #nosec G404 - } + data := utils.RandomBytes(4096) + data2 := utils.RandomBytes(4096) compressor, err := newCompressorFunc(maxMessageSize) require.NoError(t, err) @@ -57,10 +50,7 @@ func TestCompressDecompress(t *testing.T) { require.NoError(t, err) require.EqualValues(t, data, dataDecompressed) - maxMessage := make([]byte, maxMessageSize) // Max message size. Can't import due to cycle. - _, err = rand.Read(maxMessage) // #nosec G404 - require.NoError(t, err) - + maxMessage := utils.RandomBytes(maxMessageSize) maxMessageCompressed, err := compressor.Compress(maxMessage) require.NoError(t, err)