diff --git a/.changelog/unreleased/features/403-signerless-forwarding.md b/.changelog/unreleased/features/403-signerless-forwarding.md new file mode 100644 index 00000000..2f307fe3 --- /dev/null +++ b/.changelog/unreleased/features/403-signerless-forwarding.md @@ -0,0 +1 @@ +- Update `x/fowarding` to support signerless account registration. ([#403](https://github.com/noble-assets/noble/pull/403)) diff --git a/.changelog/unreleased/improvements/389-module-path.md b/.changelog/unreleased/improvements/399-module-path.md similarity index 100% rename from .changelog/unreleased/improvements/389-module-path.md rename to .changelog/unreleased/improvements/399-module-path.md diff --git a/app/ante.go b/app/ante.go index bd1ae20a..c120ed4c 100644 --- a/app/ante.go +++ b/app/ante.go @@ -7,14 +7,21 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/ante" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" ibcante "github.com/cosmos/ibc-go/v4/modules/core/ante" ibckeeper "github.com/cosmos/ibc-go/v4/modules/core/keeper" "github.com/noble-assets/forwarding/x/forwarding" forwardingkeeper "github.com/noble-assets/forwarding/x/forwarding/keeper" + forwardingtypes "github.com/noble-assets/forwarding/x/forwarding/types" feeante "github.com/noble-assets/noble/v7/x/globalfee/ante" ) +type BankKeeper interface { + authtypes.BankKeeper + forwardingtypes.BankKeeper +} + type HandlerOptions struct { ante.HandlerOptions cdc codec.Codec @@ -22,6 +29,7 @@ type HandlerOptions struct { IBCKeeper *ibckeeper.Keeper GlobalFeeSubspace paramtypes.Subspace StakingSubspace paramtypes.Subspace + BankKeeper BankKeeper ForwardingKeeper *forwardingkeeper.Keeper } @@ -67,7 +75,7 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { ante.NewSetPubKeyDecorator(options.AccountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators ante.NewValidateSigCountDecorator(options.AccountKeeper), ante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer), - ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), + forwarding.NewSigVerificationDecorator(options.AccountKeeper, options.BankKeeper, options.SignModeHandler), ante.NewIncrementSequenceDecorator(options.AccountKeeper), ibcante.NewAnteDecorator(options.IBCKeeper), } diff --git a/app/app.go b/app/app.go index b1925f43..41e99f38 100644 --- a/app/app.go +++ b/app/app.go @@ -740,10 +740,9 @@ func New( HandlerOptions{ HandlerOptions: ante.HandlerOptions{ AccountKeeper: app.AccountKeeper, - BankKeeper: app.BankKeeper, FeegrantKeeper: app.FeeGrantKeeper, SignModeHandler: encodingConfig.TxConfig.SignModeHandler(), - SigGasConsumer: ante.DefaultSigVerificationGasConsumer, + SigGasConsumer: forwarding.SigVerificationGasConsumer, }, cdc: appCodec, fiatTokenFactoryKeeper: app.FiatTokenFactoryKeeper, @@ -752,6 +751,7 @@ func New( GlobalFeeSubspace: app.GetSubspace(globalfee.ModuleName), StakingSubspace: app.GetSubspace(stakingtypes.ModuleName), + BankKeeper: app.BankKeeper, ForwardingKeeper: app.ForwardingKeeper, }, ) diff --git a/go.mod b/go.mod index 29955507..d54450b5 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/noble-assets/florin v1.0.0-rc.1 - github.com/noble-assets/forwarding v1.1.0 + github.com/noble-assets/forwarding v1.2.0-rc.0 github.com/noble-assets/halo v1.0.0 github.com/ondoprotocol/usdy-noble v1.0.0 github.com/rs/zerolog v1.27.0 diff --git a/go.sum b/go.sum index c9692df9..a5990cfc 100644 --- a/go.sum +++ b/go.sum @@ -967,8 +967,8 @@ github.com/noble-assets/cosmos-sdk v0.45.16-send-restrictions h1:oQwbCoejkXp2/oz github.com/noble-assets/cosmos-sdk v0.45.16-send-restrictions/go.mod h1:bScuNwWAP0TZJpUf+SHXRU3xGoUPp+X9nAzfeIXts40= github.com/noble-assets/florin v1.0.0-rc.1 h1:0O8Xr0Jqos7lvyvdtQE8Y0WcNH5PvfIJsocPeYLufh8= github.com/noble-assets/florin v1.0.0-rc.1/go.mod h1:W+6DjaZdSRQe2oqv8eCHQtbyp36LUNImGRCLdPNSA2o= -github.com/noble-assets/forwarding v1.1.0 h1:2TXBs2Y9vWqgHyDKtdcHht6i7OT+pLaVHE3bPvfpmJY= -github.com/noble-assets/forwarding v1.1.0/go.mod h1:o64ZfzCHteRDhOlkpi7GeKAcjlcbWUihC7Y34Er2/3U= +github.com/noble-assets/forwarding v1.2.0-rc.0 h1:f/bL/cicvhNUp9SuueiqqqSVRRn7CQxTKOesVUKrSyQ= +github.com/noble-assets/forwarding v1.2.0-rc.0/go.mod h1:o64ZfzCHteRDhOlkpi7GeKAcjlcbWUihC7Y34Er2/3U= github.com/noble-assets/halo v1.0.0 h1:JG5TAZZcuLArYgl/9dgwJJ9KAOIo2f03/S010WRVNV8= github.com/noble-assets/halo v1.0.0/go.mod h1:AUFdixNgPdce0soYfT6aNggwW9PUVFxaIkCC83M26Sk= github.com/nunnatsa/ginkgolinter v0.14.0 h1:XQPNmw+kZz5cC/HbFK3mQutpjzAQv1dHregRA+4CGGg= diff --git a/interchaintest/forwarding_test.go b/interchaintest/forwarding_test.go index 098ed1a9..434a998b 100644 --- a/interchaintest/forwarding_test.go +++ b/interchaintest/forwarding_test.go @@ -65,6 +65,34 @@ func TestForwarding_RegisterOnNoble(t *testing.T) { require.Equal(t, sdk.NewCoins(sdk.NewCoin("uusdc", sdk.NewInt(1_000_000))), stats.TotalForwarded) } +func TestForwarding_RegisterSignerlessly(t *testing.T) { + t.Parallel() + + ctx, wrapper, _, _, _, sender, receiver := ForwardingSuite(t) + validator := wrapper.chain.Validators[0] + + address, exists := ForwardingAccount(t, ctx, validator, receiver) + require.False(t, exists) + + require.NoError(t, validator.SendFunds(ctx, sender.KeyName(), ibc.WalletAmount{ + Address: address, + Denom: "uusdc", + Amount: 1_000_000, + })) + + _, exists = ForwardingAccount(t, ctx, validator, receiver) + require.False(t, exists) + + // NOTE: The keyName argument is intentionally left blank here. If + // everything is working correctly, this shouldn't error as we don't need + // to interact with the keyring. + _, err := validator.ExecTx(ctx, "", "forwarding", "register-account-signerlessly", "channel-0", receiver.FormattedAddress()) + require.NoError(t, err) + + _, exists = ForwardingAccount(t, ctx, validator, receiver) + require.True(t, exists) +} + func TestForwarding_RegisterViaTransfer(t *testing.T) { t.Parallel() diff --git a/interchaintest/go.mod b/interchaintest/go.mod index 05383967..9d4d5af3 100644 --- a/interchaintest/go.mod +++ b/interchaintest/go.mod @@ -11,7 +11,7 @@ require ( github.com/ethereum/go-ethereum v1.12.2 github.com/gogo/protobuf v1.3.3 github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 - github.com/noble-assets/forwarding v1.1.0 + github.com/noble-assets/forwarding v1.2.0-rc.0 github.com/noble-assets/noble/v7 v7.0.0 github.com/strangelove-ventures/interchaintest/v4 v4.0.0-20231026153934-334934f17a68 github.com/strangelove-ventures/paramauthority v1.1.0 diff --git a/interchaintest/go.sum b/interchaintest/go.sum index c9ecb685..b0f3b63d 100644 --- a/interchaintest/go.sum +++ b/interchaintest/go.sum @@ -808,8 +808,8 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neilotoole/errgroup v0.1.6/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/noble-assets/forwarding v1.1.0 h1:2TXBs2Y9vWqgHyDKtdcHht6i7OT+pLaVHE3bPvfpmJY= -github.com/noble-assets/forwarding v1.1.0/go.mod h1:o64ZfzCHteRDhOlkpi7GeKAcjlcbWUihC7Y34Er2/3U= +github.com/noble-assets/forwarding v1.2.0-rc.0 h1:f/bL/cicvhNUp9SuueiqqqSVRRn7CQxTKOesVUKrSyQ= +github.com/noble-assets/forwarding v1.2.0-rc.0/go.mod h1:o64ZfzCHteRDhOlkpi7GeKAcjlcbWUihC7Y34Er2/3U= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index e39c16c0..259ee8bd 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -64,7 +64,7 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // i.e., totalGas <= MaxTotalBypassMinFeeMsgGasUsage // Otherwise, minimum fees and global fees are checked to prevent spam. doesNotExceedMaxGasUsage := gas <= mfd.MaxTotalBypassMinFeeMsgGasUsage - allowedToBypassMinFee := mfd.containsOnlyBypassMinFeeMsgs(ctx, msgs) && doesNotExceedMaxGasUsage + allowedToBypassMinFee := (mfd.containsOnlyBypassMinFeeMsgs(ctx, msgs) || mfd.isSignerlessForwardingRegistration(msgs)) && doesNotExceedMaxGasUsage var allFees sdk.Coins requiredGlobalFees, err := mfd.getGlobalFee(ctx, feeTx) diff --git a/x/globalfee/ante/fee_utils.go b/x/globalfee/ante/fee_utils.go index 752d227f..bedab685 100644 --- a/x/globalfee/ante/fee_utils.go +++ b/x/globalfee/ante/fee_utils.go @@ -4,6 +4,7 @@ import ( "math" sdk "github.com/cosmos/cosmos-sdk/types" + forwardingtypes "github.com/noble-assets/forwarding/x/forwarding/types" globalfeetypes "github.com/noble-assets/noble/v7/x/globalfee/types" tmstrings "github.com/tendermint/tendermint/libs/strings" ) @@ -45,6 +46,21 @@ func (mfd FeeDecorator) containsOnlyBypassMinFeeMsgs(ctx sdk.Context, msgs []sdk return true } +func (mfd FeeDecorator) isSignerlessForwardingRegistration(msgs []sdk.Msg) bool { + if len(msgs) != 1 { + return false + } + + msg, ok := msgs[0].(*forwardingtypes.MsgRegisterAccount) + if !ok { + return false + } + + address := forwardingtypes.GenerateAddress(msg.Channel, msg.Recipient) + + return msg.Signer == address.String() +} + // DenomsSubsetOfIncludingZero and IsAnyGTEIncludingZero are similar to DenomsSubsetOf and IsAnyGTE in sdk. Since we allow zero coins in global fee(zero coins means the chain does not want to set a global fee but still want to define the fee's denom) // // overwrite DenomsSubsetOfIncludingZero from sdk, to allow zero amt coins in superset. e.g. 1stake is DenomsSubsetOfIncludingZero 0stake. [] is the DenomsSubsetOfIncludingZero of [0stake] but not [1stake].