Skip to content

Commit

Permalink
update: check if gas should be added
Browse files Browse the repository at this point in the history
  • Loading branch information
JulianToledano committed Jun 25, 2024
1 parent f1544b2 commit 6051619
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 13 deletions.
82 changes: 79 additions & 3 deletions baseapp/abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -774,10 +774,9 @@ func anyMessage(t *testing.T, cdc codec.Codec, msg *baseapptestutil.MsgSend) *an
}

func TestABCI_Query_SimulateNestedMessagesTx(t *testing.T) {
gasConsumed := uint64(5)
anteOpt := func(bapp *baseapp.BaseApp) {
bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) {
newCtx = ctx.WithGasMeter(storetypes.NewGasMeter(gasConsumed))
newCtx = ctx.WithGasMeter(storetypes.NewGasMeter(uint64(15)))
return
})
}
Expand Down Expand Up @@ -854,7 +853,6 @@ func TestABCI_Query_SimulateNestedMessagesTx(t *testing.T) {
}),
},
},
wantErr: false,
},
{
name: "with invalid nested messages",
Expand Down Expand Up @@ -921,6 +919,84 @@ func TestABCI_Query_SimulateNestedMessagesTx(t *testing.T) {
}
}

func TestABCI_Query_SimulateNestedMessagesGas(t *testing.T) {
anteOpt := func(bapp *baseapp.BaseApp) {
bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) {
newCtx = ctx.WithGasMeter(storetypes.NewGasMeter(uint64(10)))
return
})
}

_, _, addr := testdata.KeyTestPubAddr()
_, _, toAddr := testdata.KeyTestPubAddr()

tests := []struct {
name string
suite *BaseAppSuite
message sdk.Msg
consumedGas uint64
}{
{
name: "add gas",
suite: NewBaseAppSuite(t, anteOpt),
message: &baseapptestutil.MsgSend{
From: addr.String(),
To: toAddr.String(),
Amount: "10000stake",
},
consumedGas: 10,
},
{
name: "don't add gas",
suite: NewBaseAppSuite(t, anteOpt, baseapp.SetExcludeNestedMsgsGas([]sdk.Msg{&baseapptestutil.MsgNestedMessages{}})),
message: &baseapptestutil.MsgSend{
From: addr.String(),
To: toAddr.String(),
Amount: "10000stake",
},
consumedGas: 5,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := tt.suite.baseApp.InitChain(&abci.InitChainRequest{
ConsensusParams: &cmtproto.ConsensusParams{},
})
require.NoError(t, err)

baseapptestutil.RegisterNestedMessagesServer(tt.suite.baseApp.MsgServiceRouter(), NestedMessgesServerImpl{})
baseapptestutil.RegisterSendServer(tt.suite.baseApp.MsgServiceRouter(), SendServerImpl{})

nestedMessages := make([]*any.Any, 1)
b, err := tt.suite.cdc.Marshal(tt.message)
require.NoError(t, err)
nestedMessages[0] = &any.Any{
TypeUrl: sdk.MsgTypeURL(tt.message),
Value: b,
}

msg := &baseapptestutil.MsgNestedMessages{
Messages: nestedMessages,
Signer: addr.String(),
}

builder := tt.suite.txConfig.NewTxBuilder()
err = builder.SetMsgs(msg)
require.NoError(t, err)
setTxSignature(t, builder, 0)
tx := builder.GetTx()

txBytes, err := tt.suite.txConfig.TxEncoder()(tx)
require.Nil(t, err)

gas, result, err := tt.suite.baseApp.Simulate(txBytes)
require.NoError(t, err)
require.NotNil(t, result)
require.True(t, gas.GasUsed == tt.consumedGas)
})
}
}

