Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions libs/appconsts/appconsts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package appconsts

// These constants were originally sourced from:
// https://github.com/celestiaorg/celestia-specs/blob/master/src/specs/consensus.md#constants
const (
// NamespaveVersionSize is the size of a namespace version in bytes.
NamespaceVersionSize = 1

// NamespaceIDSize is the size of a namespace ID in bytes.
NamespaceIDSize = 32

// NamespaceSize is the size of a namespace (version + ID) in bytes.
NamespaceSize = NamespaceVersionSize + NamespaceIDSize

// ShareSize is the size of a share in bytes.
ShareSize = 512

// ShareInfoBytes is the number of bytes reserved for information. The info
// byte contains the share version and a sequence start idicator.
ShareInfoBytes = 1

// SequenceLenBytes is the number of bytes reserved for the sequence length
// that is present in the first share of a sequence.
SequenceLenBytes = 4

// ShareVersionZero is the first share version format.
ShareVersionZero = uint8(0)

// DefaultShareVersion is the defacto share version. Use this if you are
// unsure of which version to use.
DefaultShareVersion = ShareVersionZero

// CompactShareReservedBytes is the number of bytes reserved for the location of
// the first unit (transaction, ISR) in a compact share.
CompactShareReservedBytes = 4

// FirstCompactShareContentSize is the number of bytes usable for data in
// the first compact share of a sequence.
FirstCompactShareContentSize = ShareSize - NamespaceSize - ShareInfoBytes - SequenceLenBytes - CompactShareReservedBytes

// ContinuationCompactShareContentSize is the number of bytes usable for
// data in a continuation compact share of a sequence.
ContinuationCompactShareContentSize = ShareSize - NamespaceSize - ShareInfoBytes - CompactShareReservedBytes

// FirstSparseShareContentSize is the number of bytes usable for data in the
// first sparse share of a sequence.
FirstSparseShareContentSize = ShareSize - NamespaceSize - ShareInfoBytes - SequenceLenBytes

// ContinuationSparseShareContentSize is the number of bytes usable for data
// in a continuation sparse share of a sequence.
ContinuationSparseShareContentSize = ShareSize - NamespaceSize - ShareInfoBytes

// DefaultMaxSquareSize is the maximum original square width.
//
// Note: 128 shares in a row * 128 shares in a column * 512 bytes in a share
// = 8 MiB
DefaultMaxSquareSize = 128

// MaxShareCount is the maximum number of shares allowed in the original
// data square.
MaxShareCount = DefaultMaxSquareSize * DefaultMaxSquareSize

// DefaultMinSquareSize is the smallest original square width.
DefaultMinSquareSize = 1

// MinshareCount is the minimum number of shares allowed in the original
// data square.
MinShareCount = DefaultMinSquareSize * DefaultMinSquareSize

// MaxShareVersion is the maximum value a share version can be.
MaxShareVersion = 127

// DefaultGasPerBlobByte is the default gas cost deducted per byte of blob
// included in a PayForBlobs txn
DefaultGasPerBlobByte = 8

// TransactionsPerBlockLimit is the maximum number of transactions a block
// producer will include in a block.
//
// NOTE: Currently this value is set at roughly the number of PFBs that
// would fill one quarter of the max square size.
TransactionsPerBlockLimit = 5090
)

var (

// TODO: Consider commenting back in. Removed to reduce unneeded dependency

// // NewBaseHashFunc is the base hash function used by NMT. Change accordingly
// // if another hash.Hash should be used as a base hasher in the NMT.
// NewBaseHashFunc = consts.NewBaseHashFunc
// // DefaultCodec is the default codec creator used for data erasure.
// DefaultCodec = rsmt2d.NewLeoRSCodec

// // DataCommitmentBlocksLimit is the limit to the number of blocks we can
// // generate a data commitment for.
// DataCommitmentBlocksLimit = consts.DataCommitmentBlocksLimit

// SupportedShareVersions is a list of supported share versions.
SupportedShareVersions = []uint8{ShareVersionZero}
)
8 changes: 8 additions & 0 deletions libs/appconsts/consensus_consts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package appconsts

import "time"

const (
TimeoutPropose = time.Second * 10
TimeoutCommit = time.Second * 10
)
70 changes: 70 additions & 0 deletions libs/namespace/consts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package namespace

import (
"bytes"
"math"

"github.com/rollkit/rollkit/libs/appconsts"
)

const (
// NamespaveVersionSize is the size of a namespace version in bytes.
NamespaceVersionSize = appconsts.NamespaceVersionSize

// NamespaceIDSize is the size of a namespace ID in bytes.
NamespaceIDSize = appconsts.NamespaceIDSize

// NamespaceSize is the size of a namespace (version + ID) in bytes.
NamespaceSize = appconsts.NamespaceSize

// NamespaceVersionZero is the first namespace version.
NamespaceVersionZero = uint8(0)

// NamespaceVersionMax is the max namespace version.
NamespaceVersionMax = math.MaxUint8

// NamespaceZeroPrefixSize is the number of `0` bytes that are prefixed to
// namespace IDs for version 0.
NamespaceVersionZeroPrefixSize = 22

// NamespaceVersionZeroIDSize is the number of bytes available for
// user-specified namespace ID in a namespace ID for version 0.
NamespaceVersionZeroIDSize = NamespaceIDSize - NamespaceVersionZeroPrefixSize
)

