Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add time to the sdk.Context used in PrepareProposal #2515

Merged
merged 9 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ test-race:
# TODO: Remove the -skip flag once the following tests no longer contain data races.
# https://github.com/celestiaorg/celestia-app/issues/1369
@echo "--> Running tests in race mode"
@go test ./... -v -race -skip "TestPrepareProposalConsistency|TestIntegrationTestSuite|TestQGBRPCQueries|TestSquareSizeIntegrationTest|TestStandardSDKIntegrationTestSuite|TestTxsimCommandFlags|TestTxsimCommandEnvVar|TestMintIntegrationTestSuite|TestQGBCLI|TestUpgrade|TestMaliciousTestNode|TestMaxTotalBlobSizeSuite|TestQGBIntegrationSuite|TestSignerTestSuite|TestPriorityTestSuite"
@go test ./... -v -race -skip "TestPrepareProposalConsistency|TestIntegrationTestSuite|TestQGBRPCQueries|TestSquareSizeIntegrationTest|TestStandardSDKIntegrationTestSuite|TestTxsimCommandFlags|TestTxsimCommandEnvVar|TestMintIntegrationTestSuite|TestQGBCLI|TestUpgrade|TestMaliciousTestNode|TestMaxTotalBlobSizeSuite|TestQGBIntegrationSuite|TestSignerTestSuite|TestPriorityTestSuite|TestTimeInPrepareProposalContext"
.PHONY: test-race

