Skip to content

Commit

Permalink
Support creation of feegrants supplied from a marker (#832)
Browse files Browse the repository at this point in the history
* update third party proto deps

* add feegrant creation support to marker tx

* add GrantAllowance msg

* add feegrant keeper to marker setup

* initial implementation of marker grantallowance

* changelog update

* msg tests

* cli methods and admin feegrant to self

* reorder marker cli tests

* rename feegrant proto msg as request

* add another cli test for failing access case
  • Loading branch information
iramiller authored May 27, 2022
1 parent 2400474 commit 0ec8058
Show file tree
Hide file tree
Showing 17 changed files with 1,132 additions and 119 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Features

* Add CONTROLLER, and VALIDATOR PartyTypes for contract execution.
* Add CONTROLLER, and VALIDATOR PartyTypes for contract execution. [\#824](https://github.com/provenance-io/provenance/pull/824])
* Add FeeGrant allowance support for marker escrow accounts [#406](https://github.com/provenance-io/provenance/issues/406)

### Improvements

Expand Down
6 changes: 3 additions & 3 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ func New(
)

app.MarkerKeeper = markerkeeper.NewKeeper(
appCodec, keys[markertypes.StoreKey], app.GetSubspace(markertypes.ModuleName), app.AccountKeeper, app.BankKeeper, app.AuthzKeeper, keys[banktypes.StoreKey],
appCodec, keys[markertypes.StoreKey], app.GetSubspace(markertypes.ModuleName), app.AccountKeeper, app.BankKeeper, app.AuthzKeeper, app.FeeGrantKeeper, keys[banktypes.StoreKey],
)

app.NameKeeper = namekeeper.NewKeeper(
Expand Down Expand Up @@ -579,7 +579,7 @@ func New(

// PROVENANCE
metadata.NewAppModule(appCodec, app.MetadataKeeper, app.AccountKeeper),
marker.NewAppModule(appCodec, app.MarkerKeeper, app.AccountKeeper, app.BankKeeper),
marker.NewAppModule(appCodec, app.MarkerKeeper, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper),
name.NewAppModule(appCodec, app.NameKeeper, app.AccountKeeper, app.BankKeeper),
attribute.NewAppModule(appCodec, app.AttributeKeeper, app.AccountKeeper, app.BankKeeper, app.NameKeeper),
msgfeesmodule.NewAppModule(appCodec, app.MsgFeesKeeper, app.interfaceRegistry),
Expand Down Expand Up @@ -741,7 +741,7 @@ func New(
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),

metadata.NewAppModule(appCodec, app.MetadataKeeper, app.AccountKeeper),
marker.NewAppModule(appCodec, app.MarkerKeeper, app.AccountKeeper, app.BankKeeper),
marker.NewAppModule(appCodec, app.MarkerKeeper, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper),
name.NewAppModule(appCodec, app.NameKeeper, app.AccountKeeper, app.BankKeeper),
attribute.NewAppModule(appCodec, app.AttributeKeeper, app.AccountKeeper, app.BankKeeper, app.NameKeeper),
msgfeesmodule.NewAppModule(appCodec, app.MsgFeesKeeper, app.interfaceRegistry),
Expand Down
32 changes: 32 additions & 0 deletions docs/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@
- [MsgDeleteResponse](#provenance.marker.v1.MsgDeleteResponse)
- [MsgFinalizeRequest](#provenance.marker.v1.MsgFinalizeRequest)
- [MsgFinalizeResponse](#provenance.marker.v1.MsgFinalizeResponse)
- [MsgGrantAllowanceRequest](#provenance.marker.v1.MsgGrantAllowanceRequest)
- [MsgGrantAllowanceResponse](#provenance.marker.v1.MsgGrantAllowanceResponse)
- [MsgMintRequest](#provenance.marker.v1.MsgMintRequest)
- [MsgMintResponse](#provenance.marker.v1.MsgMintResponse)
- [MsgSetDenomMetadataRequest](#provenance.marker.v1.MsgSetDenomMetadataRequest)
Expand Down Expand Up @@ -2030,6 +2032,35 @@ MsgFinalizeResponse defines the Msg/Finalize response type



<a name="provenance.marker.v1.MsgGrantAllowanceRequest"></a>

### MsgGrantAllowanceRequest
MsgGrantAllowanceRequest validates permission to create a fee grant based on marker admin access. If
successful a feegrant is recorded where the marker account itself is the grantor


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `denom` | [string](#string) | | |
| `administrator` | [string](#string) | | |
| `grantee` | [string](#string) | | grantee is the address of the user being granted an allowance of another user's funds. |
| `allowance` | [google.protobuf.Any](#google.protobuf.Any) | | allowance can be any of basic and filtered fee allowance (fee FeeGrant module). |






<a name="provenance.marker.v1.MsgGrantAllowanceResponse"></a>

### MsgGrantAllowanceResponse
MsgGrantAllowanceResponse defines the Msg/GrantAllowanceResponse response type.






<a name="provenance.marker.v1.MsgMintRequest"></a>

### MsgMintRequest
Expand Down Expand Up @@ -2163,6 +2194,7 @@ Msg defines the Marker Msg service.
| `AddMarker` | [MsgAddMarkerRequest](#provenance.marker.v1.MsgAddMarkerRequest) | [MsgAddMarkerResponse](#provenance.marker.v1.MsgAddMarkerResponse) | AddMarker | |
| `Transfer` | [MsgTransferRequest](#provenance.marker.v1.MsgTransferRequest) | [MsgTransferResponse](#provenance.marker.v1.MsgTransferResponse) | Transfer marker denominated coin between accounts | |
| `SetDenomMetadata` | [MsgSetDenomMetadataRequest](#provenance.marker.v1.MsgSetDenomMetadataRequest) | [MsgSetDenomMetadataResponse](#provenance.marker.v1.MsgSetDenomMetadataResponse) | Allows Denom Metadata (see bank module) to be set for the Marker's Denom | |
| `GrantAllowance` | [MsgGrantAllowanceRequest](#provenance.marker.v1.MsgGrantAllowanceRequest) | [MsgGrantAllowanceResponse](#provenance.marker.v1.MsgGrantAllowanceResponse) | GrantAllowance grants fee allowance to the grantee on the granter's account with the provided expiration time. | |

<!-- end services -->

Expand Down
21 changes: 21 additions & 0 deletions proto/provenance/marker/v1/tx.proto
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
syntax = "proto3";
package provenance.marker.v1;

import "google/protobuf/any.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos/bank/v1beta1/bank.proto";
Expand Down Expand Up @@ -38,8 +40,27 @@ service Msg {
rpc Transfer(MsgTransferRequest) returns (MsgTransferResponse);
// Allows Denom Metadata (see bank module) to be set for the Marker's Denom
rpc SetDenomMetadata(MsgSetDenomMetadataRequest) returns (MsgSetDenomMetadataResponse);
// GrantAllowance grants fee allowance to the grantee on the granter's
// account with the provided expiration time.
rpc GrantAllowance(MsgGrantAllowanceRequest) returns (MsgGrantAllowanceResponse);
}

// MsgGrantAllowanceRequest validates permission to create a fee grant based on marker admin access. If
// successful a feegrant is recorded where the marker account itself is the grantor
message MsgGrantAllowanceRequest {
string denom = 1;
string administrator = 2;

// grantee is the address of the user being granted an allowance of another user's funds.
string grantee = 3;

// allowance can be any of basic and filtered fee allowance (fee FeeGrant module).
google.protobuf.Any allowance = 4 [(cosmos_proto.accepts_interface) = "FeeAllowanceI"];
}

// MsgGrantAllowanceResponse defines the Msg/GrantAllowanceResponse response type.
message MsgGrantAllowanceResponse {}

// MsgAddMarkerRequest defines the Msg/AddMarker request type
message MsgAddMarkerRequest {
cosmos.base.v1beta1.Coin amount = 1
Expand Down
66 changes: 56 additions & 10 deletions x/marker/client/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"sort"
"strings"
"testing"
"time"

"github.com/gogo/protobuf/proto"
"github.com/spf13/cobra"
Expand All @@ -32,6 +33,11 @@ import (
markertypes "github.com/provenance-io/provenance/x/marker/types"
)

const (
oneYear = 365 * 24 * 60 * 60
oneHour = 60 * 60
)

type IntegrationTestSuite struct {
suite.Suite

Expand Down Expand Up @@ -550,6 +556,21 @@ func (s *IntegrationTestSuite) TestMarkerTxCommands() {
},
true, &sdk.TxResponse{}, 0,
},
{
"fail to create feegrant not admin",
markercli.GetCmdFeeGrant(),
[]string{
"hotdog",
s.testnet.Validators[0].Address.String(),
s.accountAddresses[0].String(),
fmt.Sprintf("--%s=%s", markercli.FlagSpendLimit, sdk.NewCoin("stake", sdk.NewInt(100))),
fmt.Sprintf("--%s=%s", markercli.FlagExpiration, getFormattedExpiration(oneYear)),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
},
false, &sdk.TxResponse{}, 4,
},
{
"add single access",
markercli.GetCmdAddAccess(),
Expand Down Expand Up @@ -626,6 +647,37 @@ func (s *IntegrationTestSuite) TestMarkerTxCommands() {
},
false, &sdk.TxResponse{}, 0,
},
{
"create simple feegrant allowance",
markercli.GetCmdFeeGrant(),
[]string{
"hotdog",
s.testnet.Validators[0].Address.String(),
s.accountAddresses[0].String(),
fmt.Sprintf("--%s=%s", markercli.FlagSpendLimit, sdk.NewCoin("stake", sdk.NewInt(100))),
fmt.Sprintf("--%s=%s", markercli.FlagExpiration, getFormattedExpiration(oneYear)),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
},
false, &sdk.TxResponse{}, 0,
},
{
"create periodic feegrant allowance",
markercli.GetCmdFeeGrant(),
[]string{
"hotdog",
s.testnet.Validators[0].Address.String(),
s.accountAddresses[0].String(),
fmt.Sprintf("--%s=%v", markercli.FlagPeriod, oneHour),
fmt.Sprintf("--%s=%s", markercli.FlagPeriodLimit, sdk.NewCoin("stake", sdk.NewInt(100))),
fmt.Sprintf("--%s=%s", markercli.FlagExpiration, getFormattedExpiration(oneYear)),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
},
false, &sdk.TxResponse{}, 0,
},
{
"withdraw, fail to parse coins",
markercli.GetCmdWithdrawCoins(),
Expand Down Expand Up @@ -1038,16 +1090,6 @@ func (s *IntegrationTestSuite) TestMarkerTxGovProposals() {
}
}

func (s *IntegrationTestSuite) TestMarkerGetTxCmd() {
s.Run("marker cli tx commands not nil", func() {
tx := markercli.NewTxCmd()
s.Require().NotNil(tx)
s.Require().Equal(len(tx.Commands()), 14)
s.Require().Equal(tx.Use, markertypes.ModuleName)
s.Require().Equal(tx.Short, "Transaction commands for the marker module")
})
}

func (s *IntegrationTestSuite) TestPaginationWithPageKey() {
asJson := fmt.Sprintf("--%s=json", tmcli.OutputFlag)

Expand Down Expand Up @@ -1164,3 +1206,7 @@ func (s *IntegrationTestSuite) TestPaginationWithPageKey() {
}
})
}

func getFormattedExpiration(duration int64) string {
return time.Now().Add(time.Duration(duration) * time.Second).Format(time.RFC3339)
}
Loading

0 comments on commit 0ec8058

Please sign in to comment.