diff --git a/app/ante/deduct_fee_decorator.go b/app/ante/deduct_fee_decorator.go index 4299e6b..f14985e 100644 --- a/app/ante/deduct_fee_decorator.go +++ b/app/ante/deduct_fee_decorator.go @@ -84,6 +84,10 @@ func (dfd DeductFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bo var ( err error ) + msgs := tx.GetMsgs() + if len(msgs) == 1 && sdk.MsgTypeURL(msgs[0]) == "/planetmintgo.machine.MsgAttestMachine" { + return next(ctx, tx, simulate) + } fee := feeTx.GetFee() if !simulate { diff --git a/lib/tx.go b/lib/tx.go index 7bbe213..55d468d 100644 --- a/lib/tx.go +++ b/lib/tx.go @@ -37,7 +37,7 @@ func getAccountNumberAndSequence(clientCtx client.Context) (accountNumber, seque return } -func getClientContextAndTxFactory(fromAddress sdk.AccAddress) (clientCtx client.Context, txf tx.Factory, err error) { +func getClientContextAndTxFactory(fromAddress sdk.AccAddress, withoutFee bool) (clientCtx client.Context, txf tx.Factory, err error) { clientCtx = GetConfig().clientCtx // at least we need an account retriever // it would be better to check for an empty client context, but that does not work at the moment @@ -60,18 +60,22 @@ func getClientContextAndTxFactory(fromAddress sdk.AccAddress) (clientCtx client. if err != nil { return } - txf = getTxFactoryWithAccountNumberAndSequence(clientCtx, accountNumber, sequence) + gasPrice := "0.000005" + if withoutFee { + gasPrice = "0.0" + } + txf = getTxFactoryWithAccountNumberAndSequence(clientCtx, accountNumber, sequence, gasPrice) return } -func getTxFactoryWithAccountNumberAndSequence(clientCtx client.Context, accountNumber, sequence uint64) (txf tx.Factory) { +func getTxFactoryWithAccountNumberAndSequence(clientCtx client.Context, accountNumber, sequence uint64, gasPrice string) (txf tx.Factory) { return tx.Factory{}. WithAccountNumber(accountNumber). WithAccountRetriever(clientCtx.AccountRetriever). WithChainID(clientCtx.ChainID). WithFeeGranter(clientCtx.FeeGranter). WithGas(GetConfig().txGas). - WithGasPrices("0.000005" + GetConfig().feeDenom). + WithGasPrices(gasPrice + GetConfig().feeDenom). WithKeybase(clientCtx.Keyring). WithSequence(sequence). WithTxConfig(clientCtx.TxConfig) @@ -128,10 +132,21 @@ func getClientContext(fromAddress sdk.AccAddress) (clientCtx client.Context, err return } +func isMachineAttestationMsg(msgs ...sdk.Msg) (isMachineAttestation bool) { + if len(msgs) != 1 { + return + } + if sdk.MsgTypeURL(msgs[0]) == "/planetmintgo.machine.MsgAttestMachine" { + isMachineAttestation = true + } + return +} + // BuildUnsignedTx builds a transaction to be signed given a set of messages. // Once created, the fee, memo, and messages are set. func BuildUnsignedTx(fromAddress sdk.AccAddress, msgs ...sdk.Msg) (txJSON string, err error) { - clientCtx, txf, err := getClientContextAndTxFactory(fromAddress) + withoutFee := isMachineAttestationMsg(msgs...) + clientCtx, txf, err := getClientContextAndTxFactory(fromAddress, withoutFee) if err != nil { return } @@ -197,7 +212,8 @@ func BroadcastTxWithFileLock(fromAddress sdk.AccAddress, msgs ...sdk.Msg) (out * }() // get basic chain information - clientCtx, txf, err := getClientContextAndTxFactory(fromAddress) + withoutFee := isMachineAttestationMsg(msgs...) + clientCtx, txf, err := getClientContextAndTxFactory(fromAddress, withoutFee) if err != nil { return } diff --git a/tests/e2e/machine/suite.go b/tests/e2e/machine/suite.go index 3f38e93..4b1de37 100644 --- a/tests/e2e/machine/suite.go +++ b/tests/e2e/machine/suite.go @@ -1,6 +1,8 @@ package machine import ( + "bytes" + "github.com/planetmint/planetmint-go/lib" clitestutil "github.com/planetmint/planetmint-go/testutil/cli" "github.com/planetmint/planetmint-go/testutil/network" @@ -11,6 +13,8 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" + txcli "github.com/cosmos/cosmos-sdk/x/auth/tx" + bank "github.com/cosmos/cosmos-sdk/x/bank/client/cli" "github.com/cosmos/cosmos-sdk/x/feegrant" e2etestutil "github.com/planetmint/planetmint-go/testutil/e2e" "github.com/stretchr/testify/assert" @@ -74,6 +78,17 @@ func (s *E2ETestSuite) TestAttestMachine() { s.Require().NoError(err) addr, _ := k.GetAddress() + // Check preAttestationBalance in order to verify that it doesn't change after machine attestation + preAttestationBalanceOutput, err := clitestutil.ExecTestCLICmd(val.ClientCtx, bank.GetBalancesCmd(), []string{ + addr.String(), + }) + s.Require().NoError(err) + preAttestationBalance, ok := preAttestationBalanceOutput.(*bytes.Buffer) + if !ok { + err = lib.ErrTypeAssertionFailed + s.Require().NoError(err) + } + machine := moduleobject.Machine(sample.Name, pubKey, prvKey, addr.String()) msg2 := machinetypes.NewMsgAttestMachine(addr.String(), &machine) out, err = e2etestutil.BuildSignBroadcastTx(s.T(), addr, msg2) @@ -95,6 +110,27 @@ func (s *E2ETestSuite) TestAttestMachine() { _, err = clitestutil.ExecTestCLICmd(val.ClientCtx, machinecli.CmdGetMachineByPublicKey(), args) s.Require().NoError(err) + txResponse, err := lib.GetTxResponseFromOut(out) + s.Require().NoError(err) + + txResp, err := txcli.QueryTx(val.ClientCtx, txResponse.TxHash) + s.Require().NoError(err) + + assert.Contains(s.T(), txResp.TxHash, txResponse.TxHash) + s.Require().NoError(err) + + // Check postAttestationBalance as it should be the same as prior to the machine attestation + postAttestationBalanceOutput, err := clitestutil.ExecTestCLICmd(val.ClientCtx, bank.GetBalancesCmd(), []string{ + addr.String(), + }) + s.Require().NoError(err) + postAttestationBalance, ok := postAttestationBalanceOutput.(*bytes.Buffer) + if !ok { + err = lib.ErrTypeAssertionFailed + s.Require().NoError(err) + } + + assert.Equal(s.T(), preAttestationBalance, postAttestationBalance) } func (s *E2ETestSuite) TestInvalidAttestMachine() {