## test-bench: Run unit tests in bench mode.
Expand Down
6 changes: 5 additions & 1 deletion app/prepare_proposal.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ import (
func (app *App) PrepareProposal(req abci.RequestPrepareProposal) abci.ResponsePrepareProposal {
// create a context using a branch of the state and loaded using the
// proposal height and chain-id
sdkCtx := app.NewProposalContext(core.Header{ChainID: req.ChainId, Height: app.LastBlockHeight() + 1})
sdkCtx := app.NewProposalContext(core.Header{
ChainID: req.ChainId,
Height: req.Height,
Time: req.Time,
})
// filter out invalid transactions.
// TODO: we can remove all state independent checks from the ante handler here such as signature verification
// and only check the state dependent checks like fees and nonces as all these transactions have already
Expand Down
9 changes: 8 additions & 1 deletion app/test/fuzz_abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package app_test

import (
"testing"
"time"

"github.com/celestiaorg/celestia-app/app"
"github.com/celestiaorg/celestia-app/app/encoding"
Expand Down Expand Up @@ -115,11 +116,17 @@ func TestPrepareProposalConsistency(t *testing.T) {
testutil.ChainID,
)
txs = append(txs, sendTxs...)

blockTime := time.Now()
height := testApp.LastBlockHeight() + 1

resp := testApp.PrepareProposal(abci.RequestPrepareProposal{
BlockData: &core.Data{
Txs: coretypes.Txs(txs).ToSliceOfBytes(),
},
ChainId: testutil.ChainID,
Time: blockTime,
Height: height,
})

// check that the square size is smaller than or equal to
Expand All @@ -132,7 +139,7 @@ func TestPrepareProposalConsistency(t *testing.T) {
DataHash: resp.BlockData.Hash,
ChainID: testutil.ChainID,
Version: version.Consensus{App: appconsts.LatestVersion},
Height: testApp.LastBlockHeight() + 1,
Height: height,
},
},
)
Expand Down
100 changes: 100 additions & 0 deletions app/test/prepare_proposal_context_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package app_test

import (
"testing"
"time"

"github.com/celestiaorg/celestia-app/app"
"github.com/celestiaorg/celestia-app/app/encoding"
"github.com/celestiaorg/celestia-app/pkg/user"
"github.com/celestiaorg/celestia-app/test/util/testfactory"
"github.com/celestiaorg/celestia-app/test/util/testnode"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types"
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
tmrand "github.com/tendermint/tendermint/libs/rand"
)

// TestTimeInPrepareProposalContext checks for an edge case where the block time
// needs to be included in the sdk.Context that is being used in the
// antehandlers. If a time is not included in the context, then the second
// transaction in this test will always be filtered out, result in vesting
// accounts never being able to spend funds.
func TestTimeInPrepareProposalContext(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like we defer to using integration tests too often when unit tests would suffice

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if testing.Short() {
Comment on lines +23 to +29
Copy link
Member Author

@evan-forbes evan-forbes Sep 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could have included this in the standard cosmos-sdk test that we're already running, however since the tx needs to be second it felt a bit too hacky to do that

t.Skip("skipping TestTimeInPrepareProposalContext test in short mode.")
}
accounts := make([]string, 35)
for i := 0; i < len(accounts); i++ {
accounts[i] = tmrand.Str(9)
}
cfg := testnode.DefaultConfig().WithAccounts(accounts)
cctx, _, _ := testnode.NewNetwork(t, cfg)
ecfg := encoding.MakeConfig(app.ModuleEncodingRegisters...)
vestAccName := "vesting"
type test struct {
name string
msgFunc func() (msgs []sdk.Msg, signer string)
expectedCode uint32
}
tests := []test{
{
name: "create continuous vesting account with a start time in the future",
msgFunc: func() (msgs []sdk.Msg, signer string) {
_, _, err := cctx.Keyring.NewMnemonic(vestAccName, keyring.English, "", "", hd.Secp256k1)
require.NoError(t, err)
sendAcc := accounts[0]
sendingAccAddr := testfactory.GetAddress(cctx.Keyring, sendAcc)
vestAccAddr := testfactory.GetAddress(cctx.Keyring, vestAccName)
msg := vestingtypes.NewMsgCreateVestingAccount(
sendingAccAddr,
vestAccAddr,
sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(1000000))),
time.Now().Unix(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a start time in the future as is stated in the test name

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will grab this in a followup

time.Now().Add(time.Second*100).Unix(),
false,
)
return []sdk.Msg{msg}, sendAcc
},
expectedCode: abci.CodeTypeOK,
},
{
name: "send funds from the vesting account after it has been created",
msgFunc: func() (msgs []sdk.Msg, signer string) {
sendAcc := accounts[1]
sendingAccAddr := testfactory.GetAddress(cctx.Keyring, sendAcc)
vestAccAddr := testfactory.GetAddress(cctx.Keyring, vestAccName)
msg := banktypes.NewMsgSend(
vestAccAddr,
sendingAccAddr,
sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(1))),
)
return []sdk.Msg{msg}, vestAccName
},
expectedCode: abci.CodeTypeOK,
},
}
Comment on lines +46 to +81
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one additional test we can do is to have a third test case where we attempt to send too much and expect it to fail. I have a commit with this ready, however I'm worried that it will cause flakiness do to the process requiring a specific time delay window.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it will be flaky if you set the end time well in the future and try send all the funds

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well in the future and try send all the funds

yeah good point, sorry I was not clear enough. the thing that I was trying to test with the additional case here was not just that a tx would fail if there was not enough of a spendable balance, I think we have that somehwere already (#2004 iirc). That wouldn't be flakey.

I was trying to create a test that checks that puts us in the exact scenario we would get in if we used time.Now(). Where a tx doesn't get filtered but is invalid.


// sign and submit the transactions
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
msgs, account := tt.msgFunc()
addr := testfactory.GetAddress(cctx.Keyring, account)
signer, err := user.SetupSigner(cctx.GoContext(), cctx.Keyring, cctx.GRPCClient, addr, ecfg)
require.NoError(t, err)
res, err := signer.SubmitTx(cctx.GoContext(), msgs, user.SetGasLimit(1000000), user.SetFee(1))
if tt.expectedCode != abci.CodeTypeOK {
require.Error(t, err)
} else {
require.NoError(t, err)
}
require.NotNil(t, res)
assert.Equal(t, tt.expectedCode, res.Code, res.RawLog)
})
}
}
11 changes: 11 additions & 0 deletions app/test/prepare_proposal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package app_test

