Skip to content

Commit 4bc3c0c

Browse files
committed
fix: drop signature gas consumption from the gasless new-account path
Gasless txs skip fee deduction entirely, so charging gas has no economic effect. The TxSigLimit cap alone bounds the multisig work; reverts the NewAccountInitDecorator signature change and the SigGasConsumer wiring.
1 parent 6411203 commit 4bc3c0c

4 files changed

Lines changed: 12 additions & 35 deletions

File tree

app/ante/account_init_decorator.go

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,37 +9,24 @@ import (
99
"google.golang.org/protobuf/types/known/anypb"
1010

1111
errorsmod "cosmossdk.io/errors"
12-
storetypes "cosmossdk.io/store/types"
1312
txsigning "cosmossdk.io/x/tx/signing"
1413
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
1514
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
1615
"github.com/cosmos/cosmos-sdk/types/tx/signing"
1716
"github.com/cosmos/cosmos-sdk/x/auth/ante"
1817
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
19-
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
2018
txpolicy "github.com/pushchain/push-chain-node/app/txpolicy"
2119
)
2220

2321
type AccountInitDecorator struct {
2422
ak AccountKeeper
2523
signModeHandler *txsigning.HandlerMap
26-
sigGasConsumer SignatureVerificationGasConsumer
2724
}
2825

