diff --git a/app/prepare_proposal.go b/app/prepare_proposal.go index f77267ef15..3b6bd2cff8 100644 --- a/app/prepare_proposal.go +++ b/app/prepare_proposal.go @@ -110,7 +110,7 @@ func estimateMsgShares(txConf client.TxConfig, txs [][]byte) int { continue } - msgShares += uint64(MsgSharesUsed(int(wireMsg.MessageSize))) + msgShares += uint64(types.MsgSharesUsed(int(wireMsg.MessageSize))) } return int(msgShares) } diff --git a/app/split_shares.go b/app/split_shares.go index 263b147bdf..54c80367f4 100644 --- a/app/split_shares.go +++ b/app/split_shares.go @@ -213,7 +213,7 @@ func (sqwr *shareSplitter) hasRoomForBoth(tx, msg []byte) bool { maxTxSharesTaken := ((txBytesTaken - availableBytes) / consts.TxShareSize) + 1 // plus one becuase we have to add at least one share - maxMsgSharesTaken := MsgSharesUsed(len(msg)) + maxMsgSharesTaken := types.MsgSharesUsed(len(msg)) return currentShareCount+maxTxSharesTaken+maxMsgSharesTaken <= sqwr.maxShareCount } @@ -274,19 +274,6 @@ func (sqwr *shareSplitter) export() [][]byte { return shares } -// MsgSharesUsed calculates the minimum number of shares a message will take up. -// It accounts for the necessary delimiter and potential padding. -func MsgSharesUsed(msgSize int) int { - // add the delimiter to the message size - msgSize = types.DelimLen(uint64(msgSize)) + msgSize - shareCount := msgSize / consts.MsgShareSize - // increment the share count if the message overflows the last counted share - if msgSize%consts.MsgShareSize != 0 { - shareCount++ - } - return shareCount -} - func hasWirePayForData(tx sdk.Tx) bool { for _, msg := range tx.GetMsgs() { msgName := sdk.MsgTypeURL(msg) diff --git a/app/test/block_size_test.go b/app/test/block_size_test.go index b61056c7f6..0737c0e8a0 100644 --- a/app/test/block_size_test.go +++ b/app/test/block_size_test.go @@ -201,7 +201,7 @@ func generateSignedWirePayForDataTxs(clientCtx client.Context, txConfig client.T msg, err := types.NewWirePayForData( randomValidNamespace(), tmrand.Bytes(thisMessageSize), - AllSquareSizes(thisMessageSize)..., + types.AllSquareSizes(thisMessageSize)..., ) if err != nil { return nil, err @@ -252,39 +252,3 @@ func queryWithOutProof(clientCtx client.Context, hashHexStr string) (*rpctypes.R return node.Tx(context.Background(), hash, false) } - -// TODO: refactor these into a different package -// they will be useful for -// https://github.com/celestiaorg/celestia-app/issues/236 -// https://github.com/celestiaorg/celestia-app/issues/239 - -// generateAllSquareSizes generates and returns all of the possible square sizes -// using the maximum and minimum square sizes -func generateAllSquareSizes() []int { - sizes := []int{} - cursor := int(consts.MinSquareSize) - for cursor <= consts.MaxSquareSize { - sizes = append(sizes, cursor) - cursor *= 2 - } - return sizes -} - -// AllSquareSizes calculates all of the square sizes that message could possibly -// fit in -func AllSquareSizes(msgSize int) []uint64 { - allSizes := generateAllSquareSizes() - fitSizes := []uint64{} - shareCount := app.MsgSharesUsed(msgSize) - for _, size := range allSizes { - // if the number of shares is larger than that in the square, throw an error - // note, we use k*k-1 here because at least a single share will be reserved - // for the transaction paying for the message, therefore the max number of - // shares a message can be is number of shares in square -1. - if shareCount > (size*size)-1 { - continue - } - fitSizes = append(fitSizes, uint64(size)) - } - return fitSizes -} diff --git a/x/payment/client/cli/wirepayfordata.go b/x/payment/client/cli/wirepayfordata.go index d57f579ee6..ca250d9929 100644 --- a/x/payment/client/cli/wirepayfordata.go +++ b/x/payment/client/cli/wirepayfordata.go @@ -6,7 +6,6 @@ import ( "fmt" "github.com/spf13/cobra" - "github.com/tendermint/tendermint/pkg/consts" "github.com/celestiaorg/celestia-app/x/payment/types" "github.com/cosmos/cosmos-sdk/client" @@ -46,13 +45,7 @@ func CmdWirePayForData() *cobra.Command { return fmt.Errorf("failure to decode hex message: %w", err) } - // create the MsgPayForData - squareSizes, err := cmd.Flags().GetUintSlice(FlagSquareSizes) - if err != nil { - return err - } - squareSizes64 := parseSquareSizes(squareSizes) - pfdMsg, err := types.NewWirePayForData(namespace, message, squareSizes64...) + pfdMsg, err := types.NewWirePayForData(namespace, message, types.AllSquareSizes(len(message))...) if err != nil { return err } @@ -105,15 +98,6 @@ func CmdWirePayForData() *cobra.Command { } flags.AddTxFlagsToCmd(cmd) - cmd.Flags().UintSlice(FlagSquareSizes, []uint{consts.MaxSquareSize, 128, 64}, "Specify the square sizes, must be power of 2") return cmd } - -func parseSquareSizes(squareSizes []uint) []uint64 { - squareSizes64 := make([]uint64, len(squareSizes)) - for i := range squareSizes { - squareSizes64[i] = uint64(squareSizes[i]) - } - return squareSizes64 -} diff --git a/x/payment/client/testutil/integration_test.go b/x/payment/client/testutil/integration_test.go index 8e6f5aa9e7..9387e01ff8 100644 --- a/x/payment/client/testutil/integration_test.go +++ b/x/payment/client/testutil/integration_test.go @@ -78,23 +78,9 @@ func (s *IntegrationTestSuite) TestSubmitWirePayForData() { fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(2))).String()), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", paycli.FlagSquareSizes, "2,4,8,16"), }, false, 0, &sdk.TxResponse{}, }, - { - "invalid transaction list of square sizes", - []string{ - hexNS, - hexMsg, - fmt.Sprintf("--from=%s", username), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(2))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", paycli.FlagSquareSizes, "256,123,64"), - }, - true, 0, &sdk.TxResponse{}, - }, } for _, tc := range testCases { diff --git a/x/payment/payfordata.go b/x/payment/payfordata.go index 7be6ba38bb..f48b0241e3 100644 --- a/x/payment/payfordata.go +++ b/x/payment/payfordata.go @@ -2,6 +2,7 @@ package payment import ( "context" + "google.golang.org/grpc" sdk "github.com/cosmos/cosmos-sdk/types" @@ -12,12 +13,6 @@ import ( "github.com/celestiaorg/nmt/namespace" ) -var ( - // shareSizes includes all the possible share sizes of the given data - // that the signer must sign over. - shareSizes = []uint64{16, 32, 64, 128} -) - // SubmitPayForData constructs, signs and synchronously submits a PayForData // transaction, returning a sdk.TxResponse upon submission. func SubmitPayForData( @@ -61,7 +56,7 @@ func BuildPayForData( gasLim uint64, ) (*types.MsgWirePayForData, error) { // create the raw WirePayForData transaction - wpfd, err := types.NewWirePayForData(nID, message, shareSizes...) + wpfd, err := types.NewWirePayForData(nID, message, types.AllSquareSizes(len(message))...) if err != nil { return nil, err } diff --git a/x/payment/types/square_sizes.go b/x/payment/types/square_sizes.go new file mode 100644 index 0000000000..2239b12efc --- /dev/null +++ b/x/payment/types/square_sizes.go @@ -0,0 +1,54 @@ +package types + +import ( + "github.com/tendermint/tendermint/pkg/consts" +) + +// https://github.com/celestiaorg/celestia-app/issues/236 +// https://github.com/celestiaorg/celestia-app/issues/239 + +var allSquareSizes = generateAllSquareSizes() + +// generateAllSquareSizes generates and returns all of the possible square sizes +// using the maximum and minimum square sizes +func generateAllSquareSizes() []int { + sizes := []int{} + cursor := int(consts.MinSquareSize) + for cursor <= consts.MaxSquareSize { + sizes = append(sizes, cursor) + cursor *= 2 + } + return sizes +} + +// AllSquareSizes calculates all of the square sizes that message could possibly +// fit in +func AllSquareSizes(msgSize int) []uint64 { + allSizes := allSquareSizes + fitSizes := []uint64{} + shareCount := MsgSharesUsed(msgSize) + for _, size := range allSizes { + // if the number of shares is larger than that in the square, throw an error + // note, we use k*k-1 here because at least a single share will be reserved + // for the transaction paying for the message, therefore the max number of + // shares a message can be is number of shares in square -1. + if shareCount > (size*size)-1 { + continue + } + fitSizes = append(fitSizes, uint64(size)) + } + return fitSizes +} + +// MsgSharesUsed calculates the minimum number of shares a message will take up. +// It accounts for the necessary delimiter and potential padding. +func MsgSharesUsed(msgSize int) int { + // add the delimiter to the message size + msgSize = DelimLen(uint64(msgSize)) + msgSize + shareCount := msgSize / consts.MsgShareSize + // increment the share count if the message overflows the last counted share + if msgSize%consts.MsgShareSize != 0 { + shareCount++ + } + return shareCount +}