fix: use contents of the tx as identifier in cache (#20533)

Co-authored-by: Alexander Peters <alpe@users.noreply.github.com>
This commit is contained in:
Marko 2024-07-15 11:40:41 +02:00 committed by GitHub
parent e3ea68aa1a
commit 2cf378174d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 207 additions and 55 deletions

View File

@ -361,6 +361,7 @@ func (f Factory) BuildUnsignedTx(msgs ...sdk.Msg) (client.TxBuilder, error) {
tx.SetFeeGranter(f.feeGranter)
tx.SetFeePayer(f.feePayer)
tx.SetTimeoutHeight(f.TimeoutHeight())
tx.SetUnordered(f.Unordered())
if etx, ok := tx.(client.ExtendedTxBuilder); ok {
etx.SetExtensionOptions(f.extOptions...)

View File

@ -9,11 +9,8 @@ require (
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91
cosmossdk.io/x/gov v0.0.0-20231113122742-912390d5fc4a
cosmossdk.io/x/tx v0.13.3
github.com/chzyer/readline v1.5.1 // indirect
github.com/cockroachdb/errors v1.11.1 // indirect
github.com/cosmos/cosmos-proto v1.0.0-beta.5
github.com/cosmos/cosmos-sdk v0.51.0
github.com/manifoldco/promptui v0.9.0 // indirect
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
google.golang.org/grpc v1.64.1
@ -43,6 +40,8 @@ require (
github.com/bgentry/speakeasy v0.2.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.3 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chzyer/readline v1.5.1 // indirect
github.com/cockroachdb/errors v1.11.1 // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/pebble v1.1.0 // indirect
github.com/cockroachdb/redact v1.1.5 // indirect
@ -113,6 +112,7 @@ require (
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/linxGnu/grocksdb v1.8.14 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/manifoldco/promptui v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/minio/highwayhash v1.0.2 // indirect

View File

@ -235,7 +235,6 @@ func ProvideModuleC(key StoreKey, b KeeperB) KeeperC {
type keeperC struct {
key StoreKey
b KeeperB
}
type KeeperC interface {

View File

@ -261,15 +261,35 @@ func (d *DedupTxDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool,
return nil, errorsmod.Wrapf(sdkerrors.ErrLogic, "unordered tx ttl exceeds %d", d.maxUnOrderedTTL)
}
// check for duplicates
if d.m.Contains(tx.Hash()) {
return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "tx is duplicated")
}
// in order to create a deterministic hash based on the tx, we need to hash the contents of the tx with signature
// Get a Buffer from the pool
buf := bufPool.Get().(*bytes.Buffer)
// Make sure to reset the buffer
buf.Reset()
if !ctx.IsCheckTx() {
// a new tx included in the block, add the hash to the unordered tx manager
d.m.Add(tx.Hash(), tx.TimeoutHeight())
}
// Use the buffer
for _, msg := range tx.GetMsgs() {
// loop through the messages and write them to the buffer
// encoding the msg to bytes makes it deterministic within the state machine.
// Malleability is not a concern here because the state machine will encode the transaction deterministically.
bz, err := proto.Marshal(msg)
if err != nil {
return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "failed to marshal message")
}
buf.Write(bz)
}
// check for duplicates
// check for duplicates
if d.txManager.Contains(txHash) {
return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "tx %X is duplicated")
}
if d.env.TransactionService.ExecMode(ctx) == transaction.ExecModeFinalize {
// a new tx included in the block, add the hash to the unordered tx manager
d.txManager.Add(txHash, ttl)
}
return next(ctx, tx, simulate)
}
@ -282,10 +302,7 @@ encoding is not malleable. If a given transaction, which is otherwise valid, can
be encoded to produce different hashes, which reflect the same valid transaction,
then a duplicate unordered transaction can be submitted and included in a block.
In order to prevent this, transactions should be encoded in a deterministic manner.
[ADR-027](./adr-027-deterministic-protobuf-serialization.md) provides such a mechanism.
However, it is important to note that the way a transaction is signed should ensure
ADR-027 is followed. E.g. we want to avoid Amino signing.
In order to prevent this, the decoded transaction contents is taken. Starting with the content of the transaction we marshal the transaction in order to prevent a client reordering the transaction. Next we include the gas and timeout height as part of the identifier. All these fields are signed over in the transaction payload. If one of them changes the signature will not match the transaction.
### State Management

View File

@ -39,7 +39,7 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker),
ante.NewValidateBasicDecorator(options.Environment),
ante.NewTxTimeoutHeightDecorator(options.Environment),
ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, options.TxManager, options.Environment),
ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, options.TxManager, options.Environment, ante.DefaultSha256Cost),
ante.NewValidateMemoDecorator(options.AccountKeeper),
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker),

