refactor!: deprecate sdk.Msg.GetSigners (#15284)
Co-authored-by: Matt Kocubinski <mkocubinski@gmail.com>
This commit is contained in:
parent
b6613f9163
commit
82659a7477
@ -222,6 +222,15 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
* The field `OperationMsg.Msg` is now of type `[]byte` instead of `json.RawMessage`.
|
||||
* (cli) [#16209](https://github.com/cosmos/cosmos-sdk/pull/16209) Add API `StartCmdWithOptions` to create customized start command.
|
||||
* (x/distribution) [#16211](https://github.com/cosmos/cosmos-sdk/pull/16211) Use collections for params state management.
|
||||
* [#15284](https://github.com/cosmos/cosmos-sdk/pull/15284)
|
||||
* `sdk.Msg.GetSigners` was deprecated and is no longer supported. Use the `cosmos.msg.v1.signer` protobuf annotation instead.
|
||||
* `sdk.Tx` now requires a new method `GetMsgsV2()`.
|
||||
* `types/tx.Tx` no longer implements `sdk.Tx`.
|
||||
* `TxConfig` has a new method `SigningContext() *signing.Context`.
|
||||
* `AccountKeeper` now has an `AddressCodec() address.Codec` method and the expected `AccountKeeper` for `x/auth/ante` expects this method.
|
||||
* `SigVerifiableTx.GetSigners()` now returns `([][]byte, error)` instead of `[]sdk.AccAddress`.
|
||||
* (x/authx) [#15284](https://github.com/cosmos/cosmos-sdk/pull/15284) `NewKeeper` now requires `codec.Codec`.
|
||||
* (x/gov) [#15284](https://github.com/cosmos/cosmos-sdk/pull/15284) `NewKeeper` now requires `codec.Codec`.
|
||||
|
||||
### Client Breaking Changes
|
||||
|
||||
|
||||
@ -10,16 +10,18 @@ import (
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
"cosmossdk.io/log"
|
||||
pruningtypes "cosmossdk.io/store/pruning/types"
|
||||
"cosmossdk.io/store/snapshots"
|
||||
snapshottypes "cosmossdk.io/store/snapshots/types"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
dbm "github.com/cosmos/cosmos-db"
|
||||
"github.com/cosmos/gogoproto/jsonpb"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
pruningtypes "cosmossdk.io/store/pruning/types"
|
||||
"cosmossdk.io/store/snapshots"
|
||||
snapshottypes "cosmossdk.io/store/snapshots/types"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
baseapptestutil "github.com/cosmos/cosmos-sdk/baseapp/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
@ -455,8 +457,9 @@ func TestABCI_FinalizeBlock_MultiMsg(t *testing.T) {
|
||||
|
||||
builder := suite.txConfig.NewTxBuilder()
|
||||
msgs := tx.GetMsgs()
|
||||
msgs = append(msgs, &baseapptestutil.MsgCounter2{Counter: 0})
|
||||
msgs = append(msgs, &baseapptestutil.MsgCounter2{Counter: 1})
|
||||
_, _, addr := testdata.KeyTestPubAddr()
|
||||
msgs = append(msgs, &baseapptestutil.MsgCounter2{Counter: 0, Signer: addr.String()})
|
||||
msgs = append(msgs, &baseapptestutil.MsgCounter2{Counter: 1, Signer: addr.String()})
|
||||
|
||||
builder.SetMsgs(msgs...)
|
||||
builder.SetMemo(tx.GetMemo())
|
||||
@ -611,7 +614,8 @@ func TestABCI_InvalidTransaction(t *testing.T) {
|
||||
// transaction with no known route
|
||||
{
|
||||
txBuilder := suite.txConfig.NewTxBuilder()
|
||||
txBuilder.SetMsgs(&baseapptestutil.MsgCounter2{})
|
||||
_, _, addr := testdata.KeyTestPubAddr()
|
||||
txBuilder.SetMsgs(&baseapptestutil.MsgCounter2{Signer: addr.String()})
|
||||
setTxSignature(t, txBuilder, 0)
|
||||
unknownRouteTx := txBuilder.GetTx()
|
||||
|
||||
@ -624,7 +628,10 @@ func TestABCI_InvalidTransaction(t *testing.T) {
|
||||
require.EqualValues(t, sdkerrors.ErrUnknownRequest.ABCICode(), code, err)
|
||||
|
||||
txBuilder = suite.txConfig.NewTxBuilder()
|
||||
txBuilder.SetMsgs(&baseapptestutil.MsgCounter{}, &baseapptestutil.MsgCounter2{})
|
||||
txBuilder.SetMsgs(
|
||||
&baseapptestutil.MsgCounter{Signer: addr.String()},
|
||||
&baseapptestutil.MsgCounter2{Signer: addr.String()},
|
||||
)
|
||||
setTxSignature(t, txBuilder, 0)
|
||||
unknownRouteTx = txBuilder.GetTx()
|
||||
|
||||
@ -1247,7 +1254,7 @@ func TestABCI_PrepareProposal_ReachedMaxBytes(t *testing.T) {
|
||||
}
|
||||
resPrepareProposal, err := suite.baseApp.PrepareProposal(&reqPrepareProposal)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 11, len(resPrepareProposal.Txs))
|
||||
require.Equal(t, 8, len(resPrepareProposal.Txs))
|
||||
}
|
||||
|
||||
func TestABCI_PrepareProposal_BadEncoding(t *testing.T) {
|
||||
|
||||
@ -8,10 +8,6 @@ import (
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
"cosmossdk.io/log"
|
||||
"cosmossdk.io/store"
|
||||
storemetrics "cosmossdk.io/store/metrics"
|
||||
"cosmossdk.io/store/snapshots"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
"github.com/cockroachdb/errors"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
"github.com/cometbft/cometbft/crypto/tmhash"
|
||||
@ -19,7 +15,14 @@ import (
|
||||
dbm "github.com/cosmos/cosmos-db"
|
||||
"github.com/cosmos/gogoproto/proto"
|
||||
"golang.org/x/exp/maps"
|
||||
protov2 "google.golang.org/protobuf/proto"
|
||||
|
||||
"cosmossdk.io/store"
|
||||
storemetrics "cosmossdk.io/store/metrics"
|
||||
"cosmossdk.io/store/snapshots"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||
"github.com/cosmos/cosmos-sdk/telemetry"
|
||||
@ -174,6 +177,8 @@ type BaseApp struct {
|
||||
streamingManager storetypes.StreamingManager
|
||||
|
||||
chainID string
|
||||
|
||||
cdc codec.Codec
|
||||
}
|
||||
|
||||
// NewBaseApp returns a reference to an initialized BaseApp. It accepts a
|
||||
@ -222,6 +227,10 @@ func NewBaseApp(
|
||||
|
||||
app.runTxRecoveryMiddleware = newDefaultRecoveryMiddleware()
|
||||
|
||||
// Initialize with an empty interface registry to avoid nil pointer dereference.
|
||||
// Unless SetInterfaceRegistry is called with an interface registry with proper address codecs base app will panic.
|
||||
app.cdc = codec.NewProtoCodec(codectypes.NewInterfaceRegistry())
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
@ -636,7 +645,7 @@ func (app *BaseApp) getContextForTx(mode execMode, txBytes []byte) sdk.Context {
|
||||
}
|
||||
ctx := modeState.ctx.
|
||||
WithTxBytes(txBytes)
|
||||
// WithVoteInfos(app.voteInfos) // TODO: identify if this is needed
|
||||
// WithVoteInfos(app.voteInfos) // TODO: identify if this is needed
|
||||
|
||||
ctx = ctx.WithConsensusParams(app.GetConsensusParams(ctx))
|
||||
|
||||
@ -884,7 +893,10 @@ func (app *BaseApp) runTx(mode execMode, txBytes []byte) (gInfo sdk.GasInfo, res
|
||||
// Attempt to execute all messages and only update state if all messages pass
|
||||
// and we're in DeliverTx. Note, runMsgs will never return a reference to a
|
||||
// Result if any single message fails or does not have a registered Handler.
|
||||
result, err = app.runMsgs(runMsgCtx, msgs, mode)
|
||||
msgsV2, err := tx.GetMsgsV2()
|
||||
if err == nil {
|
||||
result, err = app.runMsgs(runMsgCtx, msgs, msgsV2, mode)
|
||||
}
|
||||
if err == nil {
|
||||
// Run optional postHandlers.
|
||||
//
|
||||
@ -924,7 +936,7 @@ func (app *BaseApp) runTx(mode execMode, txBytes []byte) (gInfo sdk.GasInfo, res
|
||||
// and DeliverTx. An error is returned if any single message fails or if a
|
||||
// Handler does not exist for a given message route. Otherwise, a reference to a
|
||||
// Result is returned. The caller must not commit state if an error is returned.
|
||||
func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode execMode) (*sdk.Result, error) {
|
||||
func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, msgsV2 []protov2.Message, mode execMode) (*sdk.Result, error) {
|
||||
events := sdk.EmptyEvents()
|
||||
var msgResponses []*codectypes.Any
|
||||
|
||||
@ -946,7 +958,7 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode execMode) (*sd
|
||||
}
|
||||
|
||||
// create message events
|
||||
msgEvents := createEvents(msgResult.GetEvents(), msg)
|
||||
msgEvents := createEvents(app.cdc, msgResult.GetEvents(), msg, msgsV2[i])
|
||||
|
||||
// append message events and data
|
||||
//
|
||||
@ -991,13 +1003,21 @@ func makeABCIData(msgResponses []*codectypes.Any) ([]byte, error) {
|
||||
return proto.Marshal(&sdk.TxMsgData{MsgResponses: msgResponses})
|
||||
}
|
||||
|
||||
func createEvents(events sdk.Events, msg sdk.Msg) sdk.Events {
|
||||
func createEvents(cdc codec.Codec, events sdk.Events, msg sdk.Msg, msgV2 protov2.Message) sdk.Events {
|
||||
eventMsgName := sdk.MsgTypeURL(msg)
|
||||
msgEvent := sdk.NewEvent(sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyAction, eventMsgName))
|
||||
|
||||
// we set the signer attribute as the sender
|
||||
if len(msg.GetSigners()) > 0 && !msg.GetSigners()[0].Empty() {
|
||||
msgEvent = msgEvent.AppendAttributes(sdk.NewAttribute(sdk.AttributeKeySender, msg.GetSigners()[0].String()))
|
||||
signers, err := cdc.GetMsgV2Signers(msgV2)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if len(signers) > 0 && signers[0] != nil {
|
||||
addrStr, err := cdc.InterfaceRegistry().SigningContext().AddressCodec().BytesToString(signers[0])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
msgEvent = msgEvent.AppendAttributes(sdk.NewAttribute(sdk.AttributeKeySender, addrStr))
|
||||
}
|
||||
|
||||
// verify that events have no module attribute set
|
||||
|
||||
@ -9,23 +9,25 @@ import (
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
"cosmossdk.io/log"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
dbm "github.com/cosmos/cosmos-db"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"cosmossdk.io/store/metrics"
|
||||
pruningtypes "cosmossdk.io/store/pruning/types"
|
||||
"cosmossdk.io/store/rootmulti"
|
||||
"cosmossdk.io/store/snapshots"
|
||||
snapshottypes "cosmossdk.io/store/snapshots/types"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
dbm "github.com/cosmos/cosmos-db"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
baseapptestutil "github.com/cosmos/cosmos-sdk/baseapp/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
)
|
||||
@ -56,7 +58,7 @@ type (
|
||||
)
|
||||
|
||||
func NewBaseAppSuite(t *testing.T, opts ...func(*baseapp.BaseApp)) *BaseAppSuite {
|
||||
cdc := codec.NewProtoCodec(codectypes.NewInterfaceRegistry())
|
||||
cdc := codectestutil.CodecOptions{}.NewCodec()
|
||||
baseapptestutil.RegisterInterfaces(cdc.InterfaceRegistry())
|
||||
|
||||
txConfig := authtx.NewTxConfig(cdc, authtx.DefaultSignModes)
|
||||
@ -107,6 +109,7 @@ func NewBaseAppSuiteWithSnapshots(t *testing.T, cfg SnapshotsConfig, opts ...fun
|
||||
|
||||
for height := int64(1); height <= int64(cfg.blocks); height++ {
|
||||
|
||||
_, _, addr := testdata.KeyTestPubAddr()
|
||||
txs := [][]byte{}
|
||||
for txNum := 0; txNum < cfg.blockTxs; txNum++ {
|
||||
msgs := []sdk.Msg{}
|
||||
@ -117,7 +120,7 @@ func NewBaseAppSuiteWithSnapshots(t *testing.T, cfg SnapshotsConfig, opts ...fun
|
||||
_, err := r.Read(value)
|
||||
require.NoError(t, err)
|
||||
|
||||
msgs = append(msgs, &baseapptestutil.MsgKeyValue{Key: key, Value: value})
|
||||
msgs = append(msgs, &baseapptestutil.MsgKeyValue{Key: key, Value: value, Signer: addr.String()})
|
||||
keyCounter++
|
||||
}
|
||||
|
||||
|
||||
@ -115,9 +115,14 @@ func TestMsgService(t *testing.T) {
|
||||
app.MsgServiceRouter(),
|
||||
testdata.MsgServerImpl{},
|
||||
)
|
||||
app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 1})
|
||||
_, err = app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 1})
|
||||
require.NoError(t, err)
|
||||
|
||||
msg := testdata.MsgCreateDog{Dog: &testdata.Dog{Name: "Spot"}}
|
||||
_, _, addr := testdata.KeyTestPubAddr()
|
||||
msg := testdata.MsgCreateDog{
|
||||
Dog: &testdata.Dog{Name: "Spot"},
|
||||
Owner: addr.String(),
|
||||
}
|
||||
|
||||
txBuilder := txConfig.NewTxBuilder()
|
||||
txBuilder.SetFeeAmount(testdata.NewTestFeeAmount())
|
||||
|
||||
@ -11,6 +11,7 @@ import (
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
dbm "github.com/cosmos/cosmos-db"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/mempool"
|
||||
@ -256,6 +257,7 @@ func (app *BaseApp) SetInterfaceRegistry(registry types.InterfaceRegistry) {
|
||||
app.interfaceRegistry = registry
|
||||
app.grpcQueryRouter.SetInterfaceRegistry(registry)
|
||||
app.msgServiceRouter.SetInterfaceRegistry(registry)
|
||||
app.cdc = codec.NewProtoCodec(registry)
|
||||
}
|
||||
|
||||
// SetTxDecoder sets the TxDecoder if it wasn't provided in the BaseApp constructor.
|
||||
|
||||
@ -31,8 +31,9 @@ var _ = math.Inf
|
||||
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type MsgCounter struct {
|
||||
Counter int64 `protobuf:"varint,1,opt,name=counter,proto3" json:"counter,omitempty"`
|
||||
FailOnHandler bool `protobuf:"varint,2,opt,name=fail_on_handler,json=failOnHandler,proto3" json:"fail_on_handler,omitempty"`
|
||||
Counter int64 `protobuf:"varint,1,opt,name=counter,proto3" json:"counter,omitempty"`
|
||||
FailOnHandler bool `protobuf:"varint,2,opt,name=fail_on_handler,json=failOnHandler,proto3" json:"fail_on_handler,omitempty"`
|
||||
Signer string `protobuf:"bytes,3,opt,name=signer,proto3" json:"signer,omitempty"`
|
||||
}
|
||||
|
||||
func (m *MsgCounter) Reset() { *m = MsgCounter{} }
|
||||
@ -82,9 +83,17 @@ func (m *MsgCounter) GetFailOnHandler() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *MsgCounter) GetSigner() string {
|
||||
if m != nil {
|
||||
return m.Signer
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type MsgCounter2 struct {
|
||||
Counter int64 `protobuf:"varint,1,opt,name=counter,proto3" json:"counter,omitempty"`
|
||||
FailOnHandler bool `protobuf:"varint,2,opt,name=fail_on_handler,json=failOnHandler,proto3" json:"fail_on_handler,omitempty"`
|
||||
Counter int64 `protobuf:"varint,1,opt,name=counter,proto3" json:"counter,omitempty"`
|
||||
FailOnHandler bool `protobuf:"varint,2,opt,name=fail_on_handler,json=failOnHandler,proto3" json:"fail_on_handler,omitempty"`
|
||||
Signer string `protobuf:"bytes,3,opt,name=signer,proto3" json:"signer,omitempty"`
|
||||
}
|
||||
|
||||
func (m *MsgCounter2) Reset() { *m = MsgCounter2{} }
|
||||
@ -134,6 +143,13 @@ func (m *MsgCounter2) GetFailOnHandler() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *MsgCounter2) GetSigner() string {
|
||||
if m != nil {
|
||||
return m.Signer
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type MsgCreateCounterResponse struct {
|
||||
}
|
||||
|
||||
@ -277,32 +293,32 @@ func init() {
|
||||
func init() { proto.RegisterFile("messages.proto", fileDescriptor_4dc296cbfe5ffcd5) }
|
||||
|
||||
var fileDescriptor_4dc296cbfe5ffcd5 = []byte{
|
||||
// 387 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x92, 0xcf, 0xca, 0xd3, 0x40,
|
||||
0x14, 0xc5, 0x1b, 0x83, 0xdf, 0x57, 0x6f, 0xab, 0x96, 0x50, 0x34, 0x8d, 0x10, 0x4a, 0x16, 0x52,
|
||||
0x84, 0x66, 0x30, 0xee, 0xda, 0x9d, 0x22, 0x55, 0x44, 0x0b, 0x11, 0x5c, 0x74, 0x53, 0x26, 0xe9,
|
||||
0xed, 0x34, 0x34, 0x99, 0x09, 0x99, 0x49, 0xa1, 0x5b, 0x9f, 0xc0, 0x47, 0xf1, 0x31, 0x5c, 0x76,
|
||||
0xe9, 0x52, 0xda, 0x85, 0xaf, 0x21, 0xf9, 0xd7, 0xba, 0xb0, 0xae, 0xbe, 0xd5, 0xdc, 0x73, 0x2e,
|
||||
0xf9, 0x9d, 0xcc, 0x61, 0xe0, 0x51, 0x82, 0x52, 0x52, 0x86, 0xd2, 0x4d, 0x33, 0xa1, 0x84, 0xf5,
|
||||
0x34, 0x14, 0x32, 0x11, 0x92, 0x24, 0x92, 0x91, 0xdd, 0xcb, 0xe2, 0xa8, 0x17, 0x7d, 0x26, 0x98,
|
||||
0x28, 0x47, 0x52, 0x4c, 0xb5, 0x3b, 0x60, 0x42, 0xb0, 0x18, 0x49, 0xa9, 0x82, 0x7c, 0x4d, 0x28,
|
||||
0xdf, 0x57, 0x2b, 0xe7, 0x13, 0xc0, 0x47, 0xc9, 0xde, 0x88, 0x9c, 0x2b, 0xcc, 0x0c, 0x13, 0x6e,
|
||||
0xc3, 0x6a, 0x34, 0xb5, 0xa1, 0x36, 0xd2, 0xfd, 0x46, 0x1a, 0xcf, 0xe1, 0xf1, 0x9a, 0x46, 0xf1,
|
||||
0x52, 0xf0, 0xe5, 0x86, 0xf2, 0x55, 0x8c, 0x99, 0x79, 0x6f, 0xa8, 0x8d, 0xda, 0xfe, 0xc3, 0xc2,
|
||||
0x9e, 0xf3, 0x77, 0x95, 0xe9, 0xcc, 0xa1, 0x73, 0xe1, 0x79, 0x77, 0x00, 0xb4, 0xc0, 0x2c, 0x80,
|
||||
0x19, 0x52, 0x85, 0x35, 0xd6, 0x47, 0x99, 0x0a, 0x2e, 0xd1, 0x59, 0x94, 0x61, 0x1f, 0x70, 0xff,
|
||||
0x85, 0xc6, 0x39, 0x1a, 0x3d, 0xd0, 0xb7, 0xb8, 0x2f, 0x83, 0xba, 0x7e, 0x31, 0x1a, 0x7d, 0xb8,
|
||||
0xbf, 0x2b, 0x56, 0x25, 0xba, 0xeb, 0x57, 0xc2, 0x78, 0x02, 0x37, 0x32, 0x62, 0x1c, 0x33, 0x53,
|
||||
0x1f, 0x6a, 0xa3, 0x07, 0x7e, 0xad, 0x26, 0x9d, 0xaf, 0xbf, 0xbf, 0xbf, 0xa8, 0x85, 0xf3, 0x0c,
|
||||
0x06, 0xe7, 0xdc, 0x26, 0xa1, 0x09, 0xf6, 0xde, 0xc2, 0x6d, 0x53, 0xd9, 0x04, 0x7a, 0xef, 0x79,
|
||||
0x98, 0x61, 0x82, 0x5c, 0x35, 0x5e, 0xc7, 0xbd, 0x74, 0x60, 0x0d, 0xdc, 0x6b, 0xff, 0xef, 0xcd,
|
||||
0xa0, 0x7d, 0x6e, 0x6a, 0xfa, 0x0f, 0x4e, 0xf7, 0x2f, 0x8e, 0xf7, 0x3f, 0xd0, 0x14, 0xda, 0xe7,
|
||||
0x16, 0x08, 0xe8, 0x9f, 0x51, 0x55, 0xdf, 0x36, 0xa6, 0x65, 0xb9, 0x57, 0x2f, 0xf3, 0x7a, 0xf6,
|
||||
0xe3, 0x68, 0x6b, 0x87, 0xa3, 0xad, 0xfd, 0x3a, 0xda, 0xda, 0xb7, 0x93, 0xdd, 0x3a, 0x9c, 0xec,
|
||||
0xd6, 0xcf, 0x93, 0xdd, 0x5a, 0x8c, 0x59, 0xa4, 0x36, 0x79, 0xe0, 0x86, 0x22, 0x21, 0xf5, 0x8b,
|
||||
0xab, 0x8e, 0xb1, 0x5c, 0x6d, 0x49, 0x40, 0x25, 0xd2, 0x34, 0x25, 0x0a, 0xa5, 0xca, 0x55, 0x14,
|
||||
0x07, 0x37, 0xe5, 0x93, 0x7a, 0xf5, 0x27, 0x00, 0x00, 0xff, 0xff, 0xea, 0x9d, 0x1c, 0xeb, 0xae,
|
||||
0x02, 0x00, 0x00,
|
||||
// 390 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x92, 0xcf, 0xaa, 0xd3, 0x40,
|
||||
0x14, 0xc6, 0x1b, 0x83, 0x6d, 0x3d, 0xad, 0x5a, 0x42, 0xd1, 0x34, 0x42, 0x28, 0x5d, 0x48, 0x11,
|
||||
0x9a, 0xc1, 0xb8, 0x6b, 0x77, 0x8a, 0x54, 0x11, 0x11, 0x22, 0xb8, 0xe8, 0xa6, 0x4c, 0xd2, 0xd3,
|
||||
0x69, 0x68, 0x32, 0x13, 0x32, 0x93, 0x42, 0xb7, 0x3e, 0x81, 0x8f, 0xe2, 0x63, 0xb8, 0xec, 0xd2,
|
||||
0xa5, 0xb4, 0x0b, 0x5f, 0x43, 0xf2, 0xaf, 0x75, 0x71, 0x7b, 0xb9, 0xab, 0xbb, 0x9a, 0xf3, 0x7d,
|
||||
0x87, 0x9c, 0xdf, 0xc9, 0xc7, 0x81, 0x27, 0x31, 0x4a, 0x49, 0x19, 0x4a, 0x27, 0x49, 0x85, 0x12,
|
||||
0x56, 0x9f, 0x09, 0x26, 0x8a, 0x92, 0xe4, 0x55, 0xe5, 0x0e, 0x98, 0x10, 0x2c, 0x42, 0x52, 0x28,
|
||||
0x3f, 0x5b, 0x13, 0xca, 0xf7, 0x55, 0xeb, 0x79, 0x20, 0x64, 0x2c, 0x24, 0x89, 0x25, 0x23, 0xbb,
|
||||
0xd7, 0xf9, 0x53, 0x36, 0x46, 0x12, 0xe0, 0xb3, 0x64, 0xef, 0x44, 0xc6, 0x15, 0xa6, 0x86, 0x09,
|
||||
0xad, 0xa0, 0x2c, 0x4d, 0x6d, 0xa8, 0x8d, 0x75, 0xaf, 0x96, 0xc6, 0x4b, 0x78, 0xba, 0xa6, 0x61,
|
||||
0xb4, 0x14, 0x7c, 0xb9, 0xa1, 0x7c, 0x15, 0x61, 0x6a, 0x3e, 0x18, 0x6a, 0xe3, 0xb6, 0xf7, 0x38,
|
||||
0xb7, 0xbf, 0xf0, 0x0f, 0xa5, 0x69, 0x3c, 0x83, 0xa6, 0x0c, 0x19, 0xc7, 0xd4, 0xd4, 0x87, 0xda,
|
||||
0xf8, 0x91, 0x57, 0xa9, 0x69, 0xe7, 0xfb, 0xdf, 0x9f, 0xaf, 0x2a, 0x31, 0x52, 0xd0, 0xb9, 0x40,
|
||||
0xdd, 0xfb, 0xa2, 0x5a, 0x60, 0xe6, 0xd4, 0x14, 0xa9, 0xc2, 0x8a, 0xed, 0xa1, 0x4c, 0x04, 0x97,
|
||||
0x38, 0x5a, 0x14, 0x1b, 0x7d, 0xc2, 0xfd, 0x37, 0x1a, 0x65, 0x68, 0xf4, 0x40, 0xdf, 0xe2, 0xbe,
|
||||
0xd8, 0xa6, 0xeb, 0xe5, 0xa5, 0xd1, 0x87, 0x87, 0xbb, 0xbc, 0x55, 0xf0, 0xbb, 0x5e, 0x29, 0xee,
|
||||
0xc6, 0x7d, 0x01, 0x83, 0x33, 0xb7, 0x26, 0xd4, 0x60, 0xf7, 0x3d, 0xb4, 0xea, 0xf0, 0xa7, 0xd0,
|
||||
0xfb, 0xc8, 0x83, 0x14, 0x63, 0xe4, 0xaa, 0xf6, 0x3a, 0xce, 0x25, 0x28, 0x6b, 0xe0, 0x5c, 0xdb,
|
||||
0xdf, 0x9d, 0x43, 0xfb, 0x1c, 0xe7, 0xec, 0x86, 0x39, 0xdd, 0xff, 0xe6, 0xb8, 0xb7, 0x0d, 0x9a,
|
||||
0x41, 0xfb, 0x9c, 0x02, 0x01, 0xfd, 0x2b, 0xaa, 0xf2, 0xdb, 0xda, 0xb4, 0x2c, 0xe7, 0xea, 0xcf,
|
||||
0xbc, 0x9d, 0xff, 0x3a, 0xda, 0xda, 0xe1, 0x68, 0x6b, 0x7f, 0x8e, 0xb6, 0xf6, 0xe3, 0x64, 0x37,
|
||||
0x0e, 0x27, 0xbb, 0xf1, 0xfb, 0x64, 0x37, 0x16, 0x13, 0x16, 0xaa, 0x4d, 0xe6, 0x3b, 0x81, 0x88,
|
||||
0x49, 0x75, 0x8a, 0xe5, 0x33, 0x91, 0xab, 0x2d, 0xf1, 0xa9, 0x44, 0x9a, 0x24, 0x44, 0xa1, 0x54,
|
||||
0x99, 0x0a, 0x23, 0xbf, 0x59, 0x1c, 0xe7, 0x9b, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x44, 0x91,
|
||||
0x2d, 0xb3, 0xf8, 0x02, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@ -549,6 +565,13 @@ func (m *MsgCounter) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Signer) > 0 {
|
||||
i -= len(m.Signer)
|
||||
copy(dAtA[i:], m.Signer)
|
||||
i = encodeVarintMessages(dAtA, i, uint64(len(m.Signer)))
|
||||
i--
|
||||
dAtA[i] = 0x1a
|
||||
}
|
||||
if m.FailOnHandler {
|
||||
i--
|
||||
if m.FailOnHandler {
|
||||
@ -587,6 +610,13 @@ func (m *MsgCounter2) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Signer) > 0 {
|
||||
i -= len(m.Signer)
|
||||
copy(dAtA[i:], m.Signer)
|
||||
i = encodeVarintMessages(dAtA, i, uint64(len(m.Signer)))
|
||||
i--
|
||||
dAtA[i] = 0x1a
|
||||
}
|
||||
if m.FailOnHandler {
|
||||
i--
|
||||
if m.FailOnHandler {
|
||||
@ -718,6 +748,10 @@ func (m *MsgCounter) Size() (n int) {
|
||||
if m.FailOnHandler {
|
||||
n += 2
|
||||
}
|
||||
l = len(m.Signer)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovMessages(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
@ -733,6 +767,10 @@ func (m *MsgCounter2) Size() (n int) {
|
||||
if m.FailOnHandler {
|
||||
n += 2
|
||||
}
|
||||
l = len(m.Signer)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovMessages(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
@ -849,6 +887,38 @@ func (m *MsgCounter) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
}
|
||||
m.FailOnHandler = bool(v != 0)
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowMessages
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthMessages
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthMessages
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Signer = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipMessages(dAtA[iNdEx:])
|
||||
@ -938,6 +1008,38 @@ func (m *MsgCounter2) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
}
|
||||
m.FailOnHandler = bool(v != 0)
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowMessages
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthMessages
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthMessages
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Signer = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipMessages(dAtA[iNdEx:])
|
||||
|
||||
@ -1,19 +1,25 @@
|
||||
syntax = "proto3";
|
||||
|
||||
import "cosmos/msg/v1/msg.proto";
|
||||
import "gogoproto/gogo.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
import "cosmos/msg/v1/msg.proto";
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/baseapp/testutil";
|
||||
|
||||
message MsgCounter {
|
||||
option (cosmos.msg.v1.signer) = "signer";
|
||||
|
||||
int64 counter = 1;
|
||||
bool fail_on_handler = 2;
|
||||
string signer = 3;
|
||||
}
|
||||
|
||||
message MsgCounter2 {
|
||||
option (cosmos.msg.v1.signer) = "signer";
|
||||
|
||||
int64 counter = 1;
|
||||
bool fail_on_handler = 2;
|
||||
string signer = 3;
|
||||
}
|
||||
|
||||
message MsgCreateCounterResponse {}
|
||||
|
||||
@ -15,16 +15,18 @@ import (
|
||||
|
||||
runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
|
||||
appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
|
||||
"cosmossdk.io/core/appconfig"
|
||||
"cosmossdk.io/depinject"
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
sdkmath "cosmossdk.io/math"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
cmttypes "github.com/cometbft/cometbft/types"
|
||||
dbm "github.com/cosmos/cosmos-db"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"cosmossdk.io/core/appconfig"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
baseapptestutil "github.com/cosmos/cosmos-sdk/baseapp/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
@ -322,9 +324,10 @@ func parseTxMemo(t *testing.T, tx sdk.Tx) (counter int64, failOnAnte bool) {
|
||||
}
|
||||
|
||||
func newTxCounter(t *testing.T, cfg client.TxConfig, counter int64, msgCounters ...int64) signing.Tx {
|
||||
_, _, addr := testdata.KeyTestPubAddr()
|
||||
msgs := make([]sdk.Msg, 0, len(msgCounters))
|
||||
for _, c := range msgCounters {
|
||||
msg := &baseapptestutil.MsgCounter{Counter: c, FailOnHandler: false}
|
||||
msg := &baseapptestutil.MsgCounter{Counter: c, FailOnHandler: false, Signer: addr.String()}
|
||||
msgs = append(msgs, msg)
|
||||
}
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ type (
|
||||
NewTxBuilder() TxBuilder
|
||||
WrapTxBuilder(sdk.Tx) (TxBuilder, error)
|
||||
SignModeHandler() *txsigning.HandlerMap
|
||||
SigningContext() *txsigning.Context
|
||||
}
|
||||
|
||||
// TxBuilder defines an interface which an application-defined concrete transaction
|
||||
|
||||
96
codec/bench_test.go
Normal file
96
codec/bench_test.go
Normal file
@ -0,0 +1,96 @@
|
||||
package codec_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
|
||||
"github.com/stretchr/testify/require"
|
||||
protov2 "google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/types/dynamicpb"
|
||||
|
||||
codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
func BenchmarkLegacyGetSigners(b *testing.B) {
|
||||
_, _, addr := testdata.KeyTestPubAddr()
|
||||
msg := &banktypes.MsgSend{
|
||||
FromAddress: addr.String(),
|
||||
ToAddress: "",
|
||||
Amount: nil,
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = msg.GetSigners()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkProtoreflectGetSigners(b *testing.B) {
|
||||
cdc := codectestutil.CodecOptions{}.NewCodec()
|
||||
signingCtx := cdc.InterfaceRegistry().SigningContext()
|
||||
_, _, addr := testdata.KeyTestPubAddr()
|
||||
// use a pulsar message
|
||||
msg := &bankv1beta1.MsgSend{
|
||||
FromAddress: addr.String(),
|
||||
ToAddress: "",
|
||||
Amount: nil,
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := signingCtx.GetSigners(msg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkProtoreflectGetSignersWithUnmarshal(b *testing.B) {
|
||||
cdc := codectestutil.CodecOptions{}.NewCodec()
|
||||
_, _, addr := testdata.KeyTestPubAddr()
|
||||
// start with a protoreflect message
|
||||
msg := &banktypes.MsgSend{
|
||||
FromAddress: addr.String(),
|
||||
ToAddress: "",
|
||||
Amount: nil,
|
||||
}
|
||||
// marshal to an any first because this is what we get from the wire
|
||||
a, err := codectypes.NewAnyWithValue(msg)
|
||||
require.NoError(b, err)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _, err := cdc.GetMsgAnySigners(a)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkProtoreflectGetSignersDynamicpb(b *testing.B) {
|
||||
cdc := codectestutil.CodecOptions{}.NewCodec()
|
||||
signingCtx := cdc.InterfaceRegistry().SigningContext()
|
||||
_, _, addr := testdata.KeyTestPubAddr()
|
||||
msg := &bankv1beta1.MsgSend{
|
||||
FromAddress: addr.String(),
|
||||
ToAddress: "",
|
||||
Amount: nil,
|
||||
}
|
||||
bz, err := protov2.Marshal(msg)
|
||||
require.NoError(b, err)
|
||||
|
||||
dynamicmsg := dynamicpb.NewMessage(msg.ProtoReflect().Descriptor())
|
||||
err = protov2.Unmarshal(bz, dynamicmsg)
|
||||
require.NoError(b, err)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := signingCtx.GetSigners(dynamicmsg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
43
codec/testutil/codec.go
Normal file
43
codec/testutil/codec.go
Normal file
@ -0,0 +1,43 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"github.com/cosmos/gogoproto/proto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/address"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
)
|
||||
|
||||
// CodecOptions are options for creating a test codec.
|
||||
type CodecOptions struct {
|
||||
AccAddressPrefix string
|
||||
ValAddressPrefix string
|
||||
}
|
||||
|
||||
// NewInterfaceRegistry returns a new InterfaceRegistry with the given options.
|
||||
func (o CodecOptions) NewInterfaceRegistry() codectypes.InterfaceRegistry {
|
||||
accAddressPrefix := o.AccAddressPrefix
|
||||
if accAddressPrefix == "" {
|
||||
accAddressPrefix = "cosmos"
|
||||
}
|
||||
|
||||
valAddressPrefix := o.ValAddressPrefix
|
||||
if valAddressPrefix == "" {
|
||||
valAddressPrefix = "cosmosvaloper"
|
||||
}
|
||||
|
||||
ir, err := codectypes.NewInterfaceRegistryWithOptions(codectypes.InterfaceRegistryOptions{
|
||||
ProtoFiles: proto.HybridResolver,
|
||||
AddressCodec: address.NewBech32Codec(accAddressPrefix),
|
||||
ValidatorAddressCodec: address.NewBech32Codec(valAddressPrefix),
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ir
|
||||
}
|
||||
|
||||
// NewCodec returns a new codec with the given options.
|
||||
func (o CodecOptions) NewCodec() *codec.ProtoCodec {
|
||||
return codec.NewProtoCodec(o.NewInterfaceRegistry())
|
||||
}
|
||||
@ -19,6 +19,7 @@ import (
|
||||
"cosmossdk.io/core/header"
|
||||
"cosmossdk.io/core/store"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
"github.com/cosmos/cosmos-sdk/codec/address"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
@ -98,9 +99,15 @@ func ProvideApp() (
|
||||
}
|
||||
|
||||
interfaceRegistry, err := codectypes.NewInterfaceRegistryWithOptions(codectypes.InterfaceRegistryOptions{
|
||||
ProtoFiles: protoFiles,
|
||||
AddressCodec: globalAccAddressCodec{},
|
||||
ValidatorAddressCodec: globalValAddressCodec{},
|
||||
ProtoFiles: proto.HybridResolver,
|
||||
// using the global prefixes is a temporary solution until we refactor this
|
||||
// to get the address.Codec's from the container
|
||||
AddressCodec: address.Bech32Codec{
|
||||
Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix(),
|
||||
},
|
||||
ValidatorAddressCodec: address.Bech32Codec{
|
||||
Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix(),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, nil, nil, nil, nil, nil, err
|
||||
@ -243,33 +250,3 @@ func ProvideHeaderInfoService(app *AppBuilder) header.Service {
|
||||
func ProvideBasicManager(app *AppBuilder) module.BasicManager {
|
||||
return app.app.basicManager
|
||||
}
|
||||
|
||||
// globalAccAddressCodec is a temporary address codec that we will use until we
|
||||
// can populate it with the correct bech32 prefixes without depending on the global.
|
||||
type globalAccAddressCodec struct{}
|
||||
|
||||
func (g globalAccAddressCodec) StringToBytes(text string) ([]byte, error) {
|
||||
if text == "" {
|
||||
return nil, nil
|
||||
}
|
||||
return sdk.AccAddressFromBech32(text)
|
||||
}
|
||||
|
||||
func (g globalAccAddressCodec) BytesToString(bz []byte) (string, error) {
|
||||
if bz == nil {
|
||||
return "", nil
|
||||
}
|
||||
return sdk.AccAddress(bz).String(), nil
|
||||
}
|
||||
|
||||
// globalValAddressCodec is a temporary address codec that we will use until we
|
||||
// can populate it with the correct bech32 prefixes without depending on the global.
|
||||
type globalValAddressCodec struct{}
|
||||
|
||||
func (g globalValAddressCodec) StringToBytes(text string) ([]byte, error) {
|
||||
return sdk.ValAddressFromBech32(text)
|
||||
}
|
||||
|
||||
func (g globalValAddressCodec) BytesToString(bz []byte) (string, error) {
|
||||
return sdk.ValAddress(bz).String(), nil
|
||||
}
|
||||
|
||||
@ -12,11 +12,11 @@ import (
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"cosmossdk.io/log"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
bam "github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/codec/testutil"
|
||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||
@ -37,8 +37,9 @@ func NewApp(rootDir string, logger log.Logger) (servertypes.ABCI, error) {
|
||||
baseApp.MountStores(capKeyMainStore)
|
||||
baseApp.SetInitChainer(InitChainer(capKeyMainStore))
|
||||
|
||||
interfaceRegistry := codectypes.NewInterfaceRegistry()
|
||||
interfaceRegistry := testutil.CodecOptions{}.NewInterfaceRegistry()
|
||||
interfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &KVStoreTx{})
|
||||
baseApp.SetInterfaceRegistry(interfaceRegistry)
|
||||
|
||||
router := bam.NewMsgServiceRouter()
|
||||
router.SetInterfaceRegistry(interfaceRegistry)
|
||||
|
||||
@ -4,6 +4,9 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
|
||||
protov2 "google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
@ -83,7 +86,7 @@ var (
|
||||
)
|
||||
|
||||
func NewTx(key, value string, accAddress sdk.AccAddress) *KVStoreTx {
|
||||
bytes := fmt.Sprintf("%s=%s", key, value)
|
||||
bytes := fmt.Sprintf("%s=%s=%s", key, value, accAddress)
|
||||
return &KVStoreTx{
|
||||
key: []byte(key),
|
||||
value: []byte(value),
|
||||
@ -100,6 +103,10 @@ func (msg *KVStoreTx) GetMsgs() []sdk.Msg {
|
||||
return []sdk.Msg{msg}
|
||||
}
|
||||
|
||||
func (msg *KVStoreTx) GetMsgsV2() ([]protov2.Message, error) {
|
||||
return []protov2.Message{&bankv1beta1.MsgSend{FromAddress: msg.address.String()}}, nil // this is a hack for tests
|
||||
}
|
||||
|
||||
func (msg *KVStoreTx) GetSignBytes() []byte {
|
||||
return msg.bytes
|
||||
}
|
||||
@ -109,8 +116,8 @@ func (msg *KVStoreTx) ValidateBasic() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (msg *KVStoreTx) GetSigners() []sdk.AccAddress {
|
||||
return nil
|
||||
func (msg *KVStoreTx) GetSigners() ([][]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (msg *KVStoreTx) GetPubKeys() ([]cryptotypes.PubKey, error) { panic("GetPubKeys not implemented") }
|
||||
@ -128,6 +135,9 @@ func decodeTx(txBytes []byte) (sdk.Tx, error) {
|
||||
case 2:
|
||||
k, v := split[0], split[1]
|
||||
tx = &KVStoreTx{k, v, txBytes, nil}
|
||||
case 3:
|
||||
k, v, addr := split[0], split[1], split[2]
|
||||
tx = &KVStoreTx{k, v, txBytes, addr}
|
||||
default:
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrTxDecode, "too many '='")
|
||||
}
|
||||
|
||||
@ -9,20 +9,22 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"cosmossdk.io/log"
|
||||
|
||||
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
|
||||
reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1"
|
||||
"cosmossdk.io/client/v2/autocli"
|
||||
"cosmossdk.io/core/appmodule"
|
||||
"cosmossdk.io/log"
|
||||
"github.com/cosmos/cosmos-sdk/codec/address"
|
||||
|
||||
authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
dbm "github.com/cosmos/cosmos-db"
|
||||
"github.com/cosmos/gogoproto/proto"
|
||||
"github.com/spf13/cast"
|
||||
|
||||
simappparams "cosmossdk.io/simapp/params"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
"cosmossdk.io/x/evidence"
|
||||
evidencekeeper "cosmossdk.io/x/evidence/keeper"
|
||||
@ -133,6 +135,36 @@ var (
|
||||
_ servertypes.Application = (*SimApp)(nil)
|
||||
)
|
||||
|
||||
// stdAccAddressCodec is a temporary address codec that we will use until we
|
||||
// can populate it with the correct bech32 prefixes without depending on the global.
|
||||
type stdAccAddressCodec struct{}
|
||||
|
||||
func (g stdAccAddressCodec) StringToBytes(text string) ([]byte, error) {
|
||||
if text == "" {
|
||||
return nil, nil
|
||||
}
|
||||
return sdk.AccAddressFromBech32(text)
|
||||
}
|
||||
|
||||
func (g stdAccAddressCodec) BytesToString(bz []byte) (string, error) {
|
||||
if bz == nil {
|
||||
return "", nil
|
||||
}
|
||||
return sdk.AccAddress(bz).String(), nil
|
||||
}
|
||||
|
||||
// stdValAddressCodec is a temporary address codec that we will use until we
|
||||
// can populate it with the correct bech32 prefixes without depending on the global.
|
||||
type stdValAddressCodec struct{}
|
||||
|
||||
func (g stdValAddressCodec) StringToBytes(text string) ([]byte, error) {
|
||||
return sdk.ValAddressFromBech32(text)
|
||||
}
|
||||
|
||||
func (g stdValAddressCodec) BytesToString(bz []byte) (string, error) {
|
||||
return sdk.ValAddress(bz).String(), nil
|
||||
}
|
||||
|
||||
// SimApp extends an ABCI application, but with most of its parameters exported.
|
||||
// They are exported for convenience in creating helper functions, as object
|
||||
// capabilities aren't needed for testing.
|
||||
@ -195,12 +227,18 @@ func NewSimApp(
|
||||
appOpts servertypes.AppOptions,
|
||||
baseAppOptions ...func(*baseapp.BaseApp),
|
||||
) *SimApp {
|
||||
encodingConfig := simappparams.MakeTestEncodingConfig()
|
||||
|
||||
appCodec := encodingConfig.Codec
|
||||
legacyAmino := encodingConfig.Amino
|
||||
interfaceRegistry := encodingConfig.InterfaceRegistry
|
||||
txConfig := encodingConfig.TxConfig
|
||||
interfaceRegistry, _ := types.NewInterfaceRegistryWithOptions(types.InterfaceRegistryOptions{
|
||||
ProtoFiles: proto.HybridResolver,
|
||||
AddressCodec: address.Bech32Codec{
|
||||
Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix(),
|
||||
},
|
||||
ValidatorAddressCodec: address.Bech32Codec{
|
||||
Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix(),
|
||||
},
|
||||
})
|
||||
appCodec := codec.NewProtoCodec(interfaceRegistry)
|
||||
legacyAmino := codec.NewLegacyAmino()
|
||||
txConfig := tx.NewTxConfig(appCodec, tx.DefaultSignModes)
|
||||
|
||||
std.RegisterLegacyAminoCodec(legacyAmino)
|
||||
std.RegisterInterfaces(interfaceRegistry)
|
||||
@ -369,7 +407,7 @@ func NewSimApp(
|
||||
app.ModuleManager = module.NewManager(
|
||||
genutil.NewAppModule(
|
||||
app.AccountKeeper, app.StakingKeeper, app,
|
||||
encodingConfig.TxConfig,
|
||||
txConfig,
|
||||
),
|
||||
auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)),
|
||||
vesting.NewAppModule(app.AccountKeeper, app.BankKeeper),
|
||||
@ -405,8 +443,8 @@ func NewSimApp(
|
||||
},
|
||||
),
|
||||
})
|
||||
app.BasicModuleManager.RegisterLegacyAminoCodec(encodingConfig.Amino)
|
||||
app.BasicModuleManager.RegisterInterfaces(encodingConfig.InterfaceRegistry)
|
||||
app.BasicModuleManager.RegisterLegacyAminoCodec(legacyAmino)
|
||||
app.BasicModuleManager.RegisterInterfaces(interfaceRegistry)
|
||||
|
||||
// During begin block slashing happens after distr.BeginBlocker so that
|
||||
// there is nothing left over in the validator fee pool, so as to keep the
|
||||
@ -488,7 +526,7 @@ func NewSimApp(
|
||||
app.SetInitChainer(app.InitChainer)
|
||||
app.SetBeginBlocker(app.BeginBlocker)
|
||||
app.SetEndBlocker(app.EndBlocker)
|
||||
app.setAnteHandler(encodingConfig.TxConfig)
|
||||
app.setAnteHandler(txConfig)
|
||||
|
||||
// In v0.46, the SDK introduces _postHandlers_. PostHandlers are like
|
||||
// antehandlers, but are run _after_ the `runMsgs` execution. They are also
|
||||
|
||||
@ -561,6 +561,7 @@ func (s *E2ETestSuite) TestCLIQueryTxCmdByEvents() {
|
||||
s.Require().Contains(err.Error(), tc.expectErrStr)
|
||||
} else {
|
||||
var result sdk.TxResponse
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &result))
|
||||
s.Require().NotNil(result.Height)
|
||||
}
|
||||
@ -743,7 +744,9 @@ func (s *E2ETestSuite) TestCLISendGenerateSignAndBroadcast() {
|
||||
sigs, err = txBuilder.GetTx().GetSignaturesV2()
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(1, len(sigs))
|
||||
s.Require().Equal(val1.Address.String(), txBuilder.GetTx().GetSigners()[0].String())
|
||||
signers, err := txBuilder.GetTx().GetSigners()
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal([]byte(val1.Address), signers[0])
|
||||
|
||||
// Write the output to disk
|
||||
signedTxFile := testutil.WriteToNewTempFile(s.T(), signedTx.String())
|
||||
@ -1580,7 +1583,9 @@ func (s *E2ETestSuite) TestSignWithMultiSignersAminoJSON() {
|
||||
)
|
||||
txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))))
|
||||
txBuilder.SetGasLimit(testdata.NewTestGasLimit() * 2)
|
||||
require.Equal([]sdk.AccAddress{val0.Address, val1.Address}, txBuilder.GetTx().GetSigners())
|
||||
signers, err := txBuilder.GetTx().GetSigners()
|
||||
require.NoError(err)
|
||||
require.Equal([][]byte{val0.Address, val1.Address}, signers)
|
||||
|
||||
// Write the unsigned tx into a file.
|
||||
txJSON, err := val0.ClientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx())
|
||||
|
||||
@ -1102,7 +1102,9 @@ func (s *E2ETestSuite) mkTxBuilder() client.TxBuilder {
|
||||
txBuilder.SetFeeAmount(feeAmount)
|
||||
txBuilder.SetGasLimit(gasLimit)
|
||||
txBuilder.SetMemo("foobar")
|
||||
s.Require().Equal([]sdk.AccAddress{val.Address}, txBuilder.GetTx().GetSigners())
|
||||
signers, err := txBuilder.GetTx().GetSigners()
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal([][]byte{val.Address}, signers)
|
||||
|
||||
// setup txFactory
|
||||
txFactory := clienttx.Factory{}.
|
||||
@ -1112,7 +1114,7 @@ func (s *E2ETestSuite) mkTxBuilder() client.TxBuilder {
|
||||
WithSignMode(signing.SignMode_SIGN_MODE_DIRECT)
|
||||
|
||||
// Sign Tx.
|
||||
err := authclient.SignTx(txFactory, val.ClientCtx, val.Moniker, txBuilder, false, true)
|
||||
err = authclient.SignTx(txFactory, val.ClientCtx, val.Moniker, txBuilder, false, true)
|
||||
s.Require().NoError(err)
|
||||
|
||||
return txBuilder
|
||||
|
||||
@ -50,6 +50,7 @@ import (
|
||||
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
@ -131,7 +132,7 @@ func TestAminoJSON_Equivalence(t *testing.T) {
|
||||
require.Equal(t, string(legacyAminoJSON), string(aminoJSON))
|
||||
|
||||
// test amino json signer handler equivalence
|
||||
gogoMsg, ok := gogo.(types.Msg)
|
||||
gogoMsg, ok := gogo.(legacytx.LegacyMsg)
|
||||
if !ok {
|
||||
// not signable
|
||||
return
|
||||
@ -440,7 +441,7 @@ func TestAminoJSON_LegacyParity(t *testing.T) {
|
||||
require.Equal(t, string(gogoBytes), string(newGogoBytes))
|
||||
|
||||
// test amino json signer handler equivalence
|
||||
msg, ok := tc.gogo.(types.Msg)
|
||||
msg, ok := tc.gogo.(legacytx.LegacyMsg)
|
||||
if !ok {
|
||||
// not signable
|
||||
return
|
||||
|
||||
@ -23,6 +23,7 @@ import (
|
||||
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
|
||||
authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
@ -101,7 +102,7 @@ func TestDecode(t *testing.T) {
|
||||
Sequence: accSeq,
|
||||
}
|
||||
|
||||
gogoMsg, ok := gogo.(sdk.Msg)
|
||||
gogoMsg, ok := gogo.(legacytx.LegacyMsg)
|
||||
require.True(t, ok)
|
||||
|
||||
err = txBuilder.SetMsgs(gogoMsg)
|
||||
|
||||
3
testutil/testdata/testpb/tx.proto
vendored
3
testutil/testdata/testpb/tx.proto
vendored
@ -30,8 +30,9 @@ message MsgCreateDogResponse {
|
||||
// TestMsg is msg type for testing protobuf message using any, as defined in
|
||||
// https://github.com/cosmos/cosmos-sdk/issues/6213.
|
||||
message TestMsg {
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
option (cosmos.msg.v1.signer) = "signers";
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
option (amino.name) = "testpb/TestMsg";
|
||||
|
||||
repeated string signers = 1;
|
||||
}
|
||||
|
||||
@ -79,12 +79,20 @@ func (c *Client) PreprocessOperationsToOptions(_ context.Context, req *types.Con
|
||||
}
|
||||
|
||||
// get the signers
|
||||
signers := tx.GetSigners()
|
||||
signers, err := tx.GetSigners()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signersStr := make([]string, len(signers))
|
||||
accountIdentifiers := make([]*types.AccountIdentifier, len(signers))
|
||||
|
||||
for i, sig := range signers {
|
||||
addr := sig.String()
|
||||
addr, err := c.config.InterfaceRegistry.SigningContext().AddressCodec().BytesToString(sig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signersStr[i] = addr
|
||||
accountIdentifiers[i] = &types.AccountIdentifier{
|
||||
Address: addr,
|
||||
|
||||
@ -32,6 +32,7 @@ import (
|
||||
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
|
||||
tmrpc "github.com/cometbft/cometbft/rpc/client"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/query"
|
||||
)
|
||||
|
||||
@ -71,14 +72,12 @@ func NewClient(cfg *Config) (*Client, error) {
|
||||
|
||||
var supportedOperations []string
|
||||
for _, ii := range cfg.InterfaceRegistry.ListImplementations(sdk.MsgInterfaceProtoName) {
|
||||
resolvedMsg, err := cfg.InterfaceRegistry.Resolve(ii)
|
||||
_, err := cfg.InterfaceRegistry.Resolve(ii)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := resolvedMsg.(sdk.Msg); ok {
|
||||
supportedOperations = append(supportedOperations, ii)
|
||||
}
|
||||
supportedOperations = append(supportedOperations, ii)
|
||||
}
|
||||
|
||||
supportedOperations = append(
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
package rosetta
|
||||
|
||||
import (
|
||||
"github.com/cosmos/gogoproto/proto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/address"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authcodec "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
bankcodec "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
@ -11,7 +15,20 @@ import (
|
||||
// MakeCodec generates the codec required to interact
|
||||
// with the cosmos APIs used by the rosetta gateway
|
||||
func MakeCodec() (*codec.ProtoCodec, codectypes.InterfaceRegistry) {
|
||||
ir := codectypes.NewInterfaceRegistry()
|
||||
ir, err := codectypes.NewInterfaceRegistryWithOptions(
|
||||
codectypes.InterfaceRegistryOptions{
|
||||
ProtoFiles: proto.HybridResolver,
|
||||
AddressCodec: address.Bech32Codec{
|
||||
Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix(),
|
||||
},
|
||||
ValidatorAddressCodec: address.Bech32Codec{
|
||||
Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix(),
|
||||
},
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cdc := codec.NewProtoCodec(ir)
|
||||
|
||||
authcodec.RegisterInterfaces(ir)
|
||||
|
||||
@ -15,6 +15,7 @@ import (
|
||||
secp "github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||
|
||||
sdkmath "cosmossdk.io/math"
|
||||
|
||||
crgerrs "cosmossdk.io/tools/rosetta/lib/errors"
|
||||
crgtypes "cosmossdk.io/tools/rosetta/lib/types"
|
||||
|
||||
@ -146,16 +147,11 @@ func (c converter) UnsignedTx(ops []*rosettatypes.Operation) (tx authsigning.Tx,
|
||||
for i := 0; i < len(ops); i++ {
|
||||
op := ops[i]
|
||||
|
||||
protoMessage, err := c.ir.Resolve(op.Type)
|
||||
msg, err := c.ir.Resolve(op.Type)
|
||||
if err != nil {
|
||||
return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, "operation not found: "+op.Type)
|
||||
}
|
||||
|
||||
msg, ok := protoMessage.(sdk.Msg)
|
||||
if !ok {
|
||||
return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, "operation is not a valid supported sdk.Msg: "+op.Type)
|
||||
}
|
||||
|
||||
err = c.Msg(op.Metadata, msg)
|
||||
if err != nil {
|
||||
return nil, crgerrs.WrapError(crgerrs.ErrCodec, err.Error())
|
||||
@ -171,7 +167,11 @@ func (c converter) UnsignedTx(ops []*rosettatypes.Operation) (tx authsigning.Tx,
|
||||
}
|
||||
}
|
||||
|
||||
signers := msg.GetSigners()
|
||||
signers, _, err := c.cdc.GetMsgV1Signers(msg)
|
||||
if err != nil {
|
||||
return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, err.Error())
|
||||
}
|
||||
|
||||
// check if there are enough signers
|
||||
if len(signers) == 0 {
|
||||
return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, fmt.Sprintf("operation at index %d got no signers", op.OperationIdentifier.Index))
|
||||
@ -249,12 +249,22 @@ func (c converter) Ops(status string, msg sdk.Msg) ([]*rosettatypes.Operation, e
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ops := make([]*rosettatypes.Operation, len(msg.GetSigners()))
|
||||
for i, signer := range msg.GetSigners() {
|
||||
signers, _, err := c.cdc.GetMsgV1Signers(msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ops := make([]*rosettatypes.Operation, len(signers))
|
||||
for i, signer := range signers {
|
||||
signerStr, err := c.ir.SigningContext().AddressCodec().BytesToString(signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
op := &rosettatypes.Operation{
|
||||
Type: opName,
|
||||
Status: &status,
|
||||
Account: &rosettatypes.AccountIdentifier{Address: signer.String()},
|
||||
Account: &rosettatypes.AccountIdentifier{Address: signerStr},
|
||||
Metadata: meta,
|
||||
}
|
||||
|
||||
@ -594,13 +604,24 @@ func (c converter) OpsAndSigners(txBytes []byte) (ops []*rosettatypes.Operation,
|
||||
return nil, nil, crgerrs.WrapError(crgerrs.ErrCodec, err.Error())
|
||||
}
|
||||
|
||||
for _, signer := range txBuilder.GetTx().GetSigners() {
|
||||
signerAddrs, err := txBuilder.GetTx().GetSigners()
|
||||
if err != nil {
|
||||
return nil, nil, crgerrs.WrapError(crgerrs.ErrBadArgument, err.Error())
|
||||
}
|
||||
|
||||
for _, signer := range signerAddrs {
|
||||
var signerStr string
|
||||
signerStr, err = c.ir.SigningContext().AddressCodec().BytesToString(signer)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
signers = append(signers, &rosettatypes.AccountIdentifier{
|
||||
Address: signer.String(),
|
||||
Address: signerStr,
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
return ops, signers, nil
|
||||
}
|
||||
|
||||
func (c converter) SignedTx(txBytes []byte, signatures []*rosettatypes.Signature) (signedTxBytes []byte, err error) {
|
||||
@ -676,7 +697,11 @@ func (c converter) SigningComponents(tx authsigning.Tx, metadata *ConstructionMe
|
||||
return nil, nil, crgerrs.WrapError(crgerrs.ErrBadArgument, err.Error())
|
||||
}
|
||||
|
||||
signers := tx.GetSigners()
|
||||
signers, err := tx.GetSigners()
|
||||
if err != nil {
|
||||
return nil, nil, crgerrs.WrapError(crgerrs.ErrBadArgument, err.Error())
|
||||
}
|
||||
|
||||
// assert the signers data provided in options are the same as the expected signing accounts
|
||||
// and that the number of rosetta provided public keys equals the one of the signers
|
||||
if len(metadata.SignersData) != len(signers) || len(signers) != len(rosPubKeys) {
|
||||
@ -704,16 +729,21 @@ func (c converter) SigningComponents(tx authsigning.Tx, metadata *ConstructionMe
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if !bytes.Equal(pubKey.Address().Bytes(), signer.Bytes()) {
|
||||
if !bytes.Equal(pubKey.Address().Bytes(), signer) {
|
||||
return nil, nil, crgerrs.WrapError(
|
||||
crgerrs.ErrBadArgument,
|
||||
fmt.Sprintf("public key at index %d does not match the expected transaction signer: %X <-> %X", i, rosPubKeys[i].Bytes, signer.Bytes()),
|
||||
fmt.Sprintf("public key at index %d does not match the expected transaction signer: %X <-> %X", i, rosPubKeys[i].Bytes, signer),
|
||||
)
|
||||
}
|
||||
|
||||
signerStr, err := c.ir.SigningContext().AddressCodec().BytesToString(signer)
|
||||
if err != nil {
|
||||
return nil, nil, crgerrs.WrapError(crgerrs.ErrBadArgument, err.Error())
|
||||
}
|
||||
|
||||
// set the signer data
|
||||
signerData := authsigning.SignerData{
|
||||
Address: signer.String(),
|
||||
Address: signerStr,
|
||||
ChainID: metadata.ChainID,
|
||||
AccountNumber: metadata.SignersData[i].AccountNumber,
|
||||
Sequence: metadata.SignersData[i].Sequence,
|
||||
@ -728,7 +758,7 @@ func (c converter) SigningComponents(tx authsigning.Tx, metadata *ConstructionMe
|
||||
|
||||
// set payload
|
||||
payloadsToSign[i] = &rosettatypes.SigningPayload{
|
||||
AccountIdentifier: &rosettatypes.AccountIdentifier{Address: signer.String()},
|
||||
AccountIdentifier: &rosettatypes.AccountIdentifier{Address: signerStr},
|
||||
Bytes: signBytes,
|
||||
SignatureType: rosettatypes.Ecdsa,
|
||||
}
|
||||
|
||||
@ -172,9 +172,11 @@ func (s *ConverterTestSuite) TestOpsAndSigners() {
|
||||
ops, signers, err := s.c.ToRosetta().OpsAndSigners(txBytes)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().Equal(len(ops), len(sdkTx.GetMsgs())*len(sdkTx.GetSigners()), "operation number mismatch")
|
||||
signerAddrs, err := sdkTx.GetSigners()
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(len(ops), len(sdkTx.GetMsgs())*len(signerAddrs), "operation number mismatch")
|
||||
|
||||
s.Require().Equal(len(signers), len(sdkTx.GetSigners()), "signers number mismatch")
|
||||
s.Require().Equal(len(signers), len(signerAddrs), "signers number mismatch")
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -8,8 +8,10 @@ import (
|
||||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
protov2 "google.golang.org/protobuf/proto"
|
||||
|
||||
"cosmossdk.io/log"
|
||||
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/mempool"
|
||||
@ -52,7 +54,7 @@ type testTx struct {
|
||||
strAddress string
|
||||
}
|
||||
|
||||
func (tx testTx) GetSigners() []sdk.AccAddress { panic("not implemented") }
|
||||
func (tx testTx) GetSigners() ([][]byte, error) { panic("not implemented") }
|
||||
|
||||
func (tx testTx) GetPubKeys() ([]cryptotypes.PubKey, error) { panic("not implemented") }
|
||||
|
||||
@ -74,6 +76,8 @@ var (
|
||||
|
||||
func (tx testTx) GetMsgs() []sdk.Msg { return nil }
|
||||
|
||||
func (tx testTx) GetMsgsV2() ([]protov2.Message, error) { return nil, nil }
|
||||
|
||||
func (tx testTx) ValidateBasic() error { return nil }
|
||||
|
||||
func (tx testTx) String() string {
|
||||
@ -88,9 +92,11 @@ func (sigErrTx) Size() int64 { return 0 }
|
||||
|
||||
func (sigErrTx) GetMsgs() []sdk.Msg { return nil }
|
||||
|
||||
func (sigErrTx) GetMsgsV2() ([]protov2.Message, error) { return nil, nil }
|
||||
|
||||
func (sigErrTx) ValidateBasic() error { return nil }
|
||||
|
||||
func (sigErrTx) GetSigners() []sdk.AccAddress { return nil }
|
||||
func (sigErrTx) GetSigners() ([][]byte, error) { return nil, nil }
|
||||
|
||||
func (sigErrTx) GetPubKeys() ([]cryptotypes.PubKey, error) { return nil, nil }
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ package testutil
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/std"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
@ -22,7 +23,7 @@ type TestEncodingConfig struct {
|
||||
|
||||
func MakeTestEncodingConfig(modules ...module.AppModuleBasic) TestEncodingConfig {
|
||||
aminoCodec := codec.NewLegacyAmino()
|
||||
interfaceRegistry := types.NewInterfaceRegistry()
|
||||
interfaceRegistry := testutil.CodecOptions{}.NewInterfaceRegistry()
|
||||
codec := codec.NewProtoCodec(interfaceRegistry)
|
||||
|
||||
encCfg := TestEncodingConfig{
|
||||
@ -43,7 +44,7 @@ func MakeTestEncodingConfig(modules ...module.AppModuleBasic) TestEncodingConfig
|
||||
}
|
||||
|
||||
func MakeTestTxConfig() client.TxConfig {
|
||||
interfaceRegistry := types.NewInterfaceRegistry()
|
||||
interfaceRegistry := testutil.CodecOptions{}.NewInterfaceRegistry()
|
||||
cdc := codec.NewProtoCodec(interfaceRegistry)
|
||||
return tx.NewTxConfig(cdc, tx.DefaultSignModes)
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"github.com/cosmos/gogoproto/proto"
|
||||
|
||||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
)
|
||||
@ -182,15 +183,15 @@ func (s SearchTxsResult) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error
|
||||
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
|
||||
func (r TxResponse) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
|
||||
if r.Tx != nil {
|
||||
var tx Tx
|
||||
var tx HasMsgs
|
||||
return unpacker.UnpackAny(r.Tx, &tx)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTx unpacks the Tx from within a TxResponse and returns it
|
||||
func (r TxResponse) GetTx() Tx {
|
||||
if tx, ok := r.Tx.GetCachedValue().(Tx); ok {
|
||||
func (r TxResponse) GetTx() HasMsgs {
|
||||
if tx, ok := r.Tx.GetCachedValue().(HasMsgs); ok {
|
||||
return tx
|
||||
}
|
||||
return nil
|
||||
|
||||
@ -4,7 +4,9 @@ import (
|
||||
"fmt"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
protov2 "google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -17,7 +19,6 @@ const MaxGasWanted = uint64((1 << 63) - 1)
|
||||
// Interface implementation checks.
|
||||
var (
|
||||
_, _, _, _ codectypes.UnpackInterfacesMessage = &Tx{}, &TxBody{}, &AuthInfo{}, &SignerInfo{}
|
||||
_ sdk.Tx = &Tx{}
|
||||
)
|
||||
|
||||
// GetMsgs implements the GetMsgs method on sdk.Tx.
|
||||
@ -89,41 +90,49 @@ func (t *Tx) ValidateBasic() error {
|
||||
return sdkerrors.ErrNoSignatures
|
||||
}
|
||||
|
||||
if len(sigs) != len(t.GetSigners()) {
|
||||
return errorsmod.Wrapf(
|
||||
sdkerrors.ErrUnauthorized,
|
||||
"wrong number of signers; expected %d, got %d", len(t.GetSigners()), len(sigs),
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSigners retrieves all the signers of a tx.
|
||||
// This includes all unique signers of the messages (in order),
|
||||
// as well as the FeePayer (if specified and not already included).
|
||||
func (t *Tx) GetSigners() []sdk.AccAddress {
|
||||
var signers []sdk.AccAddress
|
||||
func (t *Tx) GetSigners(cdc codec.Codec) ([][]byte, []protov2.Message, error) {
|
||||
var signers [][]byte
|
||||
seen := map[string]bool{}
|
||||
|
||||
for _, msg := range t.GetMsgs() {
|
||||
for _, addr := range msg.GetSigners() {
|
||||
if !seen[addr.String()] {
|
||||
signers = append(signers, addr)
|
||||
seen[addr.String()] = true
|
||||
var msgsv2 []protov2.Message
|
||||
for _, msg := range t.Body.Messages {
|
||||
xs, msgv2, err := cdc.GetMsgAnySigners(msg)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
msgsv2 = append(msgsv2, msgv2)
|
||||
|
||||
for _, signer := range xs {
|
||||
if !seen[string(signer)] {
|
||||
signers = append(signers, signer)
|
||||
seen[string(signer)] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ensure any specified fee payer is included in the required signers (at the end)
|
||||
feePayer := t.AuthInfo.Fee.Payer
|
||||
if feePayer != "" && !seen[feePayer] {
|
||||
payerAddr := sdk.MustAccAddressFromBech32(feePayer)
|
||||
signers = append(signers, payerAddr)
|
||||
seen[feePayer] = true
|
||||
var feePayerAddr []byte
|
||||
if feePayer != "" {
|
||||
var err error
|
||||
feePayerAddr, err = cdc.InterfaceRegistry().SigningContext().AddressCodec().StringToBytes(feePayer)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
if feePayerAddr != nil && !seen[string(feePayerAddr)] {
|
||||
signers = append(signers, feePayerAddr)
|
||||
seen[string(feePayerAddr)] = true
|
||||
}
|
||||
|
||||
return signers
|
||||
return signers, msgsv2, nil
|
||||
}
|
||||
|
||||
func (t *Tx) GetGas() uint64 {
|
||||
@ -134,13 +143,22 @@ func (t *Tx) GetFee() sdk.Coins {
|
||||
return t.AuthInfo.Fee.Amount
|
||||
}
|
||||
|
||||
func (t *Tx) FeePayer() sdk.AccAddress {
|
||||
func (t *Tx) FeePayer(cdc codec.Codec) []byte {
|
||||
feePayer := t.AuthInfo.Fee.Payer
|
||||
if feePayer != "" {
|
||||
return sdk.MustAccAddressFromBech32(feePayer)
|
||||
feePayerAddr, err := cdc.InterfaceRegistry().SigningContext().AddressCodec().StringToBytes(feePayer)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return feePayerAddr
|
||||
}
|
||||
// use first signer as default if no payer specified
|
||||
return t.GetSigners()[0]
|
||||
signers, _, err := t.GetSigners(cdc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return signers[0]
|
||||
}
|
||||
|
||||
func (t *Tx) FeeGranter() sdk.AccAddress {
|
||||
@ -205,8 +223,8 @@ func (m *SignerInfo) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
|
||||
func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
|
||||
registry.RegisterInterface(msgResponseInterfaceProtoName, (*MsgResponse)(nil))
|
||||
|
||||
registry.RegisterInterface("cosmos.tx.v1beta1.Tx", (*sdk.Tx)(nil))
|
||||
registry.RegisterImplementations((*sdk.Tx)(nil), &Tx{})
|
||||
registry.RegisterInterface("cosmos.tx.v1beta1.Tx", (*sdk.HasMsgs)(nil))
|
||||
registry.RegisterImplementations((*sdk.HasMsgs)(nil), &Tx{})
|
||||
|
||||
registry.RegisterInterface("cosmos.tx.v1beta1.TxExtensionOptionI", (*TxExtensionOptionI)(nil))
|
||||
}
|
||||
|
||||
@ -6,15 +6,20 @@ import (
|
||||
strings "strings"
|
||||
|
||||
"github.com/cosmos/gogoproto/proto"
|
||||
protov2 "google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
)
|
||||
|
||||
type (
|
||||
// Msg defines the interface a transaction message must fulfill.
|
||||
Msg interface {
|
||||
proto.Message
|
||||
// Msg defines the interface a transaction message needed to fulfill.
|
||||
Msg = proto.Message
|
||||
|
||||
// LegacyMsg defines the interface a transaction message needed to fulfill up through
|
||||
// v0.47.
|
||||
LegacyMsg interface {
|
||||
Msg
|
||||
|
||||
// GetSigners returns the addrs of signers that must sign.
|
||||
// CONTRACT: All signatures must be present to be valid.
|
||||
@ -36,21 +41,27 @@ type (
|
||||
GetSignature() []byte
|
||||
}
|
||||
|
||||
// Tx defines the interface a transaction must fulfill.
|
||||
Tx interface {
|
||||
HasValidateBasic
|
||||
|
||||
// HasMsgs defines an interface a transaction must fulfill.
|
||||
HasMsgs interface {
|
||||
// GetMsgs gets the all the transaction's messages.
|
||||
GetMsgs() []Msg
|
||||
}
|
||||
|
||||
// Tx defines an interface a transaction must fulfill.
|
||||
Tx interface {
|
||||
HasMsgs
|
||||
|
||||
// GetMsgsV2 gets the transaction's messages as google.golang.org/protobuf/proto.Message's.
|
||||
GetMsgsV2() ([]protov2.Message, error)
|
||||
}
|
||||
|
||||
// FeeTx defines the interface to be implemented by Tx to use the FeeDecorators
|
||||
FeeTx interface {
|
||||
Tx
|
||||
GetGas() uint64
|
||||
GetFee() Coins
|
||||
FeePayer() AccAddress
|
||||
FeeGranter() AccAddress
|
||||
FeePayer() []byte
|
||||
FeeGranter() string
|
||||
}
|
||||
|
||||
// TxWithMemo must have GetMemo() method to use ValidateMemoDecorator
|
||||
@ -84,7 +95,11 @@ type TxDecoder func(txBytes []byte) (Tx, error)
|
||||
type TxEncoder func(tx Tx) ([]byte, error)
|
||||
|
||||
// MsgTypeURL returns the TypeURL of a `sdk.Msg`.
|
||||
func MsgTypeURL(msg Msg) string {
|
||||
func MsgTypeURL(msg proto.Message) string {
|
||||
if m, ok := msg.(protov2.Message); ok {
|
||||
return "/" + string(m.ProtoReflect().Descriptor().FullName())
|
||||
}
|
||||
|
||||
return "/" + proto.MessageName(msg)
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
@ -31,6 +32,7 @@ func (s *testMsgSuite) TestMsg() {
|
||||
|
||||
func (s *testMsgSuite) TestMsgTypeURL() {
|
||||
s.Require().Equal("/testpb.TestMsg", sdk.MsgTypeURL(new(testdata.TestMsg)))
|
||||
s.Require().Equal("/google.protobuf.Any", sdk.MsgTypeURL(&anypb.Any{}))
|
||||
}
|
||||
|
||||
func (s *testMsgSuite) TestGetMsgFromTypeURL() {
|
||||
|
||||
@ -119,8 +119,10 @@ func TestAnteHandlerSigErrors(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// tx.GetSigners returns addresses in correct order: addr1, addr2, addr3
|
||||
expectedSigners := []sdk.AccAddress{addr0, addr1, addr2}
|
||||
require.Equal(t, expectedSigners, tx.GetSigners())
|
||||
expectedSigners := [][]byte{addr0, addr1, addr2}
|
||||
signers, err := tx.GetSigners()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expectedSigners, signers)
|
||||
|
||||
return TestCaseArgs{
|
||||
accNums: accNums,
|
||||
|
||||
@ -31,8 +31,10 @@ func (vbd ValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulat
|
||||
return next(ctx, tx, simulate)
|
||||
}
|
||||
|
||||
if err := tx.ValidateBasic(); err != nil {
|
||||
return ctx, err
|
||||
if validateBasic, ok := tx.(sdk.HasValidateBasic); ok {
|
||||
if err := validateBasic.ValidateBasic(); err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
}
|
||||
|
||||
return next(ctx, tx, simulate)
|
||||
@ -108,7 +110,12 @@ func (cgts ConsumeTxSizeGasDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, sim
|
||||
}
|
||||
n := len(sigs)
|
||||
|
||||
for i, signer := range sigTx.GetSigners() {
|
||||
signers, err := sigTx.GetSigners()
|
||||
if err != nil {
|
||||
return sdk.Context{}, err
|
||||
}
|
||||
|
||||
for i, signer := range signers {
|
||||
// if signature is already filled in, no need to simulate gas cost
|
||||
if i < n && !isIncompleteSignature(sigs[i].Data) {
|
||||
continue
|
||||
|
||||
@ -3,6 +3,7 @@ package ante
|
||||
import (
|
||||
"context"
|
||||
|
||||
"cosmossdk.io/core/address"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
)
|
||||
@ -14,6 +15,7 @@ type AccountKeeper interface {
|
||||
GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI
|
||||
SetAccount(ctx context.Context, acc sdk.AccountI)
|
||||
GetModuleAddress(moduleName string) sdk.AccAddress
|
||||
AddressCodec() address.Codec
|
||||
}
|
||||
|
||||
// FeegrantKeeper defines the expected feegrant keeper.
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package ante
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
@ -85,17 +86,22 @@ func (dfd DeductFeeDecorator) checkDeductFee(ctx sdk.Context, sdkTx sdk.Tx, fee
|
||||
|
||||
// if feegranter set deduct fee from feegranter account.
|
||||
// this works with only when feegrant enabled.
|
||||
if feeGranter != nil {
|
||||
if feeGranter != "" {
|
||||
feeGranterAddr, err := sdk.AccAddressFromBech32(feeGranter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if dfd.feegrantKeeper == nil {
|
||||
return sdkerrors.ErrInvalidRequest.Wrap("fee grants are not enabled")
|
||||
} else if !feeGranter.Equals(feePayer) {
|
||||
err := dfd.feegrantKeeper.UseGrantedFees(ctx, feeGranter, feePayer, fee, sdkTx.GetMsgs())
|
||||
} else if !bytes.Equal(feeGranterAddr, feePayer) {
|
||||
err := dfd.feegrantKeeper.UseGrantedFees(ctx, feeGranterAddr, feePayer, fee, sdkTx.GetMsgs())
|
||||
if err != nil {
|
||||
return errorsmod.Wrapf(err, "%s does not allow to pay fees for %s", feeGranter, feePayer)
|
||||
}
|
||||
}
|
||||
|
||||
deductFeesFrom = feeGranter
|
||||
deductFeesFrom = feeGranterAddr
|
||||
}
|
||||
|
||||
deductFeesFromAcc := dfd.accountKeeper.GetAccount(ctx, deductFeesFrom)
|
||||
@ -115,7 +121,7 @@ func (dfd DeductFeeDecorator) checkDeductFee(ctx sdk.Context, sdkTx sdk.Tx, fee
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeTx,
|
||||
sdk.NewAttribute(sdk.AttributeKeyFee, fee.String()),
|
||||
sdk.NewAttribute(sdk.AttributeKeyFeePayer, deductFeesFrom.String()),
|
||||
sdk.NewAttribute(sdk.AttributeKeyFeePayer, sdk.AccAddress(deductFeesFrom).String()),
|
||||
),
|
||||
}
|
||||
ctx.EventManager().EmitEvents(events)
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
txsigning "cosmossdk.io/x/tx/signing"
|
||||
|
||||
@ -69,9 +70,20 @@ func (spkd SetPubKeyDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate b
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
signers := sigTx.GetSigners()
|
||||
|
||||
signers, err := sigTx.GetSigners()
|
||||
if err != nil {
|
||||
return sdk.Context{}, err
|
||||
}
|
||||
|
||||
signerStrs := make([]string, len(signers))
|
||||
for i, pk := range pubkeys {
|
||||
var err error
|
||||
signerStrs[i], err = spkd.ak.AddressCodec().BytesToString(signers[i])
|
||||
if err != nil {
|
||||
return sdk.Context{}, err
|
||||
}
|
||||
|
||||
// PublicKey was omitted from slice since it has already been set in context
|
||||
if pk == nil {
|
||||
if !simulate {
|
||||
@ -82,7 +94,7 @@ func (spkd SetPubKeyDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate b
|
||||
// Only make check if simulate=false
|
||||
if !simulate && !bytes.Equal(pk.Address(), signers[i]) {
|
||||
return ctx, errorsmod.Wrapf(sdkerrors.ErrInvalidPubKey,
|
||||
"pubKey does not match signer address %s with signer index: %d", signers[i], i)
|
||||
"pubKey does not match signer address %s with signer index: %d", signerStrs[i], i)
|
||||
}
|
||||
|
||||
acc, err := GetSignerAcc(ctx, spkd.ak, signers[i])
|
||||
@ -112,7 +124,7 @@ func (spkd SetPubKeyDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate b
|
||||
var events sdk.Events
|
||||
for i, sig := range sigs {
|
||||
events = append(events, sdk.NewEvent(sdk.EventTypeTx,
|
||||
sdk.NewAttribute(sdk.AttributeKeyAccountSequence, fmt.Sprintf("%s/%d", signers[i], sig.Sequence)),
|
||||
sdk.NewAttribute(sdk.AttributeKeyAccountSequence, fmt.Sprintf("%s/%d", signerStrs[i], sig.Sequence)),
|
||||
))
|
||||
|
||||
sigBzs, err := signatureDataToBz(sig.Data)
|
||||
@ -165,10 +177,13 @@ func (sgcd SigGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
|
||||
|
||||
// stdSigs contains the sequence number, account number, and signatures.
|
||||
// When simulating, this would just be a 0-length slice.
|
||||
signerAddrs := sigTx.GetSigners()
|
||||
signers, err := sigTx.GetSigners()
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
for i, sig := range sigs {
|
||||
signerAcc, err := GetSignerAcc(ctx, sgcd.ak, signerAddrs[i])
|
||||
signerAcc, err := GetSignerAcc(ctx, sgcd.ak, signers[i])
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
@ -250,15 +265,18 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
signerAddrs := sigTx.GetSigners()
|
||||
signers, err := sigTx.GetSigners()
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
// check that signer length and signature length are the same
|
||||
if len(sigs) != len(signerAddrs) {
|
||||
return ctx, errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signer; expected: %d, got %d", len(signerAddrs), len(sigs))
|
||||
if len(sigs) != len(signers) {
|
||||
return ctx, errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signer; expected: %d, got %d", len(signers), len(sigs))
|
||||
}
|
||||
|
||||
for i, sig := range sigs {
|
||||
acc, err := GetSignerAcc(ctx, svd.ak, signerAddrs[i])
|
||||
acc, err := GetSignerAcc(ctx, svd.ak, signers[i])
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
@ -349,8 +367,13 @@ func (isd IncrementSequenceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, sim
|
||||
}
|
||||
|
||||
// increment sequence of all signers
|
||||
for _, addr := range sigTx.GetSigners() {
|
||||
acc := isd.ak.GetAccount(ctx, addr)
|
||||
signers, err := sigTx.GetSigners()
|
||||
if err != nil {
|
||||
return sdk.Context{}, err
|
||||
}
|
||||
|
||||
for _, signer := range signers {
|
||||
acc := isd.ak.GetAccount(ctx, signer)
|
||||
if err := acc.SetSequence(acc.GetSequence() + 1); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -516,10 +539,10 @@ func signatureDataToBz(data signing.SignatureData) ([][]byte, error) {
|
||||
sigs = append(sigs, nestedSigs...)
|
||||
}
|
||||
|
||||
multisig := cryptotypes.MultiSignature{
|
||||
multiSignature := cryptotypes.MultiSignature{
|
||||
Signatures: sigs,
|
||||
}
|
||||
aggregatedSig, err := multisig.Marshal()
|
||||
aggregatedSig, err := multiSignature.Marshal()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -7,12 +7,13 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"cosmossdk.io/core/address"
|
||||
"cosmossdk.io/math"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
rpcclientmock "github.com/cometbft/cometbft/rpc/client/mock"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"cosmossdk.io/core/address"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
|
||||
@ -385,7 +386,7 @@ func (s *CLITestSuite) TestCLISendGenerateSignAndBroadcast() {
|
||||
// Test validate-signatures
|
||||
res, err := authtestutil.TxValidateSignaturesExec(s.clientCtx, unsignedTxFile.Name())
|
||||
s.Require().EqualError(err, "signatures validation failed")
|
||||
s.Require().True(strings.Contains(res.String(), fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n\n", s.val.String())))
|
||||
s.Require().Contains(res.String(), fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n\n", s.val.String()))
|
||||
|
||||
// Test sign
|
||||
|
||||
@ -409,7 +410,9 @@ func (s *CLITestSuite) TestCLISendGenerateSignAndBroadcast() {
|
||||
sigs, err = txBuilder.GetTx().GetSignaturesV2()
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(1, len(sigs))
|
||||
s.Require().Equal(s.val.String(), txBuilder.GetTx().GetSigners()[0].String())
|
||||
signers, err := txBuilder.GetTx().GetSigners()
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal([]byte(s.val), signers[0])
|
||||
|
||||
// Write the output to disk
|
||||
signedTxFile := testutil.WriteToNewTempFile(s.T(), signedTx.String())
|
||||
@ -922,7 +925,9 @@ func (s *CLITestSuite) TestSignWithMultiSignersAminoJSON() {
|
||||
)
|
||||
txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))))
|
||||
txBuilder.SetGasLimit(testdata.NewTestGasLimit() * 2)
|
||||
s.Require().Equal([]sdk.AccAddress{val0, val1}, txBuilder.GetTx().GetSigners())
|
||||
signers, err := txBuilder.GetTx().GetSigners()
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal([][]byte{val0, val1}, signers)
|
||||
|
||||
// Write the unsigned tx into a file.
|
||||
txJSON, err := s.clientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx())
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
@ -65,11 +66,20 @@ func printAndValidateSigs(
|
||||
) bool {
|
||||
sigTx := tx.(authsigning.SigVerifiableTx)
|
||||
signModeHandler := clientCtx.TxConfig.SignModeHandler()
|
||||
addrCdc := clientCtx.TxConfig.SigningContext().AddressCodec()
|
||||
|
||||
cmd.Println("Signers:")
|
||||
signers := sigTx.GetSigners()
|
||||
signers, err := sigTx.GetSigners()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for i, signer := range signers {
|
||||
cmd.Printf(" %v: %v\n", i, signer.String())
|
||||
signerStr, err := addrCdc.BytesToString(signer)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cmd.Printf(" %v: %v\n", i, signerStr)
|
||||
}
|
||||
|
||||
success := true
|
||||
@ -93,7 +103,7 @@ func printAndValidateSigs(
|
||||
sigSanity = "OK"
|
||||
)
|
||||
|
||||
if i >= len(signers) || !sigAddr.Equals(signers[i]) {
|
||||
if i >= len(signers) || !bytes.Equal(sigAddr, signers[i]) {
|
||||
sigSanity = "ERROR: signature does not match its respective signer"
|
||||
success = false
|
||||
}
|
||||
|
||||
@ -48,7 +48,11 @@ func SignTx(txFactory tx.Factory, clientCtx client.Context, name string, txBuild
|
||||
return err
|
||||
}
|
||||
addr := sdk.AccAddress(pubKey.Address())
|
||||
if !isTxSigner(addr, txBuilder.GetTx().GetSigners()) {
|
||||
signers, err := txBuilder.GetTx().GetSigners()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isTxSigner(addr, signers) {
|
||||
return fmt.Errorf("%s: %s", errors.ErrorInvalidSigner, name)
|
||||
}
|
||||
if !offline {
|
||||
@ -75,7 +79,12 @@ func SignTxWithSignerAddress(txFactory tx.Factory, clientCtx client.Context, add
|
||||
}
|
||||
|
||||
// check whether the address is a signer
|
||||
if !isTxSigner(addr, txBuilder.GetTx().GetSigners()) {
|
||||
signers, err := txBuilder.GetTx().GetSigners()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !isTxSigner(addr, signers) {
|
||||
return fmt.Errorf("%s: %s", errors.ErrorInvalidSigner, name)
|
||||
}
|
||||
|
||||
@ -189,9 +198,9 @@ func ParseQueryResponse(bz []byte) (sdk.SimulationResponse, error) {
|
||||
return simRes, nil
|
||||
}
|
||||
|
||||
func isTxSigner(user sdk.AccAddress, signers []sdk.AccAddress) bool {
|
||||
func isTxSigner(user []byte, signers [][]byte) bool {
|
||||
for _, s := range signers {
|
||||
if bytes.Equal(user.Bytes(), s.Bytes()) {
|
||||
if bytes.Equal(user, s) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,11 +7,12 @@ import (
|
||||
|
||||
"cosmossdk.io/collections"
|
||||
|
||||
"cosmossdk.io/core/address"
|
||||
"cosmossdk.io/core/store"
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
"cosmossdk.io/log"
|
||||
|
||||
"cosmossdk.io/core/address"
|
||||
"cosmossdk.io/core/store"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
// handlers.
|
||||
type SigVerifiableTx interface {
|
||||
types.Tx
|
||||
GetSigners() []types.AccAddress
|
||||
GetSigners() ([][]byte, error)
|
||||
GetPubKeys() ([]cryptotypes.PubKey, error) // If signer already has pubkey in context, this list will have nil in its place
|
||||
GetSignaturesV2() ([]signing.SignatureV2, error)
|
||||
}
|
||||
@ -25,4 +25,5 @@ type Tx interface {
|
||||
types.FeeTx
|
||||
tx.TipTx
|
||||
types.TxWithTimeoutHeight
|
||||
types.HasValidateBasic
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ func TestBuilderWithAux(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
tx, err := txConfig.TxDecoder()(txBz)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tx.(sdk.FeeTx).FeePayer(), feepayerAddr)
|
||||
require.Equal(t, tx.(sdk.FeeTx).FeePayer(), []byte(feepayerAddr))
|
||||
require.Equal(t, tx.(sdk.FeeTx).GetFee(), fee)
|
||||
require.Equal(t, tx.(sdk.FeeTx).GetGas(), gas)
|
||||
require.Equal(t, tip, tx.(txtypes.TipTx).GetTip())
|
||||
|
||||
@ -1,9 +1,14 @@
|
||||
package tx
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/gogoproto/proto"
|
||||
protov2 "google.golang.org/protobuf/proto"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
@ -32,6 +37,9 @@ type wrapper struct {
|
||||
authInfoBz []byte
|
||||
|
||||
txBodyHasUnknownNonCriticals bool
|
||||
|
||||
signers [][]byte
|
||||
msgsV2 []protov2.Message
|
||||
}
|
||||
|
||||
var (
|
||||
@ -52,7 +60,7 @@ type ExtensionOptionsTxBuilder interface {
|
||||
}
|
||||
|
||||
func newBuilder(cdc codec.Codec) *wrapper {
|
||||
return &wrapper{
|
||||
w := &wrapper{
|
||||
cdc: cdc,
|
||||
tx: &tx.Tx{
|
||||
Body: &tx.TxBody{},
|
||||
@ -61,14 +69,47 @@ func newBuilder(cdc codec.Codec) *wrapper {
|
||||
},
|
||||
},
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *wrapper) GetMsgs() []sdk.Msg {
|
||||
return w.tx.GetMsgs()
|
||||
}
|
||||
|
||||
func (w *wrapper) GetMsgsV2() ([]protov2.Message, error) {
|
||||
if w.msgsV2 == nil {
|
||||
err := w.initSignersAndMsgsV2()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return w.msgsV2, nil
|
||||
}
|
||||
|
||||
func (w *wrapper) ValidateBasic() error {
|
||||
return w.tx.ValidateBasic()
|
||||
if w.tx == nil {
|
||||
return fmt.Errorf("bad Tx")
|
||||
}
|
||||
|
||||
if err := w.tx.ValidateBasic(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sigs := w.tx.Signatures
|
||||
signers, err := w.GetSigners()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(sigs) != len(signers) {
|
||||
return errorsmod.Wrapf(
|
||||
sdkerrors.ErrUnauthorized,
|
||||
"wrong number of signers; expected %d, got %d", len(signers), len(sigs),
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *wrapper) getBodyBytes() []byte {
|
||||
@ -103,8 +144,20 @@ func (w *wrapper) getAuthInfoBytes() []byte {
|
||||
return w.authInfoBz
|
||||
}
|
||||
|
||||
func (w *wrapper) GetSigners() []sdk.AccAddress {
|
||||
return w.tx.GetSigners()
|
||||
func (w *wrapper) initSignersAndMsgsV2() error {
|
||||
var err error
|
||||
w.signers, w.msgsV2, err = w.tx.GetSigners(w.cdc)
|
||||
return err
|
||||
}
|
||||
|
||||
func (w *wrapper) GetSigners() ([][]byte, error) {
|
||||
if w.signers == nil {
|
||||
err := w.initSignersAndMsgsV2()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return w.signers, nil
|
||||
}
|
||||
|
||||
func (w *wrapper) GetPubKeys() ([]cryptotypes.PubKey, error) {
|
||||
@ -138,21 +191,31 @@ func (w *wrapper) GetFee() sdk.Coins {
|
||||
return w.tx.AuthInfo.Fee.Amount
|
||||
}
|
||||
|
||||
func (w *wrapper) FeePayer() sdk.AccAddress {
|
||||
func (w *wrapper) FeePayer() []byte {
|
||||
feePayer := w.tx.AuthInfo.Fee.Payer
|
||||
if feePayer != "" {
|
||||
return sdk.MustAccAddressFromBech32(feePayer)
|
||||
feePayerAddr, err := w.cdc.InterfaceRegistry().SigningContext().AddressCodec().StringToBytes(feePayer)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return feePayerAddr
|
||||
}
|
||||
|
||||
// use first signer as default if no payer specified
|
||||
return w.GetSigners()[0]
|
||||
signers, err := w.GetSigners()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return signers[0]
|
||||
}
|
||||
|
||||
func (w *wrapper) FeeGranter() sdk.AccAddress {
|
||||
feePayer := w.tx.AuthInfo.Fee.Granter
|
||||
if feePayer != "" {
|
||||
return sdk.MustAccAddressFromBech32(feePayer)
|
||||
func (w *wrapper) FeeGranter() string {
|
||||
feeGranter := w.tx.AuthInfo.Fee.Granter
|
||||
if feeGranter != "" {
|
||||
return feeGranter
|
||||
}
|
||||
return nil
|
||||
return ""
|
||||
}
|
||||
|
||||
func (w *wrapper) GetTip() *tx.Tip {
|
||||
@ -215,6 +278,10 @@ func (w *wrapper) SetMsgs(msgs ...sdk.Msg) error {
|
||||
// set bodyBz to nil because the cached bodyBz no longer matches tx.Body
|
||||
w.bodyBz = nil
|
||||
|
||||
// reset signers and msgsV2
|
||||
w.signers = nil
|
||||
w.msgsV2 = nil
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -292,12 +359,12 @@ func (w *wrapper) SetSignatures(signatures ...signing.SignatureV2) error {
|
||||
for i, sig := range signatures {
|
||||
var modeInfo *tx.ModeInfo
|
||||
modeInfo, rawSigs[i] = SignatureDataToModeInfoAndSig(sig.Data)
|
||||
any, err := codectypes.NewAnyWithValue(sig.PubKey)
|
||||
pubKey, err := codectypes.NewAnyWithValue(sig.PubKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
signerInfos[i] = &tx.SignerInfo{
|
||||
PublicKey: any,
|
||||
PublicKey: pubKey,
|
||||
ModeInfo: modeInfo,
|
||||
Sequence: sig.Sequence,
|
||||
}
|
||||
@ -316,8 +383,13 @@ func (w *wrapper) setSignerInfos(infos []*tx.SignerInfo) {
|
||||
}
|
||||
|
||||
func (w *wrapper) setSignerInfoAtIndex(index int, info *tx.SignerInfo) {
|
||||
signers, err := w.GetSigners()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if w.tx.AuthInfo.SignerInfos == nil {
|
||||
w.tx.AuthInfo.SignerInfos = make([]*tx.SignerInfo, len(w.GetSigners()))
|
||||
w.tx.AuthInfo.SignerInfos = make([]*tx.SignerInfo, len(signers))
|
||||
}
|
||||
|
||||
w.tx.AuthInfo.SignerInfos[index] = info
|
||||
@ -330,8 +402,13 @@ func (w *wrapper) setSignatures(sigs [][]byte) {
|
||||
}
|
||||
|
||||
func (w *wrapper) setSignatureAtIndex(index int, sig []byte) {
|
||||
signers, err := w.GetSigners()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if w.tx.Signatures == nil {
|
||||
w.tx.Signatures = make([][]byte, len(w.GetSigners()))
|
||||
w.tx.Signatures = make([][]byte, len(signers))
|
||||
}
|
||||
|
||||
w.tx.Signatures[index] = sig
|
||||
@ -443,13 +520,25 @@ func (w *wrapper) AddAuxSignerData(data tx.AuxSignerData) error {
|
||||
for i, msgAny := range body.Messages {
|
||||
msgs[i] = msgAny.GetCachedValue().(sdk.Msg)
|
||||
}
|
||||
w.SetMsgs(msgs...)
|
||||
err = w.SetMsgs(msgs...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.SetTip(data.GetSignDoc().GetTip())
|
||||
|
||||
// Get the aux signer's index in GetSigners.
|
||||
signerIndex := -1
|
||||
for i, signer := range w.GetSigners() {
|
||||
if signer.String() == data.Address {
|
||||
signers, err := w.GetSigners()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i, signer := range signers {
|
||||
addrBz, err := w.cdc.InterfaceRegistry().SigningContext().AddressCodec().StringToBytes(data.Address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if bytes.Equal(signer, addrBz) {
|
||||
signerIndex = i
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
"github.com/cosmos/cosmos-sdk/codec/testutil"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -22,7 +23,7 @@ func TestTxBuilder(t *testing.T) {
|
||||
_, pubkey, addr := testdata.KeyTestPubAddr()
|
||||
|
||||
marshaler := codec.NewProtoCodec(codectypes.NewInterfaceRegistry())
|
||||
txBuilder := newBuilder(nil)
|
||||
txBuilder := newBuilder(marshaler)
|
||||
|
||||
memo := "testmemo"
|
||||
msgs := []sdk.Msg{testdata.NewTestMsg(addr)}
|
||||
@ -139,7 +140,7 @@ func TestBuilderValidateBasic(t *testing.T) {
|
||||
// require to fail validation upon invalid fee
|
||||
badFeeAmount := testdata.NewTestFeeAmount()
|
||||
badFeeAmount[0].Amount = sdkmath.NewInt(-5)
|
||||
txBuilder := newBuilder(nil)
|
||||
txBuilder := newBuilder(testutil.CodecOptions{}.NewCodec())
|
||||
|
||||
var sig1, sig2 signing.SignatureV2
|
||||
sig1 = signing.SignatureV2{
|
||||
@ -258,21 +259,21 @@ func TestBuilderFeePayer(t *testing.T) {
|
||||
|
||||
cases := map[string]struct {
|
||||
txFeePayer sdk.AccAddress
|
||||
expectedSigners []sdk.AccAddress
|
||||
expectedPayer sdk.AccAddress
|
||||
expectedSigners [][]byte
|
||||
expectedPayer []byte
|
||||
}{
|
||||
"no fee payer specified": {
|
||||
expectedSigners: []sdk.AccAddress{addr1, addr2},
|
||||
expectedSigners: [][]byte{addr1, addr2},
|
||||
expectedPayer: addr1,
|
||||
},
|
||||
"secondary signer set as fee payer": {
|
||||
txFeePayer: addr2,
|
||||
expectedSigners: []sdk.AccAddress{addr1, addr2},
|
||||
expectedSigners: [][]byte{addr1, addr2},
|
||||
expectedPayer: addr2,
|
||||
},
|
||||
"outside signer set as fee payer": {
|
||||
txFeePayer: addr3,
|
||||
expectedSigners: []sdk.AccAddress{addr1, addr2, addr3},
|
||||
expectedSigners: [][]byte{addr1, addr2, addr3},
|
||||
expectedPayer: addr3,
|
||||
},
|
||||
}
|
||||
@ -280,7 +281,7 @@ func TestBuilderFeePayer(t *testing.T) {
|
||||
for name, tc := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
// setup basic tx
|
||||
txBuilder := newBuilder(nil)
|
||||
txBuilder := newBuilder(testutil.CodecOptions{}.NewCodec())
|
||||
err := txBuilder.SetMsgs(msgs...)
|
||||
require.NoError(t, err)
|
||||
txBuilder.SetGasLimit(200000)
|
||||
@ -289,7 +290,9 @@ func TestBuilderFeePayer(t *testing.T) {
|
||||
// set fee payer
|
||||
txBuilder.SetFeePayer(tc.txFeePayer)
|
||||
// and check it updates fields properly
|
||||
require.Equal(t, tc.expectedSigners, txBuilder.GetSigners())
|
||||
signers, err := txBuilder.GetSigners()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tc.expectedSigners, signers)
|
||||
require.Equal(t, tc.expectedPayer, txBuilder.FeePayer())
|
||||
})
|
||||
}
|
||||
@ -314,5 +317,5 @@ func TestBuilderFeeGranter(t *testing.T) {
|
||||
|
||||
// set fee granter
|
||||
txBuilder.SetFeeGranter(addr1)
|
||||
require.Equal(t, addr1, txBuilder.GetTx().FeeGranter())
|
||||
require.Equal(t, addr1.String(), txBuilder.GetTx().FeeGranter())
|
||||
}
|
||||
|
||||
@ -18,12 +18,13 @@ import (
|
||||
)
|
||||
|
||||
type config struct {
|
||||
handler *txsigning.HandlerMap
|
||||
decoder sdk.TxDecoder
|
||||
encoder sdk.TxEncoder
|
||||
jsonDecoder sdk.TxDecoder
|
||||
jsonEncoder sdk.TxEncoder
|
||||
protoCodec codec.ProtoCodecMarshaler
|
||||
handler *txsigning.HandlerMap
|
||||
decoder sdk.TxDecoder
|
||||
encoder sdk.TxEncoder
|
||||
jsonDecoder sdk.TxDecoder
|
||||
jsonEncoder sdk.TxEncoder
|
||||
protoCodec codec.ProtoCodecMarshaler
|
||||
signingContext *txsigning.Context
|
||||
}
|
||||
|
||||
// ConfigOptions define the configuration of a TxConfig when calling NewTxConfigWithOptions.
|
||||
@ -125,6 +126,7 @@ func NewTxConfigWithOptions(protoCodec codec.ProtoCodecMarshaler, configOptions
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
txConfig.signingContext = opts.SigningContext
|
||||
|
||||
lenSignModes := len(configOptions.EnabledSignModes)
|
||||
handlers := make([]txsigning.SignModeHandler, lenSignModes+len(opts.CustomSignModes))
|
||||
@ -201,3 +203,7 @@ func (g config) TxJSONEncoder() sdk.TxEncoder {
|
||||
func (g config) TxJSONDecoder() sdk.TxDecoder {
|
||||
return g.jsonDecoder
|
||||
}
|
||||
|
||||
func (g config) SigningContext() *txsigning.Context {
|
||||
return g.signingContext
|
||||
}
|
||||
|
||||
@ -10,8 +10,9 @@ import (
|
||||
|
||||
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
|
||||
txconfigv1 "cosmossdk.io/api/cosmos/tx/config/v1"
|
||||
"cosmossdk.io/core/appmodule"
|
||||
"cosmossdk.io/depinject"
|
||||
|
||||
"cosmossdk.io/core/appmodule"
|
||||
txsigning "cosmossdk.io/x/tx/signing"
|
||||
"cosmossdk.io/x/tx/signing/textual"
|
||||
authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec"
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/codec/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/std"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func TestGenerator(t *testing.T) {
|
||||
interfaceRegistry := codectypes.NewInterfaceRegistry()
|
||||
interfaceRegistry := testutil.CodecOptions{}.NewInterfaceRegistry()
|
||||
std.RegisterInterfaces(interfaceRegistry)
|
||||
interfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &testdata.TestMsg{})
|
||||
protoCodec := codec.NewProtoCodec(interfaceRegistry)
|
||||
|
||||
@ -73,6 +73,7 @@ func DefaultTxDecoder(cdc codec.ProtoCodecMarshaler) sdk.TxDecoder {
|
||||
bodyBz: raw.BodyBytes,
|
||||
authInfoBz: raw.AuthInfoBytes,
|
||||
txBodyHasUnknownNonCriticals: txBodyHasUnknownNonCriticals,
|
||||
cdc: cdc,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
@ -87,7 +88,8 @@ func DefaultJSONTxDecoder(cdc codec.ProtoCodecMarshaler) sdk.TxDecoder {
|
||||
}
|
||||
|
||||
return &wrapper{
|
||||
tx: &theTx,
|
||||
tx: &theTx,
|
||||
cdc: cdc,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package tx
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
@ -51,11 +52,16 @@ func (signModeDirectAuxHandler) GetSignBytes(
|
||||
return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "got empty address in %s handler", signingtypes.SignMode_SIGN_MODE_DIRECT_AUX)
|
||||
}
|
||||
|
||||
feePayer := protoTx.FeePayer().String()
|
||||
feePayer := protoTx.FeePayer()
|
||||
|
||||
// Fee payer cannot use SIGN_MODE_DIRECT_AUX, because SIGN_MODE_DIRECT_AUX
|
||||
// does not sign over fees, which would create malleability issues.
|
||||
if feePayer == data.Address {
|
||||
addrBz, err := sdk.AccAddressFromBech32(data.Address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if bytes.Equal(feePayer, addrBz) {
|
||||
return nil, sdkerrors.ErrUnauthorized.Wrapf("fee payer %s cannot sign with %s", feePayer, signingtypes.SignMode_SIGN_MODE_DIRECT_AUX)
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/testutil"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -18,7 +19,7 @@ import (
|
||||
func TestDirectAuxHandler(t *testing.T) {
|
||||
privKey, pubkey, addr := testdata.KeyTestPubAddr()
|
||||
_, feePayerPubKey, feePayerAddr := testdata.KeyTestPubAddr()
|
||||
interfaceRegistry := codectypes.NewInterfaceRegistry()
|
||||
interfaceRegistry := testutil.CodecOptions{}.NewInterfaceRegistry()
|
||||
interfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &testdata.TestMsg{})
|
||||
marshaler := codec.NewProtoCodec(interfaceRegistry)
|
||||
|
||||
@ -81,7 +82,7 @@ func TestDirectAuxHandler(t *testing.T) {
|
||||
|
||||
t.Log("verify fee payer cannot use SIGN_MODE_DIRECT_AUX")
|
||||
_, err = modeHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT_AUX, feePayerSigningData, txBuilder.GetTx())
|
||||
require.EqualError(t, err, fmt.Sprintf("fee payer %s cannot sign with %s: unauthorized", feePayerAddr.String(), signingtypes.SignMode_SIGN_MODE_DIRECT_AUX))
|
||||
require.EqualError(t, err, fmt.Sprintf("fee payer %s cannot sign with %s: unauthorized", []byte(feePayerAddr), signingtypes.SignMode_SIGN_MODE_DIRECT_AUX))
|
||||
|
||||
t.Log("verify GetSignBytes with generating sign bytes by marshaling signDocDirectAux")
|
||||
signBytes, err := modeHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT_AUX, signingData, txBuilder.GetTx())
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
protov2 "google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
@ -156,8 +157,9 @@ func TestDirectModeHandler_nonDIRECT_MODE(t *testing.T) {
|
||||
|
||||
type nonProtoTx int
|
||||
|
||||
func (npt *nonProtoTx) GetMsgs() []sdk.Msg { return nil }
|
||||
func (npt *nonProtoTx) ValidateBasic() error { return nil }
|
||||
func (npt *nonProtoTx) GetMsgs() []sdk.Msg { return nil }
|
||||
func (npt *nonProtoTx) GetMsgsV2() ([]protov2.Message, error) { return nil, nil }
|
||||
func (npt *nonProtoTx) ValidateBasic() error { return nil }
|
||||
|
||||
var _ sdk.Tx = (*nonProtoTx)(nil)
|
||||
|
||||
|
||||
@ -36,11 +36,6 @@ func DefaultJSONTxEncoder(cdc codec.ProtoCodecMarshaler) sdk.TxEncoder {
|
||||
return cdc.MarshalJSON(txWrapper.tx)
|
||||
}
|
||||
|
||||
protoTx, ok := tx.(*txtypes.Tx)
|
||||
if ok {
|
||||
return cdc.MarshalJSON(protoTx)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("expected %T, got %T", &wrapper{}, tx)
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
@ -74,8 +75,10 @@ func (s *TxConfigTestSuite) TestTxBuilderSetMsgs() {
|
||||
s.Require().NoError(err)
|
||||
tx := txBuilder.GetTx()
|
||||
s.Require().Equal(msgs, tx.GetMsgs())
|
||||
s.Require().Equal([]sdk.AccAddress{addr1, addr2}, tx.GetSigners())
|
||||
s.Require().Equal(addr1, tx.FeePayer())
|
||||
signers, err := tx.GetSigners()
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal([][]byte{addr1, addr2}, signers)
|
||||
s.Require().Equal([]byte(addr1), tx.FeePayer())
|
||||
s.Require().Error(tx.ValidateBasic()) // should fail because of no signatures
|
||||
}
|
||||
|
||||
@ -127,7 +130,9 @@ func (s *TxConfigTestSuite) TestTxBuilderSetSignatures() {
|
||||
s.Require().Len(sigsV2, 2)
|
||||
s.Require().True(sigEquals(sig1, sigsV2[0]))
|
||||
s.Require().True(sigEquals(msig, sigsV2[1]))
|
||||
s.Require().Equal([]sdk.AccAddress{addr, msigAddr}, sigTx.GetSigners())
|
||||
signers, err := sigTx.GetSigners()
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal([][]byte{addr, msigAddr}, signers)
|
||||
s.Require().NoError(sigTx.ValidateBasic())
|
||||
|
||||
// sign transaction
|
||||
@ -178,7 +183,9 @@ func (s *TxConfigTestSuite) TestTxBuilderSetSignatures() {
|
||||
s.Require().Len(sigsV2, 2)
|
||||
s.Require().True(sigEquals(sig1, sigsV2[0]))
|
||||
s.Require().True(sigEquals(msig, sigsV2[1]))
|
||||
s.Require().Equal([]sdk.AccAddress{addr, msigAddr}, sigTx.GetSigners())
|
||||
signers, err = sigTx.GetSigners()
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal([][]byte{addr, msigAddr}, signers)
|
||||
s.Require().NoError(sigTx.ValidateBasic())
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
@ -30,13 +31,13 @@ const gasCostPerIteration = uint64(20)
|
||||
|
||||
type Keeper struct {
|
||||
storeService corestoretypes.KVStoreService
|
||||
cdc codec.BinaryCodec
|
||||
cdc codec.Codec
|
||||
router baseapp.MessageRouter
|
||||
authKeeper authz.AccountKeeper
|
||||
}
|
||||
|
||||
// NewKeeper constructs a message authorization Keeper
|
||||
func NewKeeper(storeService corestoretypes.KVStoreService, cdc codec.BinaryCodec, router baseapp.MessageRouter, ak authz.AccountKeeper) Keeper {
|
||||
func NewKeeper(storeService corestoretypes.KVStoreService, cdc codec.Codec, router baseapp.MessageRouter, ak authz.AccountKeeper) Keeper {
|
||||
return Keeper{
|
||||
storeService: storeService,
|
||||
cdc: cdc,
|
||||
@ -99,7 +100,11 @@ func (k Keeper) DispatchActions(ctx context.Context, grantee sdk.AccAddress, msg
|
||||
now := sdkCtx.BlockTime()
|
||||
|
||||
for i, msg := range msgs {
|
||||
signers := msg.GetSigners()
|
||||
signers, _, err := k.cdc.GetMsgV1Signers(msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(signers) != 1 {
|
||||
return nil, authz.ErrAuthorizationNumOfSigners
|
||||
}
|
||||
@ -108,7 +113,7 @@ func (k Keeper) DispatchActions(ctx context.Context, grantee sdk.AccAddress, msg
|
||||
|
||||
// If granter != grantee then check authorization.Accept, otherwise we
|
||||
// implicitly accept.
|
||||
if !granter.Equals(grantee) {
|
||||
if !bytes.Equal(granter, grantee) {
|
||||
skey := grantStoreKey(grantee, granter, sdk.MsgTypeURL(msg))
|
||||
|
||||
grant, found := k.getGrant(ctx, skey)
|
||||
|
||||
@ -36,7 +36,7 @@ type Keeper struct {
|
||||
storeService corestoretypes.KVStoreService
|
||||
|
||||
// The codec for binary encoding/decoding.
|
||||
cdc codec.BinaryCodec
|
||||
cdc codec.Codec
|
||||
|
||||
// Legacy Proposal router
|
||||
legacyRouter v1beta1.Router
|
||||
@ -72,7 +72,7 @@ func (k Keeper) GetAuthority() string {
|
||||
//
|
||||
// CONTRACT: the parameter Subspace must have the param key table already initialized
|
||||
func NewKeeper(
|
||||
cdc codec.BinaryCodec, storeService corestoretypes.KVStoreService, authKeeper types.AccountKeeper,
|
||||
cdc codec.Codec, storeService corestoretypes.KVStoreService, authKeeper types.AccountKeeper,
|
||||
bankKeeper types.BankKeeper, sk types.StakingKeeper, distrKeeper types.DistributionKeeper,
|
||||
router baseapp.MessageRouter, config types.Config, authority string,
|
||||
) *Keeper {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -47,14 +48,17 @@ func (keeper Keeper) SubmitProposal(ctx context.Context, messages []sdk.Msg, met
|
||||
}
|
||||
}
|
||||
|
||||
signers := msg.GetSigners()
|
||||
signers, _, err := keeper.cdc.GetMsgV1Signers(msg)
|
||||
if err != nil {
|
||||
return v1.Proposal{}, err
|
||||
}
|
||||
if len(signers) != 1 {
|
||||
return v1.Proposal{}, types.ErrInvalidSigner
|
||||
}
|
||||
|
||||
// assert that the governance module account is the only signer of the messages
|
||||
if !signers[0].Equals(keeper.GetGovernanceAccount(ctx).GetAddress()) {
|
||||
return v1.Proposal{}, errorsmod.Wrapf(types.ErrInvalidSigner, signers[0].String())
|
||||
if !bytes.Equal(signers[0], keeper.GetGovernanceAccount(ctx).GetAddress()) {
|
||||
return v1.Proposal{}, errorsmod.Wrapf(types.ErrInvalidSigner, sdk.AccAddress(signers[0]).String())
|
||||
}
|
||||
|
||||
// use the msg service router to see that there is a valid route for that message.
|
||||
|
||||
@ -79,6 +79,8 @@ type Keeper struct {
|
||||
router baseapp.MessageRouter
|
||||
|
||||
config group.Config
|
||||
|
||||
cdc codec.Codec
|
||||
}
|
||||
|
||||
// NewKeeper creates a new group keeper.
|
||||
@ -87,6 +89,7 @@ func NewKeeper(storeKey storetypes.StoreKey, cdc codec.Codec, router baseapp.Mes
|
||||
key: storeKey,
|
||||
router: router,
|
||||
accKeeper: accKeeper,
|
||||
cdc: cdc,
|
||||
}
|
||||
|
||||
groupTable, err := orm.NewAutoUInt64Table([2]byte{GroupTablePrefix}, GroupTableSeqPrefix, &group.GroupInfo{}, cdc)
|
||||
|
||||
@ -575,7 +575,7 @@ func (k Keeper) SubmitProposal(goCtx context.Context, msg *group.MsgSubmitPropos
|
||||
}
|
||||
|
||||
// Check that if the messages require signers, they are all equal to the given account address of group policy.
|
||||
if err := ensureMsgAuthZ(msgs, groupPolicyAddr); err != nil {
|
||||
if err := ensureMsgAuthZ(msgs, groupPolicyAddr, k.cdc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/x/group"
|
||||
@ -37,7 +39,7 @@ func (s Keeper) doExecuteMsgs(ctx sdk.Context, router baseapp.MessageRouter, pro
|
||||
}
|
||||
|
||||
results := make([]sdk.Result, len(msgs))
|
||||
if err := ensureMsgAuthZ(msgs, groupPolicyAcc); err != nil {
|
||||
if err := ensureMsgAuthZ(msgs, groupPolicyAcc, s.cdc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i, msg := range msgs {
|
||||
@ -61,15 +63,20 @@ func (s Keeper) doExecuteMsgs(ctx sdk.Context, router baseapp.MessageRouter, pro
|
||||
|
||||
// ensureMsgAuthZ checks that if a message requires signers that all of them
|
||||
// are equal to the given account address of group policy.
|
||||
func ensureMsgAuthZ(msgs []sdk.Msg, groupPolicyAcc sdk.AccAddress) error {
|
||||
func ensureMsgAuthZ(msgs []sdk.Msg, groupPolicyAcc sdk.AccAddress, cdc codec.Codec) error {
|
||||
for i := range msgs {
|
||||
// In practice, GetSigners() should return a non-empty array without
|
||||
// duplicates, so the code below is equivalent to:
|
||||
// `msgs[i].GetSigners()[0] == groupPolicyAcc`
|
||||
// but we prefer to loop through all GetSigners just to be sure.
|
||||
for _, acct := range msgs[i].GetSigners() {
|
||||
if !groupPolicyAcc.Equals(acct) {
|
||||
return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "msg does not have group policy authorization; expected %s, got %s", groupPolicyAcc.String(), acct.String())
|
||||
signers, _, err := cdc.GetMsgV1Signers(msgs[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, acct := range signers {
|
||||
if !bytes.Equal(groupPolicyAcc, acct) {
|
||||
return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "msg does not have group policy authorization; expected %s, got %s", groupPolicyAcc.String(), acct)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user