29-
// SignatureVerificationGasConsumer charges gas for a single signature, matching
30-
// the ante.SignatureVerificationGasConsumer contract used by the SDK's
31-
// SigGasConsumeDecorator.
32-
type SignatureVerificationGasConsumer func(meter storetypes.GasMeter, sig signing.SignatureV2, params authtypes.Params) error
33-
34-
func NewAccountInitDecorator(ak AccountKeeper, signModeHandler *txsigning.HandlerMap, sigGasConsumer SignatureVerificationGasConsumer) AccountInitDecorator {
35-
if sigGasConsumer == nil {
36-
sigGasConsumer = ante.DefaultSigVerificationGasConsumer
37-
}
38-
26+
func NewAccountInitDecorator(ak AccountKeeper, signModeHandler *txsigning.HandlerMap) AccountInitDecorator {
3927
return AccountInitDecorator{
4028
ak: ak,
4129
signModeHandler: signModeHandler,
42-
sigGasConsumer: sigGasConsumer,
4330
}
4431
}
4532

@@ -122,9 +109,11 @@ func (aid AccountInitDecorator) verifySignatureForNewAccount(ctx sdk.Context, tx
122109

123110
// Enforce the signature count limit before doing any verification work.
124111
// This decorator short-circuits the ante chain for new accounts, so
125-
// ante.ValidateSigCountDecorator never runs for them; without this an
126-
// unpriced gasless tx could carry an arbitrarily large multisig key and
127-
// force the node to verify every sub-signature for free.
112+
// ante.ValidateSigCountDecorator never runs for them; without this hard cap
113+
// a gasless tx could carry an arbitrarily large multisig key and force the
114+
// node to verify every sub-signature. Gas is deliberately NOT consumed here:
115+
// gasless txs skip fee deduction entirely, so charging gas would cost an
116+
// attacker nothing - the count cap is what actually bounds the work.
128117
sigCount := 0
129118
for _, sig := range sigs {
130119
if sig.PubKey == nil {
@@ -162,16 +151,6 @@ func (aid AccountInitDecorator) verifySignatureForNewAccount(ctx sdk.Context, tx
162151
"pubKey does not match signer address %s with signer index: %d", sdk.AccAddress(signers[i]).String(), i)
163152
}
164153

165-
// Charge gas for the signature, as ante.SigGasConsumeDecorator would
166-
// have done had the ante chain not been short-circuited.
167-
if err := aid.sigGasConsumer(ctx.GasMeter(), signing.SignatureV2{
168-
PubKey: pubKey,
169-
Data: sig.Data,
170-
Sequence: sig.Sequence,
171-
}, params); err != nil {
172-
return err
173-
}
174-
175154
// retrieve signer data
176155
chainID := ctx.ChainID()
177156
var accSequence uint64 = 0

app/ante/account_init_decorator_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
// gasless message type list).
1919
func TestAccountInitDecorator_NonGaslessTxPassesThrough(t *testing.T) {
2020
ak := newMockAccountKeeperAnte(sdk.AccAddress([]byte("feeCollector")))
21-
aid := ante.NewAccountInitDecorator(ak, nil /*signModeHandler not needed for non-gasless*/, nil)
21+
aid := ante.NewAccountInitDecorator(ak, nil /*signModeHandler not needed for non-gasless*/)
2222

2323
// banktypes.MsgSend is not gasless.
2424
tx := mockFeeTx{
@@ -45,7 +45,7 @@ func TestAccountInitDecorator_GaslessTxExistingAccountPassesThrough(t *testing.T
4545
// Pre-register the account.
4646
ak.SetAccount(context.Background(), authtypes.NewBaseAccountWithAddress(existingAddr))
4747

48-
aid := ante.NewAccountInitDecorator(ak, nil, nil)
48+
aid := ante.NewAccountInitDecorator(ak, nil)
4949

5050
// Use a non-authsigning tx — the decorator skips signature verification
5151
// for existing accounts only when it can parse signers. Since mockFeeTx doesn't
@@ -76,7 +76,7 @@ func TestAccountInitDecorator_GaslessTxExistingAccountPassesThrough(t *testing.T
7676
// tx that does not implement authsigning.Tx is rejected with ErrTxDecode.
7777
func TestAccountInitDecorator_NonAuthSigningTxReturnsError(t *testing.T) {
7878
ak := newMockAccountKeeperAnte(sdk.AccAddress([]byte("feeCollector")))
79-
aid := ante.NewAccountInitDecorator(ak, nil, nil)
79+
aid := ante.NewAccountInitDecorator(ak, nil)
8080

8181
// MsgVoteInbound is gasless.
8282
tx := mockFeeTx{

app/ante/account_init_signer_binding_test.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818
"github.com/cosmos/cosmos-sdk/types/tx/signing"
1919
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
2020
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
21-
cosmosevmante "github.com/cosmos/evm/ante"
2221

2322
"github.com/pushchain/push-chain-node/app/ante"
2423
appparams "github.com/pushchain/push-chain-node/app/params"
@@ -142,7 +141,7 @@ func buildSignedTx(t *testing.T, encCfg appparams.EncodingConfig, msg sdk.Msg, d
142141
func newSignerBindingDecorator(t *testing.T, encCfg appparams.EncodingConfig) (ante.AccountInitDecorator, *mockAccountKeeperAnte) {
143142
t.Helper()
144143
ak := newMockAccountKeeperAnte(sdk.AccAddress([]byte("feeCollector")))
145-
return ante.NewAccountInitDecorator(ak, encCfg.TxConfig.SignModeHandler(), cosmosevmante.SigVerificationGasConsumer), ak
144+
return ante.NewAccountInitDecorator(ak, encCfg.TxConfig.SignModeHandler()), ak
146145
}
147146

148147
// TestAccountInitDecorator_RejectsAliasedModuleSigner is the regression test for
@@ -297,4 +296,3 @@ func TestAccountInitDecorator_EnforcesSignatureLimit(t *testing.T) {
297296
require.True(t, sdkerrors.ErrTooManySignatures.Is(err), "expected ErrTooManySignatures, got: %v", err)
298297
require.False(t, ak.HasAccount(context.Background(), signer))
299298
}
300-

app/ante/ante_cosmos.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ func NewCosmosAnteHandler(ctx sdk.Context, options HandlerOptions) sdk.AnteHandl
4444
// - this
4545
// 1. generates the account for the new accounts only for gasless transactions,
4646
// 2. binds the declared signer to the signing key, enforces the signature
47-
// count limit, charges signature gas and verifies the sig, and
47+
// count limit and verifies the sig, and
4848
// 3. bypasses the rest of the ante chain
49-
NewAccountInitDecorator(options.AccountKeeper, options.SignModeHandler, options.SigGasConsumer),
49+
NewAccountInitDecorator(options.AccountKeeper, options.SignModeHandler),
5050
// SetPubKeyDecorator must be called before all signature verification decorators
5151
ante.NewSetPubKeyDecorator(options.AccountKeeper),
5252
ante.NewValidateSigCountDecorator(options.AccountKeeper),

0 commit comments

Comments
 (0)