func MinDataAvailabilityHeader() DataAvailabilityHeader {
	shares := make([][]byte, consts.MinSharecount)
	for i := 0; i < consts.MinSharecount; i++ {
		shares[i] = tailPaddingShare
	}
	eds, err := ExtendShares(consts.MinSquareSize, shares)
	if err != nil {
		panic(err)
	}
	dah := NewDataAvailabilityHeader(eds)
	return dah
}
MinDataAvailabilityHeader returns the minimum valid data availability header.
It is equal to the data availability header for an empty block
package da
import (
	"bytes"
	"errors"
	"fmt"
	"github.com/celestiaorg/rsmt2d"
	"github.com/tendermint/tendermint/crypto/merkle"
	"github.com/tendermint/tendermint/crypto/tmhash"
	"github.com/tendermint/tendermint/pkg/consts"
	"github.com/tendermint/tendermint/pkg/wrapper"
	daproto "github.com/tendermint/tendermint/proto/tendermint/da"
)
const (
	maxExtendedSquareWidth = consts.MaxSquareSize * 2
	minExtendedSquareWidth = consts.MinSquareSize * 2
)
type DataAvailabilityHeader struct {
	RowsRoots [][]byte `json:"row_roots"`
	ColumnRoots [][]byte `json:"column_roots"`
	hash []byte
}
func NewDataAvailabilityHeader(eds *rsmt2d.ExtendedDataSquare) DataAvailabilityHeader {
	dah := DataAvailabilityHeader{
		RowsRoots:   eds.RowRoots(),
		ColumnRoots: eds.ColRoots(),
	}
	dah.Hash()
	return dah
}
func ExtendShares(squareSize uint64, shares [][]byte) (*rsmt2d.ExtendedDataSquare, error) {
	if squareSize < consts.MinSquareSize || squareSize > consts.MaxSquareSize {
		return nil, fmt.Errorf(
			"invalid square size: min %d max %d provided %d",
			consts.MinSquareSize,
			consts.MaxSquareSize,
			squareSize,
		)
	}
	if squareSize*squareSize != uint64(len(shares)) {
		return nil, fmt.Errorf(
			"must provide valid number of shares for square size: got %d wanted %d",
			len(shares),
			squareSize*squareSize,
		)
	}
	tree := wrapper.NewErasuredNamespacedMerkleTree(squareSize)
	return rsmt2d.ComputeExtendedDataSquare(shares, consts.DefaultCodec(), tree.Constructor)
}
func (dah *DataAvailabilityHeader) String() string {
	if dah == nil {
		return "<nil DAHeader>"
	}
	return fmt.Sprintf("%X", dah.Hash())
}
func (dah *DataAvailabilityHeader) Equals(to *DataAvailabilityHeader) bool {
	return bytes.Equal(dah.Hash(), to.Hash())
}
func (dah *DataAvailabilityHeader) Hash() []byte {
	if dah == nil {
		return merkle.HashFromByteSlices(nil)
	}
	if len(dah.hash) != 0 {
		return dah.hash
	}
	colsCount := len(dah.ColumnRoots)
	rowsCount := len(dah.RowsRoots)
	slices := make([][]byte, colsCount+rowsCount)
	for i, rowRoot := range dah.RowsRoots {
		slices[i] = rowRoot
	}
	for i, colRoot := range dah.ColumnRoots {
		slices[i+colsCount] = colRoot
	}
	dah.hash = merkle.HashFromByteSlices(slices)
	return dah.hash
}
func (dah *DataAvailabilityHeader) ToProto() (*daproto.DataAvailabilityHeader, error) {
	if dah == nil {
		return nil, errors.New("nil DataAvailabilityHeader")
	}
	dahp := new(daproto.DataAvailabilityHeader)
	dahp.RowRoots = dah.RowsRoots
	dahp.ColumnRoots = dah.ColumnRoots
	return dahp, nil
}
func DataAvailabilityHeaderFromProto(dahp *daproto.DataAvailabilityHeader) (dah *DataAvailabilityHeader, err error) {
	if dahp == nil {
		return nil, errors.New("nil DataAvailabilityHeader")
	}
	dah = new(DataAvailabilityHeader)
	dah.RowsRoots = dahp.RowRoots
	dah.ColumnRoots = dahp.ColumnRoots
	return dah, dah.ValidateBasic()
}
func (dah *DataAvailabilityHeader) ValidateBasic() error {
	if dah == nil {
		return errors.New("nil data availability header is not valid")
	}
	if len(dah.ColumnRoots) < minExtendedSquareWidth || len(dah.RowsRoots) < minExtendedSquareWidth {
		return fmt.Errorf(
			"minimum valid DataAvailabilityHeader has at least %d row and column roots",
			minExtendedSquareWidth,
		)
	}
	if len(dah.ColumnRoots) > maxExtendedSquareWidth || len(dah.RowsRoots) > maxExtendedSquareWidth {
		return fmt.Errorf(
			"maximum valid DataAvailabilityHeader has at most %d row and column roots",
			maxExtendedSquareWidth,
		)
	}
	if len(dah.ColumnRoots) != len(dah.RowsRoots) {
		return fmt.Errorf(
			"unequal number of row and column roots: row %d col %d",
			len(dah.RowsRoots),
			len(dah.ColumnRoots),
		)
	}
	if err := validateHash(dah.hash); err != nil {
		return fmt.Errorf("wrong hash: %v", err)
	}
	return nil
}
func (dah *DataAvailabilityHeader) IsZero() bool {
	if dah == nil {
		return true
	}
	return len(dah.ColumnRoots) == 0 || len(dah.RowsRoots) == 0
}
var tailPaddingShare = append(
	append(make([]byte, 0, consts.ShareSize), consts.TailPaddingNamespaceID...),
	bytes.Repeat([]byte{0}, consts.ShareSize-consts.NamespaceSize)...,
)