import (
"testing"
"time"

tmrand "github.com/tendermint/tendermint/libs/rand"

Expand Down Expand Up @@ -56,11 +57,16 @@ func TestPrepareProposalPutsPFBsAtEnd(t *testing.T) {
)
txs := append(blobTxs, coretypes.Txs(normalTxs).ToSliceOfBytes()...)

height := testApp.LastBlockHeight() + 1
blockTime := time.Now()

resp := testApp.PrepareProposal(abci.RequestPrepareProposal{
BlockData: &tmproto.Data{
Txs: txs,
},
ChainId: testutil.ChainID,
Height: height,
Time: blockTime,
})
require.Len(t, resp.BlockData.Txs, numBlobTxs+numNormalTxs)
for idx, txBytes := range resp.BlockData.Txs {
Expand Down Expand Up @@ -182,9 +188,14 @@ func TestPrepareProposalFiltering(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
height := testApp.LastBlockHeight() + 1
blockTime := time.Now()

resp := testApp.PrepareProposal(abci.RequestPrepareProposal{
BlockData: &tmproto.Data{Txs: tt.txs()},
ChainId: testutil.ChainID,
Height: height,
Time: blockTime,
})
// check that we have the expected number of transactions
require.Equal(t, len(tt.txs())-len(tt.prunedTxs), len(resp.BlockData.Txs))
Expand Down
6 changes: 6 additions & 0 deletions app/test/process_proposal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -299,9 +300,14 @@ func TestProcessProposal(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
height := testApp.LastBlockHeight() + 1
blockTime := time.Now()

resp := testApp.PrepareProposal(abci.RequestPrepareProposal{
BlockData: tt.input,
ChainId: testutil.ChainID,
Height: height,
Time: blockTime,
})
require.Equal(t, len(tt.input.Txs), len(resp.BlockData.Txs))
tt.mutator(resp.BlockData)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -245,5 +245,5 @@ replace (
github.com/cosmos/cosmos-sdk => github.com/celestiaorg/cosmos-sdk v1.18.0-sdk-v0.46.14
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
github.com/tendermint/tendermint => github.com/celestiaorg/celestia-core v1.26.2-tm-v0.34.28
github.com/tendermint/tendermint => github.com/celestiaorg/celestia-core v1.27.0-tm-v0.34.28
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ github.com/bufbuild/protocompile v0.1.0/go.mod h1:ix/MMMdsT3fzxfw91dvbfzKW3fRRnu
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/celestiaorg/celestia-core v1.26.2-tm-v0.34.28 h1:2efXQaggLFknz0wQufr4nUEz5G7pSVHS1j7NuJDsvII=
github.com/celestiaorg/celestia-core v1.26.2-tm-v0.34.28/go.mod h1:++dNzzzjP9jYg+NopN9G8sg1HEZ58lv1TPtg71evZ0E=
github.com/celestiaorg/celestia-core v1.27.0-tm-v0.34.28 h1:BE7JFZ1SYpwM9OfL9cPcjlO5xjIbDPgdFkJNouyl6jA=
github.com/celestiaorg/celestia-core v1.27.0-tm-v0.34.28/go.mod h1:1GT0RfdNqOXvyR3Hq4ROcNBknQNz9E6K5l3Cla9eFFk=
github.com/celestiaorg/cosmos-sdk v1.18.0-sdk-v0.46.14 h1:dDfoQJOlVNj4HufJ1lBLTo2k3/L/255MIiKmEQziDmw=
github.com/celestiaorg/cosmos-sdk v1.18.0-sdk-v0.46.14/go.mod h1:kkdiHo/zG6ar80730+bG1owdMAQXrGp4utFu7mbfADo=
github.com/celestiaorg/knuu v0.8.2 h1:x63nYTO46j293VkNP7VcRHtYHSize6dM/h7xME2Vgi0=
Expand Down