From 3b02987fd1cd6987fabf7c518f0bba27e14627b0 Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Mon, 29 Aug 2022 14:51:31 -0400 Subject: [PATCH 1/3] Implement info reserved byte --- pkg/shares/info_reserved_byte.go | 33 ++++++++++++ pkg/shares/info_reserved_byte_test.go | 73 +++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 pkg/shares/info_reserved_byte.go create mode 100644 pkg/shares/info_reserved_byte_test.go diff --git a/pkg/shares/info_reserved_byte.go b/pkg/shares/info_reserved_byte.go new file mode 100644 index 0000000000..adf6c8a935 --- /dev/null +++ b/pkg/shares/info_reserved_byte.go @@ -0,0 +1,33 @@ +package types + +import "fmt" + +// InfoReservedByte is a byte with the following structure: the first 7 bits are +// reserved for version information in big endian form (initially `0000000`). +// The last bit is a "message start indicator", that is `1` if the share is at +// the start of a message and `0` otherwise. +type InfoReservedByte byte + +func NewInfoReservedByte(version uint8, isMessageStart bool) (InfoReservedByte, error) { + if version > 127 { + return 0, fmt.Errorf("version %d must be less than or equal to 127", version) + } + + prefix := version << 1 + if isMessageStart { + return InfoReservedByte(prefix + 1), nil + } + return InfoReservedByte(prefix), nil +} + +// Version returns the version encoded in this InfoReservedByte. +// Version is expected to be between 0 and 127 (inclusive). +func (i InfoReservedByte) Version() uint8 { + version := uint8(i) >> 1 + return version +} + +// IsMessageStart returns whether this share is the start of a message. +func (i InfoReservedByte) IsMessageStart() bool { + return uint(i)%2 == 1 +} diff --git a/pkg/shares/info_reserved_byte_test.go b/pkg/shares/info_reserved_byte_test.go new file mode 100644 index 0000000000..d6bbb78072 --- /dev/null +++ b/pkg/shares/info_reserved_byte_test.go @@ -0,0 +1,73 @@ +package types + +import "testing" + +func TestInfoReservedByte(t *testing.T) { + messageStart := true + notMessageStart := false + + type testCase struct { + version uint8 + isMessageStart bool + } + tests := []testCase{ + {0, messageStart}, + {1, messageStart}, + {2, messageStart}, + {127, messageStart}, + + {0, notMessageStart}, + {1, notMessageStart}, + {2, notMessageStart}, + {127, notMessageStart}, + } + + for _, test := range tests { + irb, err := NewInfoReservedByte(test.version, test.isMessageStart) + if err != nil { + t.Errorf("got %v want no error", err) + } + if got := irb.Version(); got != test.version { + t.Errorf("got version %v want %v", got, test.version) + } + if got := irb.IsMessageStart(); got != test.isMessageStart { + t.Errorf("got isMessageStart %v want %v", got, test.isMessageStart) + } + } +} + +func TestInfoReservedByteErrors(t *testing.T) { + messageStart := true + notMessageStart := false + + type testCase struct { + version uint8 + isMessageStart bool + } + + tests := []testCase{ + {128, notMessageStart}, + {255, notMessageStart}, + {128, messageStart}, + {255, messageStart}, + } + + for _, test := range tests { + _, err := NewInfoReservedByte(test.version, false) + if err == nil { + t.Errorf("got nil but want error when version > 127") + } + } +} + +func FuzzNewInfoReservedByte(f *testing.F) { + f.Fuzz(func(t *testing.T, version uint8, isMessageStart bool) { + if version > 127 { + t.Skip() + } + _, err := NewInfoReservedByte(version, isMessageStart) + if err != nil { + t.Errorf("got nil but want error when version > 127") + } + }) +} From ea292c6b01ecceab868c28d8211b4a7bc6fd6c49 Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Mon, 29 Aug 2022 15:36:57 -0400 Subject: [PATCH 2/3] fix: package types -> shares --- pkg/shares/info_reserved_byte.go | 2 +- pkg/shares/info_reserved_byte_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/shares/info_reserved_byte.go b/pkg/shares/info_reserved_byte.go index adf6c8a935..ff12cbf17f 100644 --- a/pkg/shares/info_reserved_byte.go +++ b/pkg/shares/info_reserved_byte.go @@ -1,4 +1,4 @@ -package types +package shares import "fmt" diff --git a/pkg/shares/info_reserved_byte_test.go b/pkg/shares/info_reserved_byte_test.go index d6bbb78072..05ea5a973f 100644 --- a/pkg/shares/info_reserved_byte_test.go +++ b/pkg/shares/info_reserved_byte_test.go @@ -1,4 +1,4 @@ -package types +package shares import "testing" From 54dc074b139efb23dc1ccc17b9eb5743b89fb1b4 Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Wed, 31 Aug 2022 10:26:41 -0400 Subject: [PATCH 3/3] Extract const for MaxShareVersion --- pkg/appconsts/appconsts.go | 3 +++ pkg/shares/info_reserved_byte.go | 14 +++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pkg/appconsts/appconsts.go b/pkg/appconsts/appconsts.go index 1a104ff3b0..5fb7193dec 100644 --- a/pkg/appconsts/appconsts.go +++ b/pkg/appconsts/appconsts.go @@ -6,4 +6,7 @@ import ( "github.com/tendermint/tendermint/pkg/consts" ) +// MaxShareVersion is the maximum value a share version can be. +const MaxShareVersion = 127 + var NameSpacedPaddedShareBytes = bytes.Repeat([]byte{0}, consts.MsgShareSize) diff --git a/pkg/shares/info_reserved_byte.go b/pkg/shares/info_reserved_byte.go index ff12cbf17f..5562f05c76 100644 --- a/pkg/shares/info_reserved_byte.go +++ b/pkg/shares/info_reserved_byte.go @@ -1,6 +1,10 @@ package shares -import "fmt" +import ( + "fmt" + + "github.com/celestiaorg/celestia-app/pkg/appconsts" +) // InfoReservedByte is a byte with the following structure: the first 7 bits are // reserved for version information in big endian form (initially `0000000`). @@ -9,8 +13,8 @@ import "fmt" type InfoReservedByte byte func NewInfoReservedByte(version uint8, isMessageStart bool) (InfoReservedByte, error) { - if version > 127 { - return 0, fmt.Errorf("version %d must be less than or equal to 127", version) + if version > appconsts.MaxShareVersion { + return 0, fmt.Errorf("version %d must be less than or equal to %d", version, appconsts.MaxShareVersion) } prefix := version << 1 @@ -20,8 +24,8 @@ func NewInfoReservedByte(version uint8, isMessageStart bool) (InfoReservedByte, return InfoReservedByte(prefix), nil } -// Version returns the version encoded in this InfoReservedByte. -// Version is expected to be between 0 and 127 (inclusive). +// Version returns the version encoded in this InfoReservedByte. Version is +// expected to be between 0 and appconsts.MaxShareVersion (inclusive). func (i InfoReservedByte) Version() uint8 { version := uint8(i) >> 1 return version