From b3b8611c299a113a7283df2e986b5d7f2498c9e5 Mon Sep 17 00:00:00 2001 From: Sanaz Taheri <35961250+staheri14@users.noreply.github.com> Date: Thu, 3 Aug 2023 16:12:50 +0300 Subject: [PATCH] feat!: incorporates ParitySharesNamespace and TailPaddingNamespace into IsReserved function (#2194) ## Overview Closes #https://github.com/celestiaorg/celestia-app/issues/2138 This PR also addresses the concerns raised in the [comment](https://github.com/celestiaorg/celestia-app/issues/2138#issuecomment-1657219076) by introducing a distinction between two types of reserved namespaces. Namespaces within the range [0-255] are now identified as "Primary Reserved Namespaces," while any other reserved namespaces beyond this range are categorized as "Non-Primary Reserved Namespaces." Hopefully, this differentiation provides better clarity and organization regarding namespace allocation and usage within the code. ## Checklist - [x] New and updated code has appropriate documentation - [x] New and updated code has new and/or updated testing - [x] Required CI checks are passing - [x] Visual proof for any user facing features like CLI or documentation updates - [x] Linked issues closed with keywords --- pkg/namespace/consts.go | 7 ++++--- pkg/namespace/namespace.go | 6 +++++- pkg/namespace/random_blob.go | 8 -------- specs/src/specs/namespace.md | 27 +++++++++++++++------------ x/blob/types/payforblob.go | 10 +--------- x/blob/types/payforblob_test.go | 8 ++++---- 6 files changed, 29 insertions(+), 37 deletions(-) diff --git a/pkg/namespace/consts.go b/pkg/namespace/consts.go index 64b5f8db84..df30ba4e21 100644 --- a/pkg/namespace/consts.go +++ b/pkg/namespace/consts.go @@ -51,9 +51,10 @@ var ( // (ordinary and PFBs) but before blobs. ReservedPaddingNamespace = MustNewV0([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 255}) - // MaxReservedNamespace is lexicographically the largest namespace that is - // reserved for protocol use. - MaxReservedNamespace = MustNewV0([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 255}) + // MaxPrimaryReservedNamespace represents the largest primary reserved + // namespace reserved for protocol use. Note that there may be other + // non-primary reserved namespaces beyond this upper limit. + MaxPrimaryReservedNamespace = MustNewV0([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 255}) // TailPaddingNamespace is the namespace reserved for tail padding. All data // with this namespace will be ignored. diff --git a/pkg/namespace/namespace.go b/pkg/namespace/namespace.go index 42889dd8a1..682385721f 100644 --- a/pkg/namespace/namespace.go +++ b/pkg/namespace/namespace.go @@ -104,8 +104,12 @@ func validateID(version uint8, id []byte) error { return nil } +// IsReserved returns true if the namespace is reserved for protocol-use. func (n Namespace) IsReserved() bool { - return bytes.Compare(n.Bytes(), MaxReservedNamespace.Bytes()) < 1 + isLessThanOrEqualToMaxPrimaryReservedNamespace := bytes.Compare(n.Bytes(), MaxPrimaryReservedNamespace.Bytes()) < 1 + isParityNamespace := n.IsParityShares() + isTailPadding := n.IsTailPadding() + return isLessThanOrEqualToMaxPrimaryReservedNamespace || isParityNamespace || isTailPadding } func (n Namespace) IsParityShares() bool { diff --git a/pkg/namespace/random_blob.go b/pkg/namespace/random_blob.go index 1bc459ca29..156d8a574f 100644 --- a/pkg/namespace/random_blob.go +++ b/pkg/namespace/random_blob.go @@ -43,14 +43,6 @@ func isBlobNamespace(ns Namespace) bool { return false } - if ns.IsParityShares() { - return false - } - - if ns.IsTailPadding() { - return false - } - if !slices.Contains(SupportedBlobNamespaceVersions, ns.Version) { return false } diff --git a/specs/src/specs/namespace.md b/specs/src/specs/namespace.md index d5fb595f3a..1c6abd5257 100644 --- a/specs/src/specs/namespace.md +++ b/specs/src/specs/namespace.md @@ -58,25 +58,28 @@ The ID is encoded as a byte slice of length 28. ## Reserved Namespaces Celestia reserves certain namespaces with specific meanings. -Celestia makes use of the reserved namespaces to properly organize and order transactions and blobs inside the [data square](./data_square_layout.md). +Reserved namespaces are used to properly organize and order transactions and blobs inside the [data square](./data_square_layout.md). Applications MUST NOT use these reserved namespaces for their blob data. -Below is a list of reserved namespaces, along with a brief description of each. -In addition to the items listed in this table, it should be noted that namespaces with values less than `0x00000000000000000000000000000000000000000000000000000000FF` are exclusively reserved for use within the Celestia protocols. +Reserved namespaces fall into two categories, _Primary Reserved Namespaces_ and _Secondary Reserved Namespaces_. +- Primary Reserved Namespaces: Namespaces with values less than or equal to `0x00000000000000000000000000000000000000000000000000000000FF` are referred to as Primary Reserved Namespaces and are exclusively reserved for use within the Celestia protocols. +- Secondary Reserved Namespaces: Currently, there are two secondary reserved namespaces, namely, `PARITY_SHARE_NAMESPACE` and `TAIL_PADDING_NAMESPACE` which fall out of the range of primary reserved namespaces. In the table, you will notice that the `PARITY_SHARE_NAMESPACE` and `TAIL_PADDING_NAMESPACE` utilize the namespace version `255`, which differs from the supported user-specified versions. The reason for employing version `255` for the `PARITY_SHARE_NAMESPACE` is to enable more efficient proof generation within the context of [nmt](https://github.com/celestiaorg/nmt), where it is used in conjunction with the `IgnoreMaxNamespace` feature. Similarly, the `TAIL_PADDING_NAMESPACE` utilizes the namespace version `255` to ensure that padding shares are always properly ordered and placed at the end of the Celestia data square even if a new namespace version is introduced. + +Below is a list of currently used primary and secondary reserved namespaces, along with a brief description of each. For additional information on the significance and application of the reserved namespaces, please refer to the [Data Square Layout](./data_square_layout.md) specifications. -| name | type | value | description | -|-------------------------------------|-------------|----------------------------------------------------------------|------------------------------------------------------------------------------------------------------| -| `TRANSACTION_NAMESPACE` | `Namespace` | `0x0000000000000000000000000000000000000000000000000000000001` | Transactions: requests that modify the state. | -| `INTERMEDIATE_STATE_ROOT_NAMESPACE` | `Namespace` | `0x0000000000000000000000000000000000000000000000000000000002` | Intermediate state roots, committed after every transaction. | -| `PAY_FOR_BLOB_NAMESPACE` | `Namespace` | `0x0000000000000000000000000000000000000000000000000000000004` | Namespace reserved for transactions that contain a PayForBlob. | -| `RESERVED_PADDING_NAMESPACE` | `Namespace` | `0x00000000000000000000000000000000000000000000000000000000FF` | Padding after all reserved namespaces but before blobs. | -| `MAX_RESERVED_NAMESPACE` | `Namespace` | `0x00000000000000000000000000000000000000000000000000000000FF` | Max reserved namespace is lexicographically the largest namespace that is reserved for protocol use. | -| `TAIL_PADDING_NAMESPACE` | `Namespace` | `0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE` | Tail padding for blobs: padding after all blobs to fill up the original data square. | -| `PARITY_SHARE_NAMESPACE` | `Namespace` | `0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF` | Parity shares: extended shares in the available data matrix. | +| name | type | value | description | +|-------------------------------------|-------------|----------------------------------------------------------------|-------------------------------------------------------------------------------------------------------| +| `TRANSACTION_NAMESPACE` | `Namespace` | `0x0000000000000000000000000000000000000000000000000000000001` | Transactions: requests that modify the state. | +| `INTERMEDIATE_STATE_ROOT_NAMESPACE` | `Namespace` | `0x0000000000000000000000000000000000000000000000000000000002` | Intermediate state roots, committed after every transaction. | +| `PAY_FOR_BLOB_NAMESPACE` | `Namespace` | `0x0000000000000000000000000000000000000000000000000000000004` | Namespace reserved for transactions that contain a PayForBlob. | +| `RESERVED_PADDING_NAMESPACE` | `Namespace` | `0x00000000000000000000000000000000000000000000000000000000FF` | Padding after all reserved namespaces but before blobs. | +| `MAX_PRIMARY_RESERVED_NAMESPACE` | `Namespace` | `0x00000000000000000000000000000000000000000000000000000000FF` | Max primary reserved namespace is the largest primary reserved namespace designated for protocol use. | +| `TAIL_PADDING_NAMESPACE` | `Namespace` | `0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE` | Tail padding for blobs: padding after all blobs to fill up the original data square. | +| `PARITY_SHARE_NAMESPACE` | `Namespace` | `0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF` | Parity shares: extended shares in the available data matrix. | ## Assumptions and Considerations diff --git a/x/blob/types/payforblob.go b/x/blob/types/payforblob.go index 7395b04f60..5fbb6ae9fe 100644 --- a/x/blob/types/payforblob.go +++ b/x/blob/types/payforblob.go @@ -186,15 +186,7 @@ func DefaultEstimateGas(blobSizes []uint32) uint64 { // tail padding). func ValidateBlobNamespace(ns appns.Namespace) error { if ns.IsReserved() { - return ErrReservedNamespace.Wrapf("got namespace: %x, want: > %x", ns, appns.MaxReservedNamespace) - } - - if ns.IsParityShares() { - return ErrParitySharesNamespace - } - - if ns.IsTailPadding() { - return ErrTailPaddingNamespace + return ErrReservedNamespace } if !slices.Contains(appns.SupportedBlobNamespaceVersions, ns.Version) { diff --git a/x/blob/types/payforblob_test.go b/x/blob/types/payforblob_test.go index cfdaa1d844..84c79f14da 100644 --- a/x/blob/types/payforblob_test.go +++ b/x/blob/types/payforblob_test.go @@ -139,9 +139,9 @@ func TestValidateBasic(t *testing.T) { intermediateStateRootsNamespaceMsg := validMsgPayForBlobs(t) intermediateStateRootsNamespaceMsg.Namespaces[0] = appns.IntermediateStateRootsNamespace.Bytes() - // MsgPayForBlobs that uses the max reserved namespace + // MsgPayForBlobs that uses the max primary reserved namespace maxReservedNamespaceMsg := validMsgPayForBlobs(t) - maxReservedNamespaceMsg.Namespaces[0] = appns.MaxReservedNamespace.Bytes() + maxReservedNamespaceMsg.Namespaces[0] = appns.MaxPrimaryReservedNamespace.Bytes() // MsgPayForBlobs that has an empty share commitment emptyShareCommitment := validMsgPayForBlobs(t) @@ -176,12 +176,12 @@ func TestValidateBasic(t *testing.T) { { name: "parity shares namespace", msg: paritySharesMsg, - wantErr: ErrParitySharesNamespace, + wantErr: ErrReservedNamespace, }, { name: "tail padding namespace", msg: tailPaddingMsg, - wantErr: ErrTailPaddingNamespace, + wantErr: ErrReservedNamespace, }, { name: "tx namespace",