func TestABCI_Query_SimulateTx(t *testing.T) {
gasConsumed := uint64(5)
anteOpt := func(bapp *baseapp.BaseApp) {
Expand Down
14 changes: 11 additions & 3 deletions baseapp/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ type BaseApp struct {
// including the goroutine handling.This is experimental and must be enabled
// by developers.
optimisticExec *oe.OptimisticExecution

// excludeNestedMsgsGas holds a set of message types for which gas costs for its nested messages are not calculated.
excludeNestedMsgsGas map[string]struct{}
}

// NewBaseApp returns a reference to an initialized BaseApp. It accepts a
Expand Down Expand Up @@ -236,7 +239,9 @@ func NewBaseApp(
if app.interBlockCache != nil {
app.cms.SetInterBlockCache(app.interBlockCache)
}

if app.excludeNestedMsgsGas == nil {
app.excludeNestedMsgsGas = make(map[string]struct{})
}
app.runTxRecoveryMiddleware = newDefaultRecoveryMiddleware()

// Initialize with an empty interface registry to avoid nil pointer dereference.
Expand Down Expand Up @@ -963,12 +968,15 @@ func (app *BaseApp) runTx(mode execMode, txBytes []byte) (gInfo sdk.GasInfo, res
}

if mode == execModeSimulate {
nestedMsgsContext, _ := app.cacheTxContext(ctx, txBytes)
gas := ctx.GasMeter().GasConsumed()
for _, msg := range msgs {
nestedErr := app.simulateNestedMessages(nestedMsgsContext, msg)
nestedErr := app.simulateNestedMessages(ctx, msg)
if nestedErr != nil {
return gInfo, nil, anteEvents, nestedErr
}
if _, ok := app.excludeNestedMsgsGas[sdk.MsgTypeURL(msg)]; ok {
ctx.GasMeter().RefundGas(ctx.GasMeter().GasConsumed()-gas, "simulation of nested messages")
}
}
}

Expand Down
13 changes: 13 additions & 0 deletions baseapp/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,19 @@ func SetOptimisticExecution(opts ...func(*oe.OptimisticExecution)) func(*BaseApp
}
}

// SetExcludeNestedMsgsGas sets the message types for which gas costs for its nested messages are not calculated when simulating.
func SetExcludeNestedMsgsGas(msgs []sdk.Msg) func(*BaseApp) {
return func(app *BaseApp) {
app.excludeNestedMsgsGas = make(map[string]struct{})
for _, msg := range msgs {
if _, ok := msg.(HasNestedMsgs); !ok {
continue
}
app.excludeNestedMsgsGas[sdk.MsgTypeURL(msg)] = struct{}{}
}
}
}

func (app *BaseApp) SetName(name string) {
if app.sealed {
panic("SetName() on sealed BaseApp")
Expand Down
24 changes: 20 additions & 4 deletions baseapp/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,9 +377,12 @@ func wonkyMsg(t *testing.T, cfg client.TxConfig, tx signing.Tx) signing.Tx {
return builder.GetTx()
}

type SendServerImpl struct{}
type SendServerImpl struct {
gas uint64
}

func (s SendServerImpl) Send(ctx context.Context, send *baseapptestutil.MsgSend) (*baseapptestutil.MsgSendResponse, error) {
sdkCtx := sdk.UnwrapSDKContext(ctx)
if send.From == "" {
return nil, errors.New("from address cannot be empty")
}
Expand All @@ -391,13 +394,20 @@ func (s SendServerImpl) Send(ctx context.Context, send *baseapptestutil.MsgSend)
if err != nil {
return nil, err
}

gas := s.gas
if gas == 0 {
gas = 5
}
sdkCtx.GasMeter().ConsumeGas(gas, "send test")
return &baseapptestutil.MsgSendResponse{}, nil
}

type NestedMessgesServerImpl struct{}
type NestedMessgesServerImpl struct {
gas uint64
}

func (n NestedMessgesServerImpl) Check(_ context.Context, message *baseapptestutil.MsgNestedMessages) (*baseapptestutil.MsgCreateNestedMessagesResponse, error) {
func (n NestedMessgesServerImpl) Check(ctx context.Context, message *baseapptestutil.MsgNestedMessages) (*baseapptestutil.MsgCreateNestedMessagesResponse, error) {
sdkCtx := sdk.UnwrapSDKContext(ctx)
cdc := codectestutil.CodecOptions{}.NewCodec()
baseapptestutil.RegisterInterfaces(cdc.InterfaceRegistry())

Expand Down Expand Up @@ -427,5 +437,11 @@ func (n NestedMessgesServerImpl) Check(_ context.Context, message *baseapptestut
}

}

gas := n.gas
if gas == 0 {
gas = 5
}
sdkCtx.GasMeter().ConsumeGas(gas, "nested messages test")
return nil, nil
}
3 changes: 2 additions & 1 deletion simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,8 @@ func NewSimApp(
voteExtHandler := NewVoteExtensionHandler()
voteExtHandler.SetHandlers(bApp)
}
baseAppOptions = append(baseAppOptions, voteExtOp, baseapp.SetOptimisticExecution())
baseAppOptions = append(baseAppOptions, voteExtOp, baseapp.SetOptimisticExecution(),
baseapp.SetExcludeNestedMsgsGas(govkeeper.DefaultConfig().ExcludedNestedMsgsForGasSim))

bApp := baseapp.NewBaseApp(appName, logger, db, txConfig.TxDecoder(), baseAppOptions...)
bApp.SetCommitMultiStoreTracer(traceStore)
Expand Down
4 changes: 2 additions & 2 deletions simapp/app_di.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ func NewSimApp(
appOpts,
// supply the logger
logger,

// ADVANCED CONFIGURATION

//
Expand Down Expand Up @@ -239,7 +238,8 @@ func NewSimApp(
voteExtHandler := NewVoteExtensionHandler()
voteExtHandler.SetHandlers(bApp)
}
baseAppOptions = append(baseAppOptions, voteExtOp, baseapp.SetOptimisticExecution())
baseAppOptions = append(baseAppOptions, voteExtOp, baseapp.SetOptimisticExecution(),
baseapp.SetExcludeNestedMsgsGas(govkeeper.DefaultConfig().ExcludedNestedMsgsForGasSim))

app.App = appBuilder.Build(db, traceStore, baseAppOptions...)

Expand Down
4 changes: 4 additions & 0 deletions x/gov/keeper/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package keeper
import (
"context"

"cosmossdk.io/core/transaction"
"cosmossdk.io/math"
v1 "cosmossdk.io/x/gov/types/v1"
)
Expand Down Expand Up @@ -33,6 +34,8 @@ type Config struct {
// CalculateVoteResultsAndVotingPowerFn is a function signature for calculating vote results and voting power
// Keeping it nil will use the default implementation
CalculateVoteResultsAndVotingPowerFn CalculateVoteResultsAndVotingPowerFn
// ExcludedNestedMsgsForGasSim is a list of messages that will avoid adding the gas of their nested messages when simulating
ExcludedNestedMsgsForGasSim []transaction.Msg
}

// DefaultConfig returns the default config for gov.
Expand All @@ -43,5 +46,6 @@ func DefaultConfig() Config {
MaxSummaryLen: 10200,
MaxVoteOptionsLen: 0, // 0 means this param is disabled, hence all supported options are allowed
CalculateVoteResultsAndVotingPowerFn: nil,
ExcludedNestedMsgsForGasSim: []transaction.Msg{&v1.MsgSubmitProposal{}},
}
}

0 comments on commit 6051619

Please sign in to comment.