View File

@ -9,8 +9,8 @@ import (
"github.com/stretchr/testify/suite"
"cosmossdk.io/core/header"
"cosmossdk.io/core/log"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
_ "cosmossdk.io/x/accounts" // import as blank for app wiring
_ "cosmossdk.io/x/auth" // import as blank for app wiring
authkeeper "cosmossdk.io/x/auth/keeper"

View File

@ -44,7 +44,7 @@ type TestnetInitializer interface {
type SystemUnderTest struct {
execBinary string
blockListener *EventListener
currentHeight int64
currentHeight atomic.Int64
outputDir string
testnetInitializer TestnetInitializer
@ -164,7 +164,7 @@ func (s *SystemUnderTest) StartChain(t *testing.T, xargs ...string) {
s.blockListener.Subscribe("tm.event='NewBlock'", func(e ctypes.ResultEvent) (more bool) {
newBlock, ok := e.Data.(tmtypes.EventDataNewBlock)
require.True(t, ok, "unexpected type %T", e.Data)
atomic.StoreInt64(&s.currentHeight, newBlock.Block.Height)
s.currentHeight.Store(newBlock.Block.Height)
return true
}),
)
@ -362,12 +362,12 @@ func (s *SystemUnderTest) PrintBuffer() {
// AwaitBlockHeight blocks until te target height is reached. An optional timeout parameter can be passed to abort early
func (s *SystemUnderTest) AwaitBlockHeight(t *testing.T, targetHeight int64, timeout ...time.Duration) {
t.Helper()
require.Greater(t, targetHeight, s.currentHeight)
require.Greater(t, targetHeight, s.currentHeight.Load())
var maxWaitTime time.Duration
if len(timeout) != 0 {
maxWaitTime = timeout[0]
} else {
maxWaitTime = time.Duration(targetHeight-s.currentHeight+3) * s.blockTime
maxWaitTime = time.Duration(targetHeight-s.currentHeight.Load()+3) * s.blockTime
}
abort := time.NewTimer(maxWaitTime).C
for {
@ -393,10 +393,10 @@ func (s *SystemUnderTest) AwaitNextBlock(t *testing.T, timeout ...time.Duration)
}
done := make(chan int64)
go func() {
for start, current := atomic.LoadInt64(&s.currentHeight), atomic.LoadInt64(&s.currentHeight); current == start; current = atomic.LoadInt64(&s.currentHeight) {
for start, current := s.currentHeight.Load(), s.currentHeight.Load(); current == start; current = s.currentHeight.Load() {
time.Sleep(s.blockTime)
}
done <- atomic.LoadInt64(&s.currentHeight)
done <- s.currentHeight.Load()
close(done)
}()
select {
@ -434,7 +434,7 @@ func (s *SystemUnderTest) ResetChain(t *testing.T) {
// reset all validator nodes
s.ForEachNodeExecAndWait(t, []string{"comet", "unsafe-reset-all"})
s.currentHeight = 0
s.currentHeight.Store(0)
s.dirty = false
}
@ -465,7 +465,7 @@ func (s *SystemUnderTest) ModifyGenesisJSON(t *testing.T, mutators ...GenesisMut
// modify json without enforcing a reset
func (s *SystemUnderTest) modifyGenesisJSON(t *testing.T, mutators ...GenesisMutator) {
t.Helper()
require.Empty(t, s.currentHeight, "forced chain reset required")
require.Empty(t, s.currentHeight.Load(), "forced chain reset required")
current, err := os.ReadFile(filepath.Join(WorkDir, s.nodePath(0), "config", "genesis.json"))
require.NoError(t, err)
for _, m := range mutators {
@ -727,6 +727,10 @@ func (s *SystemUnderTest) anyNodeRunning() bool {
return len(s.pids) != 0
}
func (s *SystemUnderTest) CurrentHeight() int64 {
return s.currentHeight.Load()
}
type Node struct {
ID string
IP string

View File

@ -0,0 +1,52 @@
//go:build system_test
package systemtests
import (
"strconv"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestUnorderedTXDuplicate(t *testing.T) {
// scenario: test unordered tx duplicate
// given a running chain with a tx in the unordered tx pool
// when a new tx with the same hash is broadcasted
// then the new tx should be rejected
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
// add genesis account with some tokens
account1Addr := cli.AddKey("account1")
account2Addr := cli.AddKey("account2")
sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", account1Addr, "10000000stake"},
)
sut.StartChain(t)
height := sut.CurrentHeight()
timeoutHeight := height + 15
timeoutHeightStr := strconv.Itoa(int(timeoutHeight))
// send tokens
rsp1 := cli.Run("tx", "bank", "send", account1Addr, account2Addr, "5000stake", "--from="+account1Addr, "--fees=1stake", "--timeout-height="+timeoutHeightStr, "--unordered", "--sequence=1", "--note=1")
RequireTxSuccess(t, rsp1)
assertDuplicateErr := func(xt assert.TestingT, gotErr error, gotOutputs ...interface{}) bool {
require.Len(t, gotOutputs, 1)
assert.Contains(t, gotOutputs[0], "is duplicated: invalid request")
return false // always abort
}
rsp2 := cli.WithRunErrorMatcher(assertDuplicateErr).Run("tx", "bank", "send", account1Addr, account2Addr, "5000stake", "--from="+account1Addr, "--fees=1stake", "--timeout-height="+timeoutHeightStr, "--unordered", "--sequence=1")
RequireTxFailure(t, rsp2)
// assert TX executed before timeout
for cli.QueryBalance(account2Addr, "stake") != 5000 {
t.Log("query balance")
if current := sut.AwaitNextBlock(t); current > timeoutHeight {
t.Fatal("TX was not executed before timeout")
}
}
}

View File

@ -1,7 +1,12 @@
package ante
import (
"bytes"
"crypto/sha256"
"encoding/binary"
"sync"
"github.com/golang/protobuf/proto" // nolint: staticcheck // for proto.Message
"cosmossdk.io/core/appmodule/v2"
"cosmossdk.io/core/transaction"
@ -12,6 +17,15 @@ import (
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
// bufPool is a pool of bytes.Buffer objects to reduce memory allocations.
var bufPool = sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}
const DefaultSha256Cost = 25
var _ sdk.AnteDecorator = (*UnorderedTxDecorator)(nil)
// UnorderedTxDecorator defines an AnteHandler decorator that is responsible for
@ -31,13 +45,15 @@ type UnorderedTxDecorator struct {
maxUnOrderedTTL uint64
txManager *unorderedtx.Manager
env appmodule.Environment
sha256Cost uint64
}
func NewUnorderedTxDecorator(maxTTL uint64, m *unorderedtx.Manager, env appmodule.Environment) *UnorderedTxDecorator {
func NewUnorderedTxDecorator(maxTTL uint64, m *unorderedtx.Manager, env appmodule.Environment, gasCost uint64) *UnorderedTxDecorator {
return &UnorderedTxDecorator{
maxUnOrderedTTL: maxTTL,
txManager: m,
env: env,
sha256Cost: gasCost,
}
}
@ -62,13 +78,27 @@ func (d *UnorderedTxDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, _ bool, ne
return ctx, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "unordered tx ttl exceeds %d", d.maxUnOrderedTTL)
}
txHash := sha256.Sum256(ctx.TxBytes())
// consume gas in all exec modes to avoid gas estimation discrepancies
if err := d.env.GasService.GasMeter(ctx).Consume(d.sha256Cost, "consume gas for calculating tx hash"); err != nil {
return ctx, errorsmod.Wrap(sdkerrors.ErrOutOfGas, "out of gas")
}
// Avoid checking for duplicates and creating the identifier in simulation mode
// This is done to avoid sha256 computation in simulation mode
if d.env.TransactionService.ExecMode(ctx) == transaction.ExecModeSimulate {
return next(ctx, tx, false)
}
// calculate the tx hash
txHash, err := TxIdentifier(ttl, tx)
if err != nil {
return ctx, err
}
// check for duplicates
if d.txManager.Contains(txHash) {
return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "tx %X is duplicated")
}
if d.env.TransactionService.ExecMode(ctx) == transaction.ExecModeFinalize {
// a new tx included in the block, add the hash to the unordered tx manager
d.txManager.Add(txHash, ttl)
@ -76,3 +106,46 @@ func (d *UnorderedTxDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, _ bool, ne
return next(ctx, tx, false)
}
// TxIdentifier returns a unique identifier for a transaction that is intended to be unordered.
func TxIdentifier(timeout uint64, tx sdk.Tx) ([32]byte, error) {
feetx := tx.(sdk.FeeTx)
if feetx.GetFee().IsZero() {
return [32]byte{}, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "unordered transaction must have a fee")
}
buf := bufPool.Get().(*bytes.Buffer)
// Make sure to reset the buffer
buf.Reset()
defer bufPool.Put(buf)
// Use the buffer
for _, msg := range tx.GetMsgs() {
// loop through the messages and write them to the buffer
// encoding the msg to bytes makes it deterministic within the state machine.
// Malleability is not a concern here because the state machine will encode the transaction deterministically.
bz, err := proto.Marshal(msg)
if err != nil {
return [32]byte{}, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "failed to marshal message")
}
if _, err := buf.Write(bz); err != nil {
return [32]byte{}, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "failed to write message to buffer")
}
}
// write the timeout height to the buffer
if err := binary.Write(buf, binary.LittleEndian, timeout); err != nil {
return [32]byte{}, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "failed to write timeout_height to buffer")
}
// write gas to the buffer
if err := binary.Write(buf, binary.LittleEndian, feetx.GetGas()); err != nil {
return [32]byte{}, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "failed to write unordered to buffer")
}
txHash := sha256.Sum256(buf.Bytes())
// Return the Buffer to the pool
return txHash, nil
}

View File

@ -1,11 +1,11 @@
package ante_test
import (
"crypto/sha256"
"testing"
"github.com/stretchr/testify/require"
storetypes "cosmossdk.io/store/types"
"cosmossdk.io/x/auth/ante"
"cosmossdk.io/x/auth/ante/unorderedtx"
@ -15,6 +15,8 @@ import (
"github.com/cosmos/cosmos-sdk/types/tx/signing"
)
const gasConsumed = uint64(25)
func TestUnorderedTxDecorator_OrderedTx(t *testing.T) {
txm := unorderedtx.NewManager(t.TempDir())
defer func() {
@ -25,7 +27,7 @@ func TestUnorderedTxDecorator_OrderedTx(t *testing.T) {
suite := SetupTestSuite(t, false)
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment()))
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
tx, txBz := genUnorderedTx(t, false, 0)
ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100)
@ -44,7 +46,7 @@ func TestUnorderedTxDecorator_UnorderedTx_NoTTL(t *testing.T) {
suite := SetupTestSuite(t, false)
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment()))
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
tx, txBz := genUnorderedTx(t, true, 0)
ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100)
@ -63,7 +65,7 @@ func TestUnorderedTxDecorator_UnorderedTx_InvalidTTL(t *testing.T) {
suite := SetupTestSuite(t, false)
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment()))
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
tx, txBz := genUnorderedTx(t, true, 100+unorderedtx.DefaultMaxUnOrderedTTL+1)
ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100)
@ -82,13 +84,14 @@ func TestUnorderedTxDecorator_UnorderedTx_AlreadyExists(t *testing.T) {
suite := SetupTestSuite(t, false)
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment()))
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
tx, txBz := genUnorderedTx(t, true, 150)
ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100)
ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100).WithGasMeter(storetypes.NewGasMeter(gasConsumed))
txHash := sha256.Sum256(txBz)
txm.Add(txHash, 150)
bz := [32]byte{}
copy(bz[:], txBz[:32])
txm.Add(bz, 150)
_, err := chain(ctx, tx, false)
require.Error(t, err)
@ -104,10 +107,10 @@ func TestUnorderedTxDecorator_UnorderedTx_ValidCheckTx(t *testing.T) {
suite := SetupTestSuite(t, false)
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment()))
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
tx, txBz := genUnorderedTx(t, true, 150)
ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100).WithExecMode(sdk.ExecModeCheck)
ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100).WithExecMode(sdk.ExecModeCheck).WithGasMeter(storetypes.NewGasMeter(gasConsumed))
_, err := chain(ctx, tx, false)
require.NoError(t, err)
@ -123,16 +126,18 @@ func TestUnorderedTxDecorator_UnorderedTx_ValidDeliverTx(t *testing.T) {
suite := SetupTestSuite(t, false)
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment()))
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
tx, txBz := genUnorderedTx(t, true, 150)
ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100).WithExecMode(sdk.ExecModeFinalize)
ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100).WithExecMode(sdk.ExecModeFinalize).WithGasMeter(storetypes.NewGasMeter(gasConsumed))
_, err := chain(ctx, tx, false)
require.NoError(t, err)
txHash := sha256.Sum256(txBz)
require.True(t, txm.Contains(txHash))
bz := [32]byte{}
copy(bz[:], txBz[:32])
require.True(t, txm.Contains(bz))
}
func genUnorderedTx(t *testing.T, unordered bool, ttl uint64) (sdk.Tx, []byte) {
@ -159,8 +164,9 @@ func genUnorderedTx(t *testing.T, unordered bool, ttl uint64) (sdk.Tx, []byte) {
tx, err := s.CreateTestTx(s.ctx, privKeys, accNums, accSeqs, s.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
require.NoError(t, err)
txBz, err := s.encCfg.TxConfig.TxEncoder()(tx)
txBz, err := ante.TxIdentifier(ttl, tx)
require.NoError(t, err)
return tx, txBz
return tx, txBz[:]
}

View File

@ -3,12 +3,10 @@ module cosmossdk.io/x/authz
go 1.22.2
require (
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect
cosmossdk.io/api v0.7.5
cosmossdk.io/core v0.12.1-0.20231114100755-569e3ff6a0d7
cosmossdk.io/depinject v1.0.0-alpha.4
cosmossdk.io/errors v1.0.1
cosmossdk.io/log v1.3.1
cosmossdk.io/math v1.3.0
cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91
@ -168,6 +166,8 @@ require (
)
require (
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect
cosmossdk.io/log v1.3.1 // indirect
cosmossdk.io/schema v0.1.1 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
)
@ -182,6 +182,8 @@ replace (
cosmossdk.io/core/testing => ../../core/testing
cosmossdk.io/depinject => ../../depinject
cosmossdk.io/log => ../../log
cosmossdk.io/logger => ../../logger
cosmossdk.io/store => ../../store
cosmossdk.io/x/accounts => ../accounts
cosmossdk.io/x/auth => ../auth
cosmossdk.io/x/bank => ../bank

View File

@ -10,8 +10,6 @@ cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE=
cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k=
cosmossdk.io/schema v0.1.1 h1:I0M6pgI7R10nq+/HCQfbO6BsGBZA8sQy+duR1Y3aKcA=
cosmossdk.io/schema v0.1.1/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc h1:R9O9d75e0qZYUsVV0zzi+D7cNLnX2JrUOQNoIPaF0Bg=
cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc/go.mod h1:amTTatOUV3u1PsKmNb87z6/galCxrRbz9kRdJkL0DyU=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs=

View File

@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/suite"
"cosmossdk.io/core/header"
"cosmossdk.io/log"
"cosmossdk.io/core/log"
sdkmath "cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
"cosmossdk.io/x/authz/keeper"

View File

@ -6,7 +6,7 @@ import (
"fmt"
"time"
"github.com/cosmos/gogoproto/proto"
gogoproto "github.com/cosmos/gogoproto/proto"
"cosmossdk.io/core/appmodule"
corecontext "cosmossdk.io/core/context"
@ -65,7 +65,7 @@ func (k Keeper) update(ctx context.Context, grantee, granter sdk.AccAddress, upd
return authz.ErrNoAuthorizationFound
}
msg, ok := updated.(proto.Message)
msg, ok := updated.(gogoproto.Message)
if !ok {
return sdkerrors.ErrPackAny.Wrapf("cannot proto marshal %T", updated)
}

View File

@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/suite"
"cosmossdk.io/core/header"
"cosmossdk.io/log"
"cosmossdk.io/core/log"
storetypes "cosmossdk.io/store/types"
"cosmossdk.io/x/authz"
authzkeeper "cosmossdk.io/x/authz/keeper"

View File

@ -8,7 +8,7 @@ import (
govtypes "cosmossdk.io/api/cosmos/gov/v1beta1"
"cosmossdk.io/core/header"
"cosmossdk.io/log"
"cosmossdk.io/core/log"
storetypes "cosmossdk.io/store/types"
"cosmossdk.io/x/authz"
v2 "cosmossdk.io/x/authz/migrations/v2"

View File

@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/require"
"cosmossdk.io/core/header"
"cosmossdk.io/log"
"cosmossdk.io/core/log"
storetypes "cosmossdk.io/store/types"
authtypes "cosmossdk.io/x/auth/types"
"cosmossdk.io/x/authz"