diff --git a/CHANGELOG.md b/CHANGELOG.md index 913bce77f6f..eed1e5db8ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,12 @@ Ref: https://keepachangelog.com/en/1.0.0/ # Changelog +## [Unreleased] + +### Features + +* [\#9860](https://github.com/cosmos/cosmos-sdk/pull/9860) Emit transaction fee in ante handler fee decorator. The event type is `tx` and the attribute is `fee`. + ## [v0.43.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.43.0) - 2021-08-10 ### Features @@ -203,7 +209,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#9720](https://github.com/cosmos/cosmos-sdk/pull/9720) Feegrant grant cli granter now accepts key name as well as address in general and accepts only address in --generate-only mode * [\#9766](https://github.com/cosmos/cosmos-sdk/pull/9766) Fix hardcoded ledger signing algorithm on `keys add` command. * [\#9793](https://github.com/cosmos/cosmos-sdk/pull/9793) Fixed ECDSA/secp256r1 transaction malleability. -* (server) [#9704](https://github.com/cosmos/cosmos-sdk/pull/9704) Start GRPCWebServer in goroutine, avoid blocking other services from starting. +* (server) [#9704](https://github.com/cosmos/cosmos-sdk/pull/9704) Start GRPCWebServer in goroutine, avoid blocking other services from starting. * (bank) [\#9687](https://github.com/cosmos/cosmos-sdk/issues/9687) fixes [\#9159](https://github.com/cosmos/cosmos-sdk/issues/9159). Added migration to prune balances with zero coins. diff --git a/types/events.go b/types/events.go index 27a0017635a..9c495a9da2a 100644 --- a/types/events.go +++ b/types/events.go @@ -227,6 +227,7 @@ var ( AttributeKeyAccountSequence = "acc_seq" AttributeKeySignature = "signature" + AttributeKeyFee = "fee" EventTypeMessage = "message" diff --git a/x/auth/ante/fee.go b/x/auth/ante/fee.go index e183887d0fc..b1d1d72a770 100644 --- a/x/auth/ante/fee.go +++ b/x/auth/ante/fee.go @@ -117,6 +117,11 @@ func (dfd DeductFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bo } } + events := sdk.Events{sdk.NewEvent(sdk.EventTypeTx, + sdk.NewAttribute(sdk.AttributeKeyFee, feeTx.GetFee().String()), + )} + ctx.EventManager().EmitEvents(events) + return next(ctx, tx, simulate) } diff --git a/x/auth/client/testutil/suite.go b/x/auth/client/testutil/suite.go index b2f43ca69ab..ca21194040c 100644 --- a/x/auth/client/testutil/suite.go +++ b/x/auth/client/testutil/suite.go @@ -426,6 +426,76 @@ func (s *IntegrationTestSuite) TestCLIQueryTxCmdByEvents() { } } +func (s *IntegrationTestSuite) TestCLIQueryTxsCmdByEvents() { + val := s.network.Validators[0] + + account2, err := val.ClientCtx.Keyring.Key("newAccount2") + s.Require().NoError(err) + + sendTokens := sdk.NewInt64Coin(s.cfg.BondDenom, 10) + + // Send coins. + out, err := s.createBankMsg( + val, account2.GetAddress(), + sdk.NewCoins(sendTokens), + ) + s.Require().NoError(err) + var txRes sdk.TxResponse + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &txRes)) + s.Require().NoError(s.network.WaitForNextBlock()) + + // Query the tx by hash to get the inner tx. + out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, authcli.QueryTxCmd(), []string{txRes.TxHash, fmt.Sprintf("--%s=json", tmcli.OutputFlag)}) + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &txRes)) + + testCases := []struct { + name string + args []string + expectEmpty bool + }{ + { + "fee event happy case", + []string{ + fmt.Sprintf("--events=tx.fee=%s", + sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }, + false, + }, + { + "no matching fee event", + []string{ + fmt.Sprintf("--events=tx.fee=%s", + sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(0))).String()), + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }, + true, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + cmd := authcli.QueryTxsByEventsCmd() + clientCtx := val.ClientCtx + + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + s.Require().NoError(err) + + var result sdk.SearchTxsResult + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &result)) + + if tc.expectEmpty { + s.Require().Equal(0, len(result.Txs)) + } else { + s.Require().NotEqual(0, len(result.Txs)) + s.Require().NotNil(result.Txs[0]) + } + }) + } +} + func (s *IntegrationTestSuite) TestCLISendGenerateSignAndBroadcast() { val1 := s.network.Validators[0]