diff --git a/app/test/check_tx_test.go b/app/test/check_tx_test.go index 3690c918d9..38aca0bb4b 100644 --- a/app/test/check_tx_test.go +++ b/app/test/check_tx_test.go @@ -24,7 +24,7 @@ func TestCheckTx(t *testing.T) { encCfg := encoding.MakeConfig(app.ModuleEncodingRegisters...) ns1 := appns.MustNewV0(bytes.Repeat([]byte{1}, appns.NamespaceVersionZeroIDSize)) - accs := []string{"a", "b", "c", "d", "e", "f"} + accs := []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"} testApp, kr := testutil.SetupTestAppWithGenesisValSet(app.DefaultConsensusParams(), accs...) @@ -107,6 +107,54 @@ func TestCheckTx(t *testing.T) { }, expectedABCICode: abci.CodeTypeOK, }, + { + name: "1,000 byte blob", + checkType: abci.CheckTxType_New, + getTx: func() []byte { + tx := blobfactory.RandBlobTxsWithAccounts(encCfg.TxConfig.TxEncoder(), tmrand.NewRand(), kr, nil, 1_000, 1, false, testutil.ChainID, accs[4:5])[0] + return tx + }, + expectedABCICode: abci.CodeTypeOK, + }, + { + name: "10,000 byte blob", + checkType: abci.CheckTxType_New, + getTx: func() []byte { + tx := blobfactory.RandBlobTxsWithAccounts(encCfg.TxConfig.TxEncoder(), tmrand.NewRand(), kr, nil, 10_000, 1, false, testutil.ChainID, accs[5:6])[0] + return tx + }, + expectedABCICode: abci.CodeTypeOK, + }, + { + name: "100,000 byte blob", + checkType: abci.CheckTxType_New, + getTx: func() []byte { + tx := blobfactory.RandBlobTxsWithAccounts(encCfg.TxConfig.TxEncoder(), tmrand.NewRand(), kr, nil, 100_000, 1, false, testutil.ChainID, accs[6:7])[0] + return tx + }, + expectedABCICode: abci.CodeTypeOK, + }, + { + name: "1,000,000 byte blob", + checkType: abci.CheckTxType_New, + getTx: func() []byte { + tx := blobfactory.RandBlobTxsWithAccounts(encCfg.TxConfig.TxEncoder(), tmrand.NewRand(), kr, nil, 1_000_000, 1, false, testutil.ChainID, accs[7:8])[0] + return tx + }, + expectedABCICode: abci.CodeTypeOK, + }, + { + name: "10,000,000 byte blob", + checkType: abci.CheckTxType_New, + getTx: func() []byte { + tx := blobfactory.RandBlobTxsWithAccounts(encCfg.TxConfig.TxEncoder(), tmrand.NewRand(), kr, nil, 10_000_000, 1, false, testutil.ChainID, accs[8:9])[0] + return tx + }, + // TODO: consider modifying CheckTx to return an error for this case + // so that consensus nodes do not propagate blobs that are too + // large. + expectedABCICode: abci.CodeTypeOK, + }, } for _, tt := range tests { diff --git a/app/test/integration_test.go b/app/test/integration_test.go index 45e0c8d0b0..585c1b3347 100644 --- a/app/test/integration_test.go +++ b/app/test/integration_test.go @@ -14,6 +14,7 @@ import ( "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/types/errors" "github.com/stretchr/testify/suite" @@ -29,6 +30,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" abci "github.com/tendermint/tendermint/abci/types" tmrand "github.com/tendermint/tendermint/libs/rand" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" coretypes "github.com/tendermint/tendermint/types" ) @@ -374,3 +376,64 @@ func (s *IntegrationTestSuite) TestEmptyBlock() { ExtendBlobTest(t, blockRes.Block) } } + +// TestSubmitPayForBlob_blobSizes verifies the tx response ABCI code when +// SubmitPayForBlob is invoked with different blob sizes. +func (s *IntegrationTestSuite) TestSubmitPayForBlob_blobSizes() { + t := s.T() + require.NoError(t, s.cctx.WaitForBlocks(3)) + + type testCase struct { + name string + blob *tmproto.Blob + // txResponseCode is the expected tx response ABCI code. + txResponseCode uint32 + } + testCases := []testCase{ + { + name: "1,000 byte blob", + blob: mustNewBlob(t, 1_000), + txResponseCode: abci.CodeTypeOK, + }, + { + name: "10,000 byte blob", + blob: mustNewBlob(t, 10_000), + txResponseCode: abci.CodeTypeOK, + }, + { + name: "100,000 byte blob", + blob: mustNewBlob(t, 100_000), + txResponseCode: abci.CodeTypeOK, + }, + { + name: "1,000,000 byte blob", + blob: mustNewBlob(t, 1_000_000), + txResponseCode: abci.CodeTypeOK, + }, + { + name: "10,000,000 byte blob returns err tx too large", + blob: mustNewBlob(t, 10_000_000), + txResponseCode: errors.ErrTxTooLarge.ABCICode(), + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + signer := blobtypes.NewKeyringSigner(s.cctx.Keyring, s.accounts[141], s.cctx.ChainID) + options := []blobtypes.TxBuilderOption{blobtypes.SetGasLimit(1_000_000_000)} + res, err := blob.SubmitPayForBlob(context.TODO(), signer, s.cctx.GRPCClient, []*blobtypes.Blob{tc.blob}, options...) + + require.NoError(t, err) + require.NotNil(t, res) + require.Equal(t, tc.txResponseCode, res.Code, res.Logs) + }) + } +} + +func mustNewBlob(t *testing.T, blobSize int) *tmproto.Blob { + ns1 := appns.MustNewV0(bytes.Repeat([]byte{1}, appns.NamespaceVersionZeroIDSize)) + data := tmrand.Bytes(blobSize) + result, err := blobtypes.NewBlob(ns1, data, appconsts.ShareVersionZero) + require.NoError(t, err) + return result +}