var (
// NamespaceVersionZeroPrefix is the prefix of a namespace ID for version 0.
NamespaceVersionZeroPrefix = bytes.Repeat([]byte{0}, NamespaceVersionZeroPrefixSize)

// TxNamespace is the namespace reserved for transaction data.
TxNamespace = MustNewV0([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 1})

// IntermediateStateRootsNamespace is the namespace reserved for
// intermediate state root data.
IntermediateStateRootsNamespace = MustNewV0([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 2})

// PayForBlobNamespace is the namespace reserved for PayForBlobs transactions.
PayForBlobNamespace = MustNewV0([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 4})

// ReservedPaddingNamespace is the namespace used for padding after all
// reserved namespaces. In practice this padding is after transactions
// (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})

// TailPaddingNamespace is the namespace reserved for tail padding. All data
// with this namespace will be ignored.
TailPaddingNamespace = Namespace{
Version: math.MaxUint8,
ID: append(bytes.Repeat([]byte{0xFF}, NamespaceIDSize-1), 0xFE),
}

// ParitySharesNamespace is the namespace reserved for erasure coded data.
ParitySharesNamespace = Namespace{
Version: math.MaxUint8,
ID: bytes.Repeat([]byte{0xFF}, NamespaceIDSize),
}
)
130 changes: 130 additions & 0 deletions libs/namespace/namespace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package namespace

import (
"bytes"
"fmt"
)

type Namespace struct {
Version uint8
ID []byte
}

// New returns a new namespace with the provided version and id.
func New(version uint8, id []byte) (Namespace, error) {
err := validateVersion(version)
if err != nil {
return Namespace{}, err
}

err = validateID(version, id)
if err != nil {
return Namespace{}, err
}

return Namespace{
Version: version,
ID: id,
}, nil
}

// MustNew returns a new namespace with the provided version and id. It panics
// if the provided version or id are not supported.
func MustNew(version uint8, id []byte) Namespace {
ns, err := New(version, id)
if err != nil {
panic(err)
}
return ns
}

// MustNewV0 returns a new namespace with version 0 and the provided id. This
// function panics if the provided id is not exactly NamespaceVersionZeroIDSize bytes.
func MustNewV0(id []byte) Namespace {
if len(id) != NamespaceVersionZeroIDSize {
panic(fmt.Sprintf("invalid namespace id length: %v must be %v", len(id), NamespaceVersionZeroIDSize))
}

ns, err := New(NamespaceVersionZero, append(NamespaceVersionZeroPrefix, id...))
if err != nil {
panic(err)
}
return ns
}

// From returns a namespace from the provided byte slice.
func From(b []byte) (Namespace, error) {
if len(b) != NamespaceSize {
return Namespace{}, fmt.Errorf("invalid namespace length: %v must be %v", len(b), NamespaceSize)
}
rawVersion := b[0]
rawNamespace := b[1:]
return New(rawVersion, rawNamespace)
}

// Bytes returns this namespace as a byte slice.
func (n Namespace) Bytes() []byte {
return append([]byte{n.Version}, n.ID...)
}

// ValidateBlobNamespace returns an error if this namespace is not a valid blob namespace.
func (n Namespace) ValidateBlobNamespace() error {
if n.IsReserved() {
return fmt.Errorf("invalid blob namespace: %v cannot use a reserved namespace ID, want > %v", n.Bytes(), MaxReservedNamespace.Bytes())
}

if n.IsParityShares() {
return fmt.Errorf("invalid blob namespace: %v cannot use parity shares namespace ID", n.Bytes())
}

if n.IsTailPadding() {
return fmt.Errorf("invalid blob namespace: %v cannot use tail padding namespace ID", n.Bytes())
}

return nil
}

// validateVersion returns an error if the version is not supported.
func validateVersion(version uint8) error {
if version != NamespaceVersionZero && version != NamespaceVersionMax {
return fmt.Errorf("unsupported namespace version %v", version)
}
return nil
}

// validateID returns an error if the provided id does not meet the requirements
// for the provided version.
func validateID(version uint8, id []byte) error {
if len(id) != NamespaceIDSize {
return fmt.Errorf("unsupported namespace id length: id %v must be %v bytes but it was %v bytes", id, NamespaceIDSize, len(id))
}

if version == NamespaceVersionZero && !bytes.HasPrefix(id, NamespaceVersionZeroPrefix) {
return fmt.Errorf("unsupported namespace id with version %v. ID %v must start with %v leading zeros", version, id, len(NamespaceVersionZeroPrefix))
}
return nil
}

func (n Namespace) IsReserved() bool {
return bytes.Compare(n.Bytes(), MaxReservedNamespace.Bytes()) < 1
}

func (n Namespace) IsParityShares() bool {
return bytes.Equal(n.Bytes(), ParitySharesNamespace.Bytes())
}

func (n Namespace) IsTailPadding() bool {
return bytes.Equal(n.Bytes(), TailPaddingNamespace.Bytes())
}

func (n Namespace) IsReservedPadding() bool {
return bytes.Equal(n.Bytes(), ReservedPaddingNamespace.Bytes())
}

func (n Namespace) IsTx() bool {
return bytes.Equal(n.Bytes(), TxNamespace.Bytes())
}

func (n Namespace) IsPayForBlob() bool {
return bytes.Equal(n.Bytes(), PayForBlobNamespace.Bytes())
}
Loading