Skip to content

Commit

Permalink
fix: worst case share indexes (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
rootulp authored Mar 15, 2024
1 parent 2ce8723 commit 1673eb9
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 7 deletions.
21 changes: 14 additions & 7 deletions square/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func (b *Builder) AppendBlobTx(blobTx *blob.BlobTx) bool {
iw := &blob.IndexWrapper{
Tx: blobTx.Tx,
TypeId: blob.ProtoIndexWrapperTypeID,
ShareIndexes: worstCaseShareIndexes(len(blobTx.Blobs), b.maxSquareSize),
ShareIndexes: worstCaseShareIndexes(len(blobTx.Blobs)),
}
size := proto.Size(iw)
pfbShareDiff := b.PfbCounter.Add(size)
Expand Down Expand Up @@ -407,14 +407,21 @@ func (e Element) maxShareOffset() int {
return e.NumShares + e.MaxPadding
}

// worstCaseShareIndexes returns the largest possible share indexes for a set
// of blobs at a given appversion. Largest possible is "worst" in that protobuf
// uses varints to encode integers, so larger integers can require more bytes to
// encode.
func worstCaseShareIndexes(blobs, maxSquareSize int) []uint32 {
// worstCaseShareIndexes returns the largest possible share indexes for a set of
// blobs. Largest possible is "worst" in that protobuf uses varints to encode
// integers, so larger integers can require more bytes to encode.
//
// Note: the implementation of this function assumes that the worst case share
// index is always 128 * 128 to preserve backwards compatibility with
// celestia-app v1.x.
func worstCaseShareIndexes(blobs int) []uint32 {
// TODO: de-duplicate this constant with celestia-app SquareSizeUpperBound constant.
// https://github.com/celestiaorg/celestia-app/blob/a93bb625c6dc0ae6c7c357e9991815a68ab33c79/pkg/appconsts/v1/app_consts.go#L5
squareSizeUpperBound := 128
worstCaseShareIndex := squareSizeUpperBound * squareSizeUpperBound
shareIndexes := make([]uint32, blobs)
for i := range shareIndexes {
shareIndexes[i] = uint32(maxSquareSize * maxSquareSize)
shareIndexes[i] = uint32(worstCaseShareIndex)
}
return shareIndexes
}
32 changes: 32 additions & 0 deletions square/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package square_test

import (
"bytes"
_ "embed"
"encoding/json"
"fmt"
"math/rand"
"testing"
Expand Down Expand Up @@ -341,3 +343,33 @@ func generateBlobTxsWithNamespaces(namespaces []namespace.Namespace, blobSizes [
}
return txs
}

type block struct {
Txs [][]byte `protobuf:"bytes,1,rep,name=txs,proto3" json:"txs,omitempty"`
}

// TestBigBlock indirectly verifies that the worst case share padding
// calculation is computed using the rules on celestia-app v1.x. This test does
// so by using a big_block.json file generated via celestia-app v1.x and then
// verifies the share index of a particular blob. Note: if worst case share
// padding is modified then we expect this test to fail and need a new valid
// testdata/big_block.json.
//
// https://github.com/celestiaorg/go-square/issues/47
func TestBigBlock(t *testing.T) {
bigBlock := block{}
err := json.Unmarshal([]byte(bigBlockJSON), &bigBlock)
require.NoError(t, err)

builder, err := square.NewBuilder(defaultMaxSquareSize, defaultSubtreeRootThreshold, bigBlock.Txs...)
require.NoError(t, err)
assert.Len(t, builder.Blobs, 84)
assert.Len(t, builder.Pfbs, 25)

index, err := builder.FindBlobStartingIndex(0, 0)
require.NoError(t, err)
assert.Equal(t, 2234, index)
}

//go:embed "testdata/big_block.json"
var bigBlockJSON string
29 changes: 29 additions & 0 deletions square/testdata/big_block.json

Large diffs are not rendered by default.

0 comments on commit 1673eb9

Please sign in to comment.