Skip to content

Commit 46d375a

Browse files
randy-croaljo242Eric-Warehime
authored
fix: RemoveSigVerificationDecorator Incarnation Cache Causing State Divergence Under Block-STM bug (#25912)
Co-authored-by: Alex | Cosmos Labs <alex@cosmoslabs.io> Co-authored-by: Eric Warehime <eric.warehime@gmail.com>
1 parent e334fa3 commit 46d375a

File tree

2 files changed

+14
-32
lines changed

2 files changed

+14
-32
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
123123
* (x/auth) [#25828](https://github.com/cosmos/cosmos-sdk/pull/25828) Limits pagination at default for values that exceed it.
124124
* (x/staking) [#25829](https://github.com/cosmos/cosmos-sdk/pull/25829) Validates case-sensitivity on authz grands in x/staking.
125125
* (mempool) [#25869](https://github.com/cosmos/cosmos-sdk/pull/25869) fix(mempool): add thread safety to NextSenderTx.
126+
* (blockstm) [#25912](https://github.com/cosmos/cosmos-sdk/pull/25912) Remove `SigVerificationDecorator` signature incarnation cache causing state divergence under blockstm.
126127
* (x/group) [#25922](https://github.com/cosmos/cosmos-sdk/pull/25922) Add zero-total-weight check for ThresholdDecisionPolicy
127128
* (x/group) [#25917](https://github.com/cosmos/cosmos-sdk/pull/25917) Prevent creation of zero-weight groups.
128129
* (x/group) [#25919](https://github.com/cosmos/cosmos-sdk/pull/25919) add safer type assertions to group `DecisionPolicy` getter calls.

x/auth/ante/sigverify.go

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ var (
3232
key = make([]byte, secp256k1.PubKeySize)
3333
simSecp256k1Pubkey = &secp256k1.PubKey{Key: key}
3434
simSecp256k1Sig [64]byte
35-
36-
SigVerificationResultCacheKey = "ante:SigVerificationResult"
3735
)
3836

3937
func init() {
@@ -305,65 +303,65 @@ func OnlyLegacyAminoSigners(sigData signing.SignatureData) bool {
305303
}
306304
}
307305

308-
func (svd SigVerificationDecorator) anteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool) error {
306+
func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
309307
sigTx, ok := tx.(authsigning.Tx)
310308
if !ok {
311-
return errorsmod.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type")
309+
return ctx, errorsmod.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type")
312310
}
313311

314312
utx, ok := tx.(sdk.TxWithUnordered)
315313
isUnordered := ok && utx.GetUnordered()
316314
unorderedEnabled := svd.ak.UnorderedTransactionsEnabled()
317315

318316
if isUnordered && !unorderedEnabled {
319-
return errorsmod.Wrap(sdkerrors.ErrNotSupported, "unordered transactions are not enabled")
317+
return ctx, errorsmod.Wrap(sdkerrors.ErrNotSupported, "unordered transactions are not enabled")
320318
}
321319

322320
// stdSigs contains the sequence number, account number, and signatures.
323321
// When simulating, this would just be a 0-length slice.
324322
sigs, err := sigTx.GetSignaturesV2()
325323
if err != nil {
326-
return err
324+
return ctx, err
327325
}
328326

329327
signers, err := sigTx.GetSigners()
330328
if err != nil {
331-
return err
329+
return ctx, err
332330
}
333331

334332
// check that signer length and signature length are the same
335333
if len(sigs) != len(signers) {
336-
return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signer; expected: %d, got %d", len(signers), len(sigs))
334+
return ctx, errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signer; expected: %d, got %d", len(signers), len(sigs))
337335
}
338336

339337
// In normal transactions, each signer has a sequence value. In unordered transactions, the nonce value is at the tx body level,
340338
// so we get one nonce value for all the signers, rather than a sequence value for each signer.
341339
// Because of this, we verify the unordered nonce outside the sigs loop, to avoid verifying the same nonce multiple times.
342340
if isUnordered {
343341
if err := svd.verifyUnorderedNonce(ctx, utx); err != nil {
344-
return err
342+
return ctx, err
345343
}
346344
}
347345

348346
for i, sig := range sigs {
349347
if sig.Sequence > 0 && isUnordered {
350-
return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "sequence is not allowed for unordered transactions")
348+
return ctx, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "sequence is not allowed for unordered transactions")
351349
}
352350
acc, err := GetSignerAcc(ctx, svd.ak, signers[i])
353351
if err != nil {
354-
return err
352+
return ctx, err
355353
}
356354

357355
// retrieve pubkey
358356
pubKey := acc.GetPubKey()
359357
if !simulate && pubKey == nil {
360-
return errorsmod.Wrap(sdkerrors.ErrInvalidPubKey, "pubkey on account is not set")
358+
return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidPubKey, "pubkey on account is not set")
361359
}
362360

363361
// Check account sequence number.
364362
if !isUnordered {
365363
if sig.Sequence != acc.GetSequence() {
366-
return errorsmod.Wrapf(
364+
return ctx, errorsmod.Wrapf(
367365
sdkerrors.ErrWrongSequence,
368366
"account sequence mismatch, expected %d, got %d", acc.GetSequence(), sig.Sequence,
369367
)
@@ -394,7 +392,7 @@ func (svd SigVerificationDecorator) anteHandle(ctx sdk.Context, tx sdk.Tx, simul
394392
}
395393
adaptableTx, ok := tx.(authsigning.V2AdaptableTx)
396394
if !ok {
397-
return fmt.Errorf("expected tx to implement V2AdaptableTx, got %T", tx)
395+
return ctx, fmt.Errorf("expected tx to implement V2AdaptableTx, got %T", tx)
398396
}
399397
txData := adaptableTx.GetSigningTxData()
400398
err = authsigning.VerifySignature(ctx, pubKey, signerData, sig.Data, svd.signModeHandler, txData)
@@ -407,28 +405,11 @@ func (svd SigVerificationDecorator) anteHandle(ctx sdk.Context, tx sdk.Tx, simul
407405
} else {
408406
errMsg = fmt.Sprintf("signature verification failed; please verify account number (%d) and chain-id (%s): (%s)", accNum, chainID, err.Error())
409407
}
410-
return errorsmod.Wrap(sdkerrors.ErrUnauthorized, errMsg)
411-
408+
return ctx, errorsmod.Wrap(sdkerrors.ErrUnauthorized, errMsg)
412409
}
413410
}
414411
}
415412

416-
return nil
417-
}
418-
419-
func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
420-
if v, ok := ctx.GetIncarnationCache(SigVerificationResultCacheKey); ok {
421-
// can't convert `nil` to interface
422-
if v != nil {
423-
err = v.(error)
424-
}
425-
} else {
426-
err = svd.anteHandle(ctx, tx, simulate)
427-
ctx.SetIncarnationCache(SigVerificationResultCacheKey, err)
428-
}
429-
if err != nil {
430-
return ctx, err
431-
}
432413
return next(ctx, tx, simulate)
433414
}
434415

0 commit comments

Comments
 (0)