-
Notifications
You must be signed in to change notification settings - Fork 258
/
blob_share_decorator.go
83 lines (71 loc) · 3.14 KB
/
blob_share_decorator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package ante
import (
"github.com/celestiaorg/celestia-app/v2/pkg/appconsts"
v1 "github.com/celestiaorg/celestia-app/v2/pkg/appconsts/v1"
blobtypes "github.com/celestiaorg/celestia-app/v2/x/blob/types"
"github.com/celestiaorg/go-square/shares"
"cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// BlobShareDecorator helps to prevent a PFB from being included in a block but
// not fitting in a data square because the number of shares occupied by the PFB
// exceeds the max number of shares available to blob data in a data square.
type BlobShareDecorator struct {
k BlobKeeper
}
func NewBlobShareDecorator(k BlobKeeper) BlobShareDecorator {
return BlobShareDecorator{k}
}
// AnteHandle implements the Cosmos SDK AnteHandler function signature. It
// returns an error if tx contains a MsgPayForBlobs where the shares occupied by
// the PFB exceeds the max number of shares in a data square.
func (d BlobShareDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
if !ctx.IsCheckTx() {
return next(ctx, tx, simulate)
}
if ctx.BlockHeader().Version.App == v1.Version {
return next(ctx, tx, simulate)
}
maxBlobShares := d.getMaxBlobShares(ctx)
for _, m := range tx.GetMsgs() {
if pfb, ok := m.(*blobtypes.MsgPayForBlobs); ok {
if sharesNeeded := getSharesNeeded(pfb.BlobSizes); sharesNeeded > maxBlobShares {
return ctx, errors.Wrapf(blobtypes.ErrBlobsTooLarge, "the number of shares occupied by blobs in this MsgPayForBlobs %d exceeds the max number of shares available for blob data %d", sharesNeeded, maxBlobShares)
}
}
}
return next(ctx, tx, simulate)
}
// getMaxBlobShares returns the max the number of shares available for blob data.
func (d BlobShareDecorator) getMaxBlobShares(ctx sdk.Context) int {
squareSize := d.getMaxSquareSize(ctx)
totalShares := squareSize * squareSize
// The PFB tx share must occupy at least one share so the number of blob shares
// is at most one less than totalShares.
blobShares := totalShares - 1
return blobShares
}
// getMaxSquareSize returns the maximum square size based on the current values
// for the governance parameter and the versioned constant.
func (d BlobShareDecorator) getMaxSquareSize(ctx sdk.Context) int {
// TODO: fix hack that forces the max square size for the first height to
// 64. This is due to our fork of the sdk not initializing state before
// BeginBlock of the first block. This is remedied in versions of the sdk
// and comet that have full support of PreparePropsoal, although
// celestia-app does not currently use those. see this PR for more details
// https://github.com/cosmos/cosmos-sdk/pull/14505
if ctx.BlockHeader().Height <= 1 {
return int(appconsts.DefaultGovMaxSquareSize)
}
upperBound := appconsts.SquareSizeUpperBound(ctx.BlockHeader().Version.App)
govParam := d.k.GovMaxSquareSize(ctx)
return min(upperBound, int(govParam))
}
// getSharesNeeded returns the total number of shares needed to represent all of
// the blobs described by blobSizes.
func getSharesNeeded(blobSizes []uint32) (sum int) {
for _, blobSize := range blobSizes {
sum += shares.SparseSharesNeeded(blobSize)
}
return sum
}