Skip to content

Commit

Permalink
Merge pull request #440 from celestiaorg/hlib/tail-padding
Browse files Browse the repository at this point in the history
  • Loading branch information
Wondertan authored Jul 1, 2021
2 parents 004a1a9 + efd2150 commit 0fa5dce
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 25 deletions.
26 changes: 5 additions & 21 deletions p2p/ipld/wrapper/nmt_wrapper.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
package wrapper

import (
"bytes"
"fmt"

"github.com/lazyledger/nmt"
"github.com/lazyledger/nmt/namespace"
"github.com/lazyledger/rsmt2d"

"github.com/lazyledger/lazyledger-core/types/consts"
)

// emptyNamepsaceID occurs when a share is empty and indicates that
var emptyNamespaceID = namespace.ID{0, 0, 0, 0, 0, 0, 0, 0}

// Fulfills the rsmt2d.Tree interface and rsmt2d.TreeConstructorFn function
var _ rsmt2d.TreeConstructorFn = ErasuredNamespacedMerkleTree{}.Constructor
var _ rsmt2d.Tree = &ErasuredNamespacedMerkleTree{}
Expand Down Expand Up @@ -53,28 +48,17 @@ func (w ErasuredNamespacedMerkleTree) Constructor() rsmt2d.Tree {
// rsmt.Tree interface. NOTE: panics if an error is encountered while pushing or
// if the tree size is exceeded.
func (w *ErasuredNamespacedMerkleTree) Push(data []byte, idx rsmt2d.SquareIndex) {
// determine the namespace based on where in the tree we're pushing
nsID := make(namespace.ID, consts.NamespaceSize)

if idx.Axis+1 > 2*uint(w.squareSize) || idx.Cell+1 > 2*uint(w.squareSize) {
panic(fmt.Sprintf("pushed past predetermined square size: boundary at %d index at %+v", 2*w.squareSize, idx))
}

// use the parity namespace if the cell is not in Q0 of the extended
// datasquare if the cell is empty it means we got an empty block so we need
// to use TailPaddingNamespaceID
nidAndData := make([]byte, consts.NamespaceSize+len(data))
copy(nidAndData[consts.NamespaceSize:], data)
// use the parity namespace if the cell is not in Q0 of the extended data square
if idx.Axis+1 > uint(w.squareSize) || idx.Cell+1 > uint(w.squareSize) {
copy(nsID, consts.ParitySharesNamespaceID)
copy(nidAndData[:consts.NamespaceSize], consts.ParitySharesNamespaceID)
} else {
// empty shares use the TailPaddingNamespaceID if the data is empty, so
// here we check if the share is empty (namepsace == [0,0,0,0,0,0,0,0])
if bytes.Equal(data[:consts.NamespaceSize], emptyNamespaceID) {
copy(nsID, consts.TailPaddingNamespaceID)
} else {
copy(nsID, data[:consts.NamespaceSize])
}
copy(nidAndData[:consts.NamespaceSize], data[:consts.NamespaceSize])
}
nidAndData := append(append(make([]byte, 0, consts.NamespaceSize+len(data)), nsID...), data...)
// push to the underlying tree
err := w.tree.Push(nidAndData)
// panic on error
Expand Down
2 changes: 1 addition & 1 deletion types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -1268,7 +1268,7 @@ func (data *Data) ComputeShares() (NamespacedShares, int) {
wantLen = consts.MinSharecount
}

tailShares := GenerateTailPaddingShares(wantLen-curLen, consts.ShareSize)
tailShares := TailPaddingShares(wantLen - curLen)

return append(append(append(append(
txShares,
Expand Down
2 changes: 1 addition & 1 deletion types/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ func TestNilDataAvailabilityHeaderHashDoesntCrash(t *testing.T) {
func TestEmptyBlockData(t *testing.T) {
blockData := Data{}
shares, _ := blockData.ComputeShares()
assert.Equal(t, GenerateTailPaddingShares(consts.MinSquareSize, consts.ShareSize), shares)
assert.Equal(t, TailPaddingShares(1), shares)
}

func TestCommit(t *testing.T) {
Expand Down
14 changes: 12 additions & 2 deletions types/share_splitting.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,20 @@ func getNextChunk(rawDatas [][]byte, outerIndex int, innerIndex int, width int)
return rawData, outerIndex, innerIndex, startIndex
}

func GenerateTailPaddingShares(n int, shareWidth int) NamespacedShares {
// tail is filler for all tail padded shares
// it is allocated once and used everywhere
var tailPaddingShare = append(
append(make([]byte, 0, consts.ShareSize), consts.TailPaddingNamespaceID...),
bytes.Repeat([]byte{0}, consts.ShareSize-consts.NamespaceSize)...,
)

func TailPaddingShares(n int) NamespacedShares {
shares := make([]NamespacedShare, n)
for i := 0; i < n; i++ {
shares[i] = NamespacedShare{bytes.Repeat([]byte{0}, shareWidth), consts.TailPaddingNamespaceID}
shares[i] = NamespacedShare{
Share: tailPaddingShare,
ID: consts.TailPaddingNamespaceID,
}
}
return shares
}
Expand Down

0 comments on commit 0fa5dce

Please sign in to comment.