diff --git a/CHANGELOG.md b/CHANGELOG.md
index 65ebe2b7eb..cc4af23563 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -40,6 +40,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Features
* Added support to set a list of specific recipients allowed for send authorizations in the marker module [#1237](https://github.com/provenance-io/provenance/issues/1237).
+* Added msg to add, finalize, and activate a marker in a single request [#770](https://github.com/provenance-io/provenance/issues/770).
### Improvements
diff --git a/app/params/weights.go b/app/params/weights.go
index 22e5c5e984..ecbe1a58b2 100644
--- a/app/params/weights.go
+++ b/app/params/weights.go
@@ -19,11 +19,11 @@ const (
DefaultWeightRemoveAdministratorProposalContent int = 5
DefaultWeightChangeStatusProposalContent int = 5
DefaultWeightSetDenomMetadataProposalContent int = 5
- DefaultWeightMsgAddMarker int = 100
- DefaultWeightMsgChangeStatus int = 10
- DefaultWeightMsgAddAccess int = 10
- DefaultWeightMsgMintMarker int = 67
- DefaultWeightMsgBurnMarker int = 67
+ // Adjusted marker operations to a cumulative weight of 100
+ DefaultWeightMsgAddMarker int = 60
+ DefaultWeightMsgChangeStatus int = 10
+ DefaultWeightMsgAddAccess int = 10
+ DefaultWeightMsgAddFinalizeActivateMarker int = 20
// MsgFees
DefaultWeightAddMsgFeeProposalContent int = 75
DefaultWeightRemoveMsgFeeProposalContent int = 25
diff --git a/docs/proto-docs.md b/docs/proto-docs.md
index de9081b3e1..01d07c1210 100644
--- a/docs/proto-docs.md
+++ b/docs/proto-docs.md
@@ -112,6 +112,8 @@
- [MsgActivateResponse](#provenance.marker.v1.MsgActivateResponse)
- [MsgAddAccessRequest](#provenance.marker.v1.MsgAddAccessRequest)
- [MsgAddAccessResponse](#provenance.marker.v1.MsgAddAccessResponse)
+ - [MsgAddFinalizeActivateMarkerRequest](#provenance.marker.v1.MsgAddFinalizeActivateMarkerRequest)
+ - [MsgAddFinalizeActivateMarkerResponse](#provenance.marker.v1.MsgAddFinalizeActivateMarkerResponse)
- [MsgAddMarkerRequest](#provenance.marker.v1.MsgAddMarkerRequest)
- [MsgAddMarkerResponse](#provenance.marker.v1.MsgAddMarkerResponse)
- [MsgBurnRequest](#provenance.marker.v1.MsgBurnRequest)
@@ -933,7 +935,7 @@ Msg defines the attribute module Msg service.
### AccessGrant
-AccessGrant associates a colelction of permisssions with an address for delegated marker account control.
+AccessGrant associates a collection of permissions with an address for delegated marker account control.
| Field | Type | Label | Description |
@@ -1928,6 +1930,37 @@ MsgAddAccessResponse defines the Msg/AddAccess response type
+
+
+### MsgAddFinalizeActivateMarkerRequest
+MsgAddFinalizeActivateMarkerRequest defines the Msg/AddFinalizeActivateMarker request type
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | | |
+| `manager` | [string](#string) | | |
+| `from_address` | [string](#string) | | |
+| `marker_type` | [MarkerType](#provenance.marker.v1.MarkerType) | | |
+| `access_list` | [AccessGrant](#provenance.marker.v1.AccessGrant) | repeated | |
+| `supply_fixed` | [bool](#bool) | | |
+| `allow_governance_control` | [bool](#bool) | | |
+
+
+
+
+
+
+
+
+### MsgAddFinalizeActivateMarkerResponse
+MsgAddFinalizeActivateMarkerResponse defines the Msg/AddFinalizeActivateMarker response type
+
+
+
+
+
+
### MsgAddMarkerRequest
@@ -2281,6 +2314,7 @@ Msg defines the Marker Msg service.
| `IbcTransfer` | [MsgIbcTransferRequest](#provenance.marker.v1.MsgIbcTransferRequest) | [MsgIbcTransferResponse](#provenance.marker.v1.MsgIbcTransferResponse) | Transfer over ibc any marker(including restricted markers) between ibc accounts. The relayer is still needed to accomplish ibc middleware relays. | |
| `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. | |
+| `AddFinalizeActivateMarker` | [MsgAddFinalizeActivateMarkerRequest](#provenance.marker.v1.MsgAddFinalizeActivateMarkerRequest) | [MsgAddFinalizeActivateMarkerResponse](#provenance.marker.v1.MsgAddFinalizeActivateMarkerResponse) | AddFinalizeActivateMarker | |
diff --git a/proto/provenance/marker/v1/accessgrant.proto b/proto/provenance/marker/v1/accessgrant.proto
index 913d3a3038..4ab790420d 100644
--- a/proto/provenance/marker/v1/accessgrant.proto
+++ b/proto/provenance/marker/v1/accessgrant.proto
@@ -10,7 +10,7 @@ option java_package = "io.provenance.marker.v1";
option java_multiple_files = true;
option java_outer_classname = "AccessGrantProto";
-// AccessGrant associates a colelction of permisssions with an address for delegated marker account control.
+// AccessGrant associates a collection of permissions with an address for delegated marker account control.
message AccessGrant {
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
diff --git a/proto/provenance/marker/v1/tx.proto b/proto/provenance/marker/v1/tx.proto
index a5764ba628..935b31aab6 100644
--- a/proto/provenance/marker/v1/tx.proto
+++ b/proto/provenance/marker/v1/tx.proto
@@ -47,6 +47,8 @@ service Msg {
// GrantAllowance grants fee allowance to the grantee on the granter's
// account with the provided expiration time.
rpc GrantAllowance(MsgGrantAllowanceRequest) returns (MsgGrantAllowanceResponse);
+ // AddFinalizeActivateMarker
+ rpc AddFinalizeActivateMarker(MsgAddFinalizeActivateMarkerRequest) returns (MsgAddFinalizeActivateMarkerResponse);
}
// MsgGrantAllowanceRequest validates permission to create a fee grant based on marker admin access. If
@@ -193,4 +195,19 @@ message MsgSetDenomMetadataRequest {
}
// MsgSetDenomMetadataResponse defines the Msg/SetDenomMetadata response type
-message MsgSetDenomMetadataResponse {}
\ No newline at end of file
+message MsgSetDenomMetadataResponse {}
+
+// MsgAddFinalizeActivateMarkerRequest defines the Msg/AddFinalizeActivateMarker request type
+message MsgAddFinalizeActivateMarkerRequest {
+ cosmos.base.v1beta1.Coin amount = 1
+ [(gogoproto.nullable) = false, (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coin"];
+ string manager = 3;
+ string from_address = 4;
+ MarkerType marker_type = 5;
+ repeated AccessGrant access_list = 6 [(gogoproto.nullable) = false];
+ bool supply_fixed = 7;
+ bool allow_governance_control = 8;
+}
+
+// MsgAddFinalizeActivateMarkerResponse defines the Msg/AddFinalizeActivateMarker response type
+message MsgAddFinalizeActivateMarkerResponse {}
diff --git a/x/marker/client/cli/cli_test.go b/x/marker/client/cli/cli_test.go
index a5249f59c6..72d51ea794 100644
--- a/x/marker/client/cli/cli_test.go
+++ b/x/marker/client/cli/cli_test.go
@@ -31,6 +31,7 @@ import (
"github.com/provenance-io/provenance/internal/pioconfig"
"github.com/provenance-io/provenance/testutil"
markercli "github.com/provenance-io/provenance/x/marker/client/cli"
+ "github.com/provenance-io/provenance/x/marker/types"
markertypes "github.com/provenance-io/provenance/x/marker/types"
)
@@ -1254,3 +1255,193 @@ func (s *IntegrationTestSuite) TestPaginationWithPageKey() {
func getFormattedExpiration(duration int64) string {
return time.Now().Add(time.Duration(duration) * time.Second).Format(time.RFC3339)
}
+
+func (s *IntegrationTestSuite) TestAddFinalizeActivateMarkerTxCommands() {
+
+ testCases := []struct {
+ name string
+ cmd *cobra.Command
+ args []string
+ expectErr bool
+ respType proto.Message
+ expectedCode uint32
+ }{
+ {
+ "create a new marker, finalize it and activate it.",
+ markercli.GetCmdAddFinalizeActivateMarker(),
+ []string{
+ "1000newhotdog",
+ getAccessGrantString(s.testnet.Validators[0].Address, s.accountAddresses[1]),
+ fmt.Sprintf("--%s=%s", markercli.FlagType, "RESTRICTED"),
+ fmt.Sprintf("--%s=%s", markercli.FlagSupplyFixed, "true"),
+ fmt.Sprintf("--%s=%s", markercli.FlagAllowGovernanceControl, "true"),
+ fmt.Sprintf("--%s=%s", flags.FlagFrom, s.testnet.Validators[0].Address.String()),
+ 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 a new marker, finalize it and activate it, with access grant to one address ",
+ markercli.GetCmdAddFinalizeActivateMarker(),
+ []string{
+ "1000newhotdog1",
+ getAccessGrantString(s.testnet.Validators[0].Address, nil),
+ fmt.Sprintf("--%s=%s", markercli.FlagType, "RESTRICTED"),
+ fmt.Sprintf("--%s=%s", markercli.FlagSupplyFixed, "true"),
+ fmt.Sprintf("--%s=%s", markercli.FlagAllowGovernanceControl, "true"),
+ fmt.Sprintf("--%s=%s", flags.FlagFrom, s.testnet.Validators[0].Address.String()),
+ 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 a new marker with no access grant ",
+ markercli.GetCmdAddFinalizeActivateMarker(),
+ []string{
+ "1000newhotdog1",
+ fmt.Sprintf("--%s=%s", markercli.FlagType, "RESTRICTED"),
+ fmt.Sprintf("--%s=%s", markercli.FlagSupplyFixed, "true"),
+ fmt.Sprintf("--%s=%s", markercli.FlagAllowGovernanceControl, "true"),
+ fmt.Sprintf("--%s=%s", flags.FlagFrom, s.testnet.Validators[0].Address.String()),
+ 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()),
+ },
+ true, &sdk.TxResponse{}, 0,
+ },
+ {
+ "create a new marker, finalize it and activate it with dashes and periods",
+ markercli.GetCmdAddFinalizeActivateMarker(),
+ []string{
+ "1000newcat-scratch-fever.bobcat",
+ getAccessGrantString(s.testnet.Validators[0].Address, nil),
+ fmt.Sprintf("--%s=%s", markercli.FlagType, "RESTRICTED"),
+ fmt.Sprintf("--%s=%s", markercli.FlagSupplyFixed, "true"),
+ fmt.Sprintf("--%s=%s", markercli.FlagAllowGovernanceControl, "true"),
+ fmt.Sprintf("--%s=%s", flags.FlagFrom, s.testnet.Validators[0].Address.String()),
+ 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,
+ },
+ {
+ "fail to create add/finalize/activate marker, incorrect allow governance value",
+ markercli.GetCmdAddFinalizeActivateMarker(),
+ []string{
+ "1000hotdog",
+ getAccessGrantString(s.testnet.Validators[0].Address, nil),
+ fmt.Sprintf("--%s=%s", markercli.FlagType, "RESTRICTED"),
+ fmt.Sprintf("--%s=%s", markercli.FlagSupplyFixed, "false"),
+ fmt.Sprintf("--%s=%s", markercli.FlagAllowGovernanceControl, "wrong"),
+ fmt.Sprintf("--%s=%s", flags.FlagFrom, s.testnet.Validators[0].Address.String()),
+ 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()),
+ },
+ true, &sdk.TxResponse{}, 0,
+ },
+ {
+ "fail to create add/finalize/activate marker, incorrect supply fixed value",
+ markercli.GetCmdAddFinalizeActivateMarker(),
+ []string{
+ "1000hotdog",
+ getAccessGrantString(s.testnet.Validators[0].Address, nil),
+ fmt.Sprintf("--%s=%s", markercli.FlagType, "RESTRICTED"),
+ fmt.Sprintf("--%s=%s", markercli.FlagSupplyFixed, "wrong"),
+ fmt.Sprintf("--%s=%s", markercli.FlagAllowGovernanceControl, "true"),
+ fmt.Sprintf("--%s=%s", flags.FlagFrom, s.testnet.Validators[0].Address.String()),
+ 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()),
+ },
+ true, &sdk.TxResponse{}, 0,
+ },
+ }
+
+ for _, tc := range testCases {
+ tc := tc
+
+ s.Run(tc.name, func() {
+ clientCtx := s.testnet.Validators[0].ClientCtx
+
+ out, err := clitestutil.ExecTestCLICmd(clientCtx, tc.cmd, tc.args)
+ if tc.expectErr {
+ s.Require().Error(err)
+ } else {
+ s.Require().NoError(err)
+ s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
+ txResp := tc.respType.(*sdk.TxResponse)
+ s.Require().Equal(tc.expectedCode, txResp.Code)
+ }
+ })
+ }
+}
+
+func getAccessGrantString(address sdk.AccAddress, anotherAddress sdk.AccAddress) string {
+ if anotherAddress != nil {
+ accessGrant := address.String() + ",mint,admin;" + anotherAddress.String() + ",burn"
+ return accessGrant
+ } else {
+ accessGrant := address.String() + ",mint,admin;"
+ return accessGrant
+ }
+}
+
+func (s *IntegrationTestSuite) TestParseAccessGrantFromString() {
+ testCases := []struct {
+ name string
+ accessGrantString string
+ expectPanic bool
+ expectedResult []types.AccessGrant
+ }{
+ {
+ "successfully parses empty string",
+ "",
+ false,
+ []types.AccessGrant{},
+ },
+ {
+ "fails parsing invalid string",
+ "blah",
+ true,
+ []types.AccessGrant{},
+ },
+ {
+ "should fail empty list of permissions",
+ ",,;",
+ true,
+ []types.AccessGrant{},
+ },
+ {
+ "should fail address is not valid",
+ "NotAnAddress,mint;",
+ true,
+ []types.AccessGrant{},
+ },
+ {
+ "should succeed to add access type",
+ fmt.Sprintf("%s,mint;", s.accountAddresses[0].String()),
+ false,
+ []types.AccessGrant{markertypes.AccessGrant{Address: s.accountAddresses[0].String(), Permissions: []markertypes.Access{markertypes.Access_Mint}}},
+ },
+ }
+ for _, tc := range testCases {
+ tc := tc
+
+ s.Run(tc.name, func() {
+ if tc.expectPanic {
+ panicFunc := func() { markercli.ParseAccessGrantFromString(tc.accessGrantString) }
+ s.Assert().Panics(panicFunc)
+
+ } else {
+ result := markercli.ParseAccessGrantFromString(tc.accessGrantString)
+ s.Assert().ElementsMatch(result, tc.expectedResult)
+ }
+ })
+ }
+}
diff --git a/x/marker/client/cli/tx.go b/x/marker/client/cli/tx.go
index 1910bff1e2..333ad1e082 100644
--- a/x/marker/client/cli/tx.go
+++ b/x/marker/client/cli/tx.go
@@ -70,6 +70,7 @@ func NewTxCmd() *cobra.Command {
GetCmdRevokeAuthorization(),
GetCmdFeeGrant(),
GetIbcTransferTxCmd(),
+ GetCmdAddFinalizeActivateMarker(),
)
return txCmd
}
@@ -905,6 +906,63 @@ Examples:
return cmd
}
+// GetCmdAddFinalizeActivateMarker implements the add finalize activate marker command
+func GetCmdAddFinalizeActivateMarker() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create-finalize-activate [coin] [access-grant-string]",
+ Aliases: []string{"cfa"},
+ Args: cobra.ExactArgs(2),
+ Short: "Creates, Finalizes and Activates a new marker",
+ Long: strings.TrimSpace(`Creates a new marker, finalizes it and put's it ACTIVATED state managed by the from address
+with the given supply amount and denomination provided in the coin argument
+`),
+ Example: fmt.Sprintf(`$ %s tx marker create-finalize-activate 1000hotdogcoin address1,mint,admin;address2,burn --%s=false --%s=false --from=mykey`, FlagType, FlagSupplyFixed, FlagAllowGovernanceControl),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, err := client.GetClientTxContext(cmd)
+ if err != nil {
+ return err
+ }
+ markerType := ""
+ coin, err := sdk.ParseCoinNormalized(args[0])
+ if err != nil {
+ return fmt.Errorf("invalid coin %s", args[0])
+ }
+ callerAddr := clientCtx.GetFromAddress()
+ markerType, err = cmd.Flags().GetString(FlagType)
+ if err != nil {
+ return fmt.Errorf("invalid marker type: %w", err)
+ }
+ typeValue := types.MarkerType_Coin
+ if len(markerType) > 0 {
+ typeValue = types.MarkerType(types.MarkerType_value["MARKER_TYPE_"+markerType])
+ if typeValue < 1 {
+ return fmt.Errorf("invalid marker type: %s; expected COIN|RESTRICTED", markerType)
+ }
+ }
+ supplyFixed, err := cmd.Flags().GetBool(FlagSupplyFixed)
+ if err != nil {
+ return fmt.Errorf("incorrect value for %s flag. Accepted: true,false Error: %w", FlagSupplyFixed, err)
+ }
+ allowGovernanceControl, err := cmd.Flags().GetBool(FlagAllowGovernanceControl)
+ if err != nil {
+ return fmt.Errorf("incorrect value for %s flag. Accepted: true,false Error: %w", FlagAllowGovernanceControl, err)
+ }
+ accessGrants := ParseAccessGrantFromString(args[1])
+ if len(accessGrants) == 0 {
+ panic("at least one access grant should be present.")
+ }
+ msg := types.NewMsgAddFinalizeActivateMarkerRequest(coin.Denom, coin.Amount, callerAddr, callerAddr, typeValue, supplyFixed, allowGovernanceControl, accessGrants)
+
+ return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
+ },
+ }
+ cmd.Flags().String(FlagType, "COIN", "a marker type to assign (default is COIN)")
+ cmd.Flags().Bool(FlagSupplyFixed, false, "a true or false value to denote if a supply is fixed (default is false)")
+ cmd.Flags().Bool(FlagAllowGovernanceControl, false, "a true or false value to denote if marker is allowed governance control (default is false)")
+ flags.AddTxFlagsToCmd(cmd)
+ return cmd
+}
+
func getPeriodReset(duration int64) time.Time {
return time.Now().Add(getPeriod(duration))
}
@@ -912,3 +970,27 @@ func getPeriodReset(duration int64) time.Time {
func getPeriod(duration int64) time.Duration {
return time.Duration(duration) * time.Second
}
+
+// ParseAccessGrantFromString splits string (example address1,perm1,perm2...;address2, perm1...) to AccessGrant
+func ParseAccessGrantFromString(addressPermissionString string) []types.AccessGrant {
+ parts := strings.Split(addressPermissionString, ";")
+ grants := make([]types.AccessGrant, 0)
+ for _, p := range parts {
+ // ignore if someone put in a ; at the end by mistake
+ if len(p) == 0 {
+ continue
+ }
+ partsPerAddress := strings.Split(p, ",")
+ // if it has an address has to have at least one access associated with it
+ if !(len(partsPerAddress) > 1) {
+ panic("at least one grant should be provided with address")
+ }
+ var permissions types.AccessList
+ address := sdk.MustAccAddressFromBech32(partsPerAddress[0])
+ for _, permission := range partsPerAddress[1:] {
+ permissions = append(permissions, types.AccessByName(permission))
+ }
+ grants = append(grants, *types.NewAccessGrant(address, permissions))
+ }
+ return grants
+}
diff --git a/x/marker/handler.go b/x/marker/handler.go
index e48f803d1b..30cec88458 100644
--- a/x/marker/handler.go
+++ b/x/marker/handler.go
@@ -61,6 +61,9 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
res, err := msgServer.SetDenomMetadata(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
+ case *types.MsgAddFinalizeActivateMarkerRequest:
+ res, err := msgServer.AddFinalizeActivateMarker(sdk.WrapSDKContext(ctx), msg)
+ return sdk.WrapServiceResult(ctx, res, err)
default:
return nil, sdkerrors.ErrUnknownRequest.Wrapf("unrecognized %s message type: %T", types.ModuleName, msg)
}
diff --git a/x/marker/handler_test.go b/x/marker/handler_test.go
index 593d09086f..2a80ad7e95 100644
--- a/x/marker/handler_test.go
+++ b/x/marker/handler_test.go
@@ -597,3 +597,56 @@ func (s *HandlerTestSuite) TestMsgSetDenomMetadataRequest() {
}
s.runTests(cases)
}
+func (s *HandlerTestSuite) TestMsgAddFinalizeActivateMarkerRequest() {
+ denom := "hotdog"
+ denomWithDashPeriod := fmt.Sprintf("%s-my.marker", denom)
+ activeStatus := types.NewMsgAddFinalizeActivateMarkerRequest(denom, sdk.NewInt(100), s.user1Addr, s.user1Addr, types.MarkerType_Coin, true, true, []types.AccessGrant{*types.NewAccessGrant(s.user1Addr, []types.Access{types.Access_Mint, types.Access_Admin})})
+
+ accessGrantWrongStatus := types.NewMsgAddFinalizeActivateMarkerRequest(denom, sdk.NewInt(100), s.user1Addr, s.user1Addr, types.MarkerType_Coin, true, true, nil)
+
+ cases := []CommonTest{
+ {
+ "should successfully ADD,FINALIZE,ACTIVATE new marker",
+ activeStatus,
+ []string{s.user1},
+ "",
+ types.NewEventMarkerAdd(denom, "100", "proposed", s.user1, types.MarkerType_Coin.String()),
+ },
+ {
+ "should fail to ADD,FINALIZE,ACTIVATE new marker, validate basic failure",
+ accessGrantWrongStatus,
+ []string{s.user1},
+ "since this will activate the marker, must have at least one access list defined: invalid request",
+ nil,
+ },
+ {
+ "should fail to ADD,FINALIZE,ACTIVATE new marker, marker already exists",
+ types.NewMsgAddMarkerRequest(denom, sdk.NewInt(100), s.user1Addr, s.user1Addr, types.MarkerType_Coin, true, true),
+ []string{s.user1},
+ fmt.Sprintf("marker address already exists for %s: invalid request", types.MustGetMarkerAddress(denom)),
+ nil,
+ },
+ {
+ "should successfully add marker with dash and period",
+ types.NewMsgAddMarkerRequest(denomWithDashPeriod, sdk.NewInt(1000), s.user1Addr, s.user1Addr, types.MarkerType_Coin, true, true),
+ []string{s.user1},
+ "",
+ types.NewEventMarkerAdd(denomWithDashPeriod, "1000", "proposed", s.user1, types.MarkerType_Coin.String()),
+ },
+ {
+ "should successfully mint denom",
+ types.NewMsgMintRequest(s.user1Addr, sdk.NewInt64Coin(denom, 1000)),
+ []string{s.user1},
+ "",
+ types.NewEventMarkerMint("1000", denom, s.user1),
+ },
+ {
+ "should fail to burn denom, user doesn't have permissions",
+ types.NewMsgBurnRequest(s.user1Addr, sdk.NewInt64Coin(denom, 50)),
+ []string{s.user1},
+ fmt.Sprintf("%s does not have ACCESS_BURN on hotdog markeraccount: invalid request", s.user1),
+ nil,
+ },
+ }
+ s.runTests(cases)
+}
diff --git a/x/marker/keeper/keeper_test.go b/x/marker/keeper/keeper_test.go
index 566104677c..2f98c0ef95 100644
--- a/x/marker/keeper/keeper_test.go
+++ b/x/marker/keeper/keeper_test.go
@@ -677,3 +677,146 @@ func testUserAddress(name string) sdk.AccAddress {
addr := types.MustGetMarkerAddress(name)
return addr
}
+
+func TestAddFinalizeActivateMarker(t *testing.T) {
+ app := simapp.Setup(t)
+ ctx := app.BaseApp.NewContext(false, tmproto.Header{})
+ server := markerkeeper.NewMsgServerImpl(app.MarkerKeeper)
+
+ addr := types.MustGetMarkerAddress("testcoin")
+ pubkey := secp256k1.GenPrivKey().PubKey()
+ user := testUserAddress("testcoin")
+ manager := testUserAddress("manager")
+ existingBalance := sdk.NewCoin("coin", sdk.NewInt(1000))
+
+ // prefund the marker address so an account gets created before the marker does.
+ app.AccountKeeper.SetAccount(ctx, authtypes.NewBaseAccount(user, pubkey, 0, 0))
+ require.NoError(t, testutil.FundAccount(app.BankKeeper, ctx, addr, sdk.NewCoins(existingBalance)), "funding account")
+ require.Equal(t, existingBalance, app.BankKeeper.GetBalance(ctx, addr, "coin"), "account balance must be set")
+
+ // Creating a marker over an account with zero sequence is fine.
+ // One shot marker creation
+ _, err := server.AddFinalizeActivateMarker(sdk.WrapSDKContext(ctx), types.NewMsgAddFinalizeActivateMarkerRequest(
+ "testcoin",
+ sdk.NewInt(30),
+ user,
+ manager,
+ types.MarkerType_Coin,
+ true,
+ true,
+ []types.AccessGrant{*types.NewAccessGrant(manager, []types.Access{types.Access_Mint, types.Access_Admin})},
+ ))
+ require.NoError(t, err, "should allow a marker over existing account that has not signed anything.")
+
+ // existing coin balance must still be present
+ require.Equal(t, existingBalance, app.BankKeeper.GetBalance(ctx, addr, "coin"), "account balances must be preserved")
+
+ m, err := app.MarkerKeeper.GetMarkerByDenom(ctx, "testcoin")
+ require.NoError(t, err)
+ require.EqualValues(t, m.GetSupply(), sdk.NewInt64Coin("testcoin", 30))
+ require.EqualValues(t, m.GetStatus(), types.StatusActive)
+
+ m, err = app.MarkerKeeper.GetMarker(ctx, user)
+ require.NoError(t, err)
+ require.EqualValues(t, m.GetSupply(), sdk.NewInt64Coin("testcoin", 30))
+ require.EqualValues(t, m.GetStatus(), types.StatusActive)
+
+ // Creating a marker over an existing marker fails.
+ _, err = server.AddFinalizeActivateMarker(sdk.WrapSDKContext(ctx), types.NewMsgAddFinalizeActivateMarkerRequest(
+ "testcoin",
+ sdk.NewInt(30),
+ user,
+ manager,
+ types.MarkerType_Coin,
+ true,
+ true,
+ []types.AccessGrant{*types.NewAccessGrant(manager, []types.Access{types.Access_Mint, types.Access_Admin})},
+ ))
+ require.Error(t, err, "fails because marker already exists")
+
+ // Load the created marker
+ m, err = app.MarkerKeeper.GetMarker(ctx, user)
+ require.NoError(t, err)
+ require.EqualValues(t, m.GetSupply(), sdk.NewInt64Coin("testcoin", 30))
+ require.EqualValues(t, m.GetStatus(), types.StatusActive)
+
+ // entire supply should have been allocated to marker acount
+ require.EqualValues(t, app.MarkerKeeper.GetEscrow(ctx, m).AmountOf("testcoin"), sdk.NewInt(30))
+}
+
+// Creating a marker over an existing account with a positive sequence number fails.
+func TestInvalidAccount(t *testing.T) {
+ app := simapp.Setup(t)
+ ctx := app.BaseApp.NewContext(false, tmproto.Header{})
+ pubkey := secp256k1.GenPrivKey().PubKey()
+ server := markerkeeper.NewMsgServerImpl(app.MarkerKeeper)
+ user := testUserAddress("testcoin")
+ manager := testUserAddress("manager")
+ // replace existing test account with a new copy that has a positive sequence number
+ app.AccountKeeper.SetAccount(ctx, authtypes.NewBaseAccount(user, pubkey, 0, 10))
+
+ _, err := server.AddFinalizeActivateMarker(sdk.WrapSDKContext(ctx), types.NewMsgAddFinalizeActivateMarkerRequest(
+ "testcoin",
+ sdk.NewInt(30),
+ user,
+ manager,
+ types.MarkerType_Coin,
+ true,
+ true,
+ []types.AccessGrant{*types.NewAccessGrant(manager, []types.Access{types.Access_Mint, types.Access_Admin})},
+ ))
+ require.Error(t, err, "should not allow creation over and existing account with a positive sequence number.")
+ require.Contains(t, err.Error(), "account at "+user.String()+" is not a marker account: invalid request")
+}
+
+func TestAddFinalizeActivateMarkerUnrestrictedDenoms(t *testing.T) {
+ app := simapp.Setup(t)
+ ctx := app.BaseApp.NewContext(false, tmproto.Header{})
+ server := markerkeeper.NewMsgServerImpl(app.MarkerKeeper)
+
+ user := testUserAddress("test")
+
+ // Require a long unrestricted denom
+ app.MarkerKeeper.SetParams(ctx, types.Params{UnrestrictedDenomRegex: "[a-z]{12,20}"})
+
+ _, err := server.AddFinalizeActivateMarker(sdk.WrapSDKContext(ctx),
+ types.NewMsgAddFinalizeActivateMarkerRequest(
+ "tooshort",
+ sdk.NewInt(30),
+ user,
+ user,
+ types.MarkerType_Coin,
+ true,
+ true,
+ []types.AccessGrant{*types.NewAccessGrant(user, []types.Access{types.Access_Mint, types.Access_Admin})},
+ ))
+ require.Error(t, err, "fails with unrestricted denom length fault")
+ require.Equal(t, fmt.Errorf("invalid denom [tooshort] (fails unrestricted marker denom validation [a-z]{12,20})"), err, "should fail with denom restriction")
+
+ _, err = server.AddFinalizeActivateMarker(sdk.WrapSDKContext(ctx), types.NewMsgAddFinalizeActivateMarkerRequest(
+ "itslongenough",
+ sdk.NewInt(30),
+ user,
+ user,
+ types.MarkerType_Coin,
+ true,
+ true,
+ []types.AccessGrant{*types.NewAccessGrant(user, []types.Access{types.Access_Mint, types.Access_Admin})},
+ ))
+ require.NoError(t, err, "should allow a marker with a sufficiently long denom")
+
+ // Set to an empty string (returns to default expression)
+ app.MarkerKeeper.SetParams(ctx, types.Params{UnrestrictedDenomRegex: ""})
+ _, err = server.AddFinalizeActivateMarker(sdk.WrapSDKContext(ctx), types.NewMsgAddFinalizeActivateMarkerRequest(
+ "short",
+ sdk.NewInt(30),
+ user,
+ user,
+ types.MarkerType_Coin,
+ true,
+ true,
+ []types.AccessGrant{*types.NewAccessGrant(user, []types.Access{types.Access_Mint, types.Access_Admin})},
+ ))
+ // succeeds now as the default unrestricted denom expression allows any valid denom (minimum length is 2)
+ require.NoError(t, err, "should allow any valid denom with a min length of two")
+}
diff --git a/x/marker/keeper/marker.go b/x/marker/keeper/marker.go
index e9d96ae637..0186307ebe 100644
--- a/x/marker/keeper/marker.go
+++ b/x/marker/keeper/marker.go
@@ -482,7 +482,7 @@ func (k Keeper) FinalizeMarker(ctx sdk.Context, caller sdk.Address, denom string
return nil
}
-// ActivateMarker transistions a marker into the active status, enforcing permissions, supply constraints, and minting
+// ActivateMarker transitions a marker into the active status, enforcing permissions, supply constraints, and minting
// any supply as required.
func (k Keeper) ActivateMarker(ctx sdk.Context, caller sdk.Address, denom string) error {
defer telemetry.MeasureSince(time.Now(), types.ModuleName, "activate")
@@ -567,7 +567,8 @@ func (k Keeper) CancelMarker(ctx sdk.Context, caller sdk.AccAddress, denom strin
escrow := k.bankKeeper.GetBalance(ctx, m.GetAddress(), m.GetDenom())
inCirculation := totalSupply.Sub(escrow.Amount)
if inCirculation.GT(sdk.ZeroInt()) {
- return fmt.Errorf("cannot cancel marker with %d minted coin in circulation out of %d total."+
+ // changing to %v
+ return fmt.Errorf("cannot cancel marker with %v minted coin in circulation out of %v total."+
" ensure marker account holds the entire supply of %s", inCirculation, totalSupply, denom)
}
case types.StatusProposed:
@@ -621,7 +622,8 @@ func (k Keeper) DeleteMarker(ctx sdk.Context, caller sdk.AccAddress, denom strin
escrow := k.bankKeeper.GetAllBalances(ctx, m.GetAddress())
inCirculation := totalSupply.Sub(escrow.AmountOf(denom))
if inCirculation.GT(sdk.ZeroInt()) {
- return fmt.Errorf("cannot delete marker with %d minted coin in circulation out of %d total."+
+ // use %v since %d doesn't apply to Int (wraps big.Int)
+ return fmt.Errorf("cannot delete marker with %v minted coin in circulation out of %v total."+
" ensure marker account holds the entire supply of %s", inCirculation, totalSupply, denom)
}
@@ -635,7 +637,7 @@ func (k Keeper) DeleteMarker(ctx sdk.Context, caller sdk.AccAddress, denom strin
return fmt.Errorf("can not destroy marker due to balances in escrow: %s", escrow)
}
- // get the updated state of the marker afer supply burn...
+ // get the updated state of the marker after supply burn...
m, err = k.GetMarkerByDenom(ctx, denom)
if err != nil {
return fmt.Errorf("marker not found for %s: %w", denom, err)
@@ -818,6 +820,26 @@ func (k Keeper) SetMarkerDenomMetadata(ctx sdk.Context, metadata banktypes.Metad
return nil
}
+// AddFinalizeAndActivateMarker adds marker, finalizes, and then activates it
+func (k Keeper) AddFinalizeAndActivateMarker(ctx sdk.Context, marker types.MarkerAccountI) error {
+ err := k.AddMarkerAccount(ctx, marker)
+ if err != nil {
+ return err
+ }
+
+ // Manager is the same as the manager in add marker request.
+ err = k.FinalizeMarker(ctx, marker.GetManager(), marker.GetDenom())
+ if err != nil {
+ return err
+ }
+
+ err = k.ActivateMarker(ctx, marker.GetManager(), marker.GetDenom())
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
// accountControlsAllSupply return true if the caller account address possess 100% of the total supply of a marker.
// This check is used to determine if an account should be allowed to perform defacto admin operations on a marker.
func (k Keeper) accountControlsAllSupply(ctx sdk.Context, caller sdk.AccAddress, m types.MarkerAccountI) bool {
diff --git a/x/marker/keeper/msg_server.go b/x/marker/keeper/msg_server.go
index 5ea2d8c95c..eaa3a80a27 100644
--- a/x/marker/keeper/msg_server.go
+++ b/x/marker/keeper/msg_server.go
@@ -445,9 +445,9 @@ func (k msgServer) Transfer(goCtx context.Context, msg *types.MsgTransferRequest
return &types.MsgTransferResponse{}, nil
}
-// Transfer handles a message to send coins from one account to another (used with restricted coins that are not
+// IbcTransfer handles a message to ibc send coins from one account to another (used with restricted coins that are not
//
-// sent using the normal bank send process)
+// sent using the normal ibc send process)
func (k msgServer) IbcTransfer(goCtx context.Context, msg *types.MsgIbcTransferRequest) (*types.MsgIbcTransferResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
@@ -541,3 +541,60 @@ func (k msgServer) SetDenomMetadata(
return &types.MsgSetDenomMetadataResponse{}, nil
}
+
+// AddFinalizeActivateMarker Handle a message to add a new marker account, finalize it and activate it in one go.
+func (k msgServer) AddFinalizeActivateMarker(goCtx context.Context, msg *types.MsgAddFinalizeActivateMarkerRequest) (*types.MsgAddFinalizeActivateMarkerResponse, error) {
+ ctx := sdk.UnwrapSDKContext(goCtx)
+
+ var err error
+ // Add marker requests must pass extra validation for denom (in addition to regular coin validation expression)
+ if err = k.ValidateUnrestictedDenom(ctx, msg.Amount.Denom); err != nil {
+ return nil, err
+ }
+
+ // since this is a one shot process should have 1 access list member, to have any value for a marker.
+ if len(msg.AccessList) == 0 {
+ return nil, sdkerrors.ErrInvalidRequest.Wrap("since this will activate the marker, must have at least one access list defined")
+ }
+
+ addr := types.MustGetMarkerAddress(msg.Amount.Denom)
+ var manager sdk.AccAddress
+ // if manager not supplied set manager from the --from-address
+ if msg.Manager != "" {
+ manager, err = sdk.AccAddressFromBech32(msg.Manager)
+ } else {
+ manager, err = sdk.AccAddressFromBech32(msg.FromAddress)
+ }
+ if err != nil {
+ return nil, err
+ }
+ account := authtypes.NewBaseAccount(addr, nil, 0, 0)
+ ma := types.NewMarkerAccount(
+ account,
+ sdk.NewCoin(msg.Amount.Denom, msg.Amount.Amount),
+ manager,
+ msg.AccessList,
+ types.StatusProposed,
+ msg.MarkerType)
+ ma.SupplyFixed = msg.SupplyFixed
+
+ if k.GetEnableGovernance(ctx) {
+ ma.AllowGovernanceControl = true
+ } else {
+ ma.AllowGovernanceControl = msg.AllowGovernanceControl
+ }
+
+ if err := k.Keeper.AddFinalizeAndActivateMarker(ctx, ma); err != nil {
+ ctx.Logger().Error("unable to add, finalize and activate marker", "err", err)
+ return nil, sdkerrors.ErrInvalidRequest.Wrap(err.Error())
+ }
+
+ ctx.EventManager().EmitEvent(
+ sdk.NewEvent(
+ sdk.EventTypeMessage,
+ sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
+ ),
+ )
+
+ return &types.MsgAddFinalizeActivateMarkerResponse{}, nil
+}
diff --git a/x/marker/simulation/operations.go b/x/marker/simulation/operations.go
index 4f28d8557f..c9b39d67cb 100644
--- a/x/marker/simulation/operations.go
+++ b/x/marker/simulation/operations.go
@@ -29,6 +29,8 @@ const (
OpWeightMsgChangeStatus = "op_weight_msg_change_status"
//nolint:gosec // not credentials
OpWeightMsgAddAccess = "op_weight_msg_add_access"
+ //nolint:gosec // not credentials
+ OpWeightMsgAddActivateFinalizeMarker = "op_weight_msg_add_finalize_activate_marker"
)
/*
@@ -50,9 +52,10 @@ func WeightedOperations(
appParams simtypes.AppParams, cdc codec.JSONCodec, k keeper.Keeper, ak authkeeper.AccountKeeperI, bk bankkeeper.Keeper,
) simulation.WeightedOperations {
var (
- weightMsgAddMarker int
- weightMsgChangeStatus int
- weightMsgAddAccess int
+ weightMsgAddMarker int
+ weightMsgChangeStatus int
+ weightMsgAddAccess int
+ weightMsgAddFinalizeActivateMarker int
)
appParams.GetOrGenerate(cdc, OpWeightMsgAddMarker, &weightMsgAddMarker, nil,
@@ -73,6 +76,12 @@ func WeightedOperations(
},
)
+ appParams.GetOrGenerate(cdc, OpWeightMsgAddActivateFinalizeMarker, &weightMsgAddFinalizeActivateMarker, nil,
+ func(_ *rand.Rand) {
+ weightMsgAddFinalizeActivateMarker = simappparams.DefaultWeightMsgAddFinalizeActivateMarker
+ },
+ )
+
return simulation.WeightedOperations{
simulation.NewWeightedOperation(
weightMsgAddMarker,
@@ -86,6 +95,10 @@ func WeightedOperations(
weightMsgAddAccess,
SimulateMsgAddAccess(k, ak, bk),
),
+ simulation.NewWeightedOperation(
+ weightMsgAddFinalizeActivateMarker,
+ SimulateMsgAddFinalizeActivateMarker(k, ak, bk),
+ ),
}
}
@@ -176,6 +189,31 @@ func SimulateMsgAddAccess(k keeper.Keeper, ak authkeeper.AccountKeeperI, bk bank
}
}
+// SimulateMsgAddFinalizeActivateMarker will bind a NAME under an existing name using a 40% probability of restricting it.
+func SimulateMsgAddFinalizeActivateMarker(k keeper.Keeper, ak authkeeper.AccountKeeperI, bk bankkeeper.Keeper) simtypes.Operation {
+ return func(
+ r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
+ ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
+ simAccount, _ := simtypes.RandomAcc(r, accs)
+ mgrAccount, _ := simtypes.RandomAcc(r, accs)
+ denom := randomUnrestrictedDenom(r, k.GetUnrestrictedDenomRegex(ctx))
+ // random access grants
+ grants := randomAccessGrants(r, accs, 100)
+ msg := types.NewMsgAddFinalizeActivateMarkerRequest(
+ denom,
+ sdk.NewIntFromUint64(randomUint64(r, k.GetMaxTotalSupply(ctx))),
+ simAccount.Address,
+ mgrAccount.Address,
+ types.MarkerType(r.Intn(2)+1), // coin or restricted_coin
+ r.Intn(2) > 0, // fixed supply
+ r.Intn(2) > 0, // allow gov
+ grants,
+ )
+
+ return Dispatch(r, app, ctx, ak, bk, simAccount, chainID, msg, nil)
+ }
+}
+
// Dispatch sends an operation to the chain using a given account/funds on account for fees. Failures on the server side
// are handled as no-op msg operations with the error string as the status/response.
func Dispatch(
diff --git a/x/marker/simulation/operations_test.go b/x/marker/simulation/operations_test.go
index c0b12a5f79..2c95ef2e28 100644
--- a/x/marker/simulation/operations_test.go
+++ b/x/marker/simulation/operations_test.go
@@ -70,6 +70,7 @@ func (suite *SimTestSuite) TestWeightedOperations() {
{simappparams.DefaultWeightMsgChangeStatus, types.ModuleName, fmt.Sprintf("%T", &types.MsgActivateRequest{})},
// Possible names: types.TypeAddAccessRequest, fmt.Sprintf("%T", &types.MsgAddAccessRequest{})
{simappparams.DefaultWeightMsgAddAccess, types.ModuleName, types.TypeAddAccessRequest},
+ {simappparams.DefaultWeightMsgAddFinalizeActivateMarker, types.ModuleName, types.TypeAddActivateFinalizeMarkerRequest},
}
for i, w := range weightedOps {
@@ -83,15 +84,14 @@ func (suite *SimTestSuite) TestWeightedOperations() {
}
}
-// TestSimulateMsgBindName tests the normal scenario of a valid message of type TypeMsgBindName.
-// Abonormal scenarios, where the message is created by an errors, are not tested here.
+// TestSimulateMsgAddMarker tests the normal scenario of a valid message of type TypeAddMarkerRequest.
+// Abnormal scenarios, where the message is created by an errors, are not tested here.
func (suite *SimTestSuite) TestSimulateMsgAddMarker() {
// setup 3 accounts
s := rand.NewSource(1)
r := rand.New(s)
accounts := suite.getTestingAccounts(r, 3)
- suite.app.NameKeeper.SetNameRecord(suite.ctx, "provenance", accounts[0].Address, false)
// begin a new block
suite.app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: suite.app.LastBlockHeight() + 1, AppHash: suite.app.LastCommitID().Hash}})
@@ -110,6 +110,32 @@ func (suite *SimTestSuite) TestSimulateMsgAddMarker() {
suite.Require().Len(futureOperations, 0)
}
+// TestSimulateMsgAddActivateFinalizeMarker tests the normal scenario of a valid message of type TypeAddActivateFinalizeMarkerRequest.
+// Abnormal scenarios, where the message is created by an errors, are not tested here.
+func (suite *SimTestSuite) TestSimulateMsgAddActivateFinalizeMarker() {
+
+ // setup 3 accounts
+ s := rand.NewSource(1)
+ r := rand.New(s)
+ accounts := suite.getTestingAccounts(r, 3)
+
+ // begin a new block
+ suite.app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: suite.app.LastBlockHeight() + 1, AppHash: suite.app.LastCommitID().Hash}})
+
+ // execute operation
+ op := simulation.SimulateMsgAddFinalizeActivateMarker(suite.app.MarkerKeeper, suite.app.AccountKeeper, suite.app.BankKeeper)
+ operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "")
+ suite.Require().NoError(err)
+
+ var msg types.MsgAddFinalizeActivateMarkerRequest
+ types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg)
+
+ suite.Require().True(operationMsg.OK, operationMsg.String())
+ suite.Require().Equal(types.TypeAddActivateFinalizeMarkerRequest, msg.Type())
+ suite.Require().Equal(types.ModuleName, msg.Route())
+ suite.Require().Len(futureOperations, 0)
+}
+
func (suite *SimTestSuite) getTestingAccounts(r *rand.Rand, n int) []simtypes.Account {
accounts := simtypes.RandomAccounts(r, n)
diff --git a/x/marker/spec/03_messages.md b/x/marker/spec/03_messages.md
index 2263b4b312..d1c717812b 100644
--- a/x/marker/spec/03_messages.md
+++ b/x/marker/spec/03_messages.md
@@ -278,3 +278,18 @@ This service message is expected to fail if:
- Any DenomUnit entries are removed.
- DenomUnit Denom fields are modified.
- Any aliases are removed from a DenomUnit.
+
+## Msg/AddFinalizeActivateMarkerRequest
+
+AddFinalizeActivate requested is used for adding, finalizing, and activating a marker in a single request.
+
+This service message is expected to fail if:
+
+- The given denom value is invalid or does not match an existing marker on the system
+- The marker is pending:
+ - And the request is not signed with an administrator address that matches the manager address or:
+ - The given administrator address does not currently have the "admin" access granted on the marker
+- The accesslist:
+ - Contains more than one entry for a given address
+ - Contains a grant with an invalid address
+ - Contains a grant with an invalid access enum value (Unspecified/0)
\ No newline at end of file
diff --git a/x/marker/types/accessgrant.pb.go b/x/marker/types/accessgrant.pb.go
index 9e0781b78c..b604294dac 100644
--- a/x/marker/types/accessgrant.pb.go
+++ b/x/marker/types/accessgrant.pb.go
@@ -79,7 +79,7 @@ func (Access) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_7242c30a84644575, []int{0}
}
-// AccessGrant associates a colelction of permisssions with an address for delegated marker account control.
+// AccessGrant associates a collection of permissions with an address for delegated marker account control.
type AccessGrant struct {
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
Permissions AccessList `protobuf:"varint,2,rep,packed,name=permissions,proto3,enum=provenance.marker.v1.Access,castrepeated=AccessList" json:"permissions,omitempty"`
diff --git a/x/marker/types/msg.go b/x/marker/types/msg.go
index 88604502fd..a43dd4ef41 100644
--- a/x/marker/types/msg.go
+++ b/x/marker/types/msg.go
@@ -18,20 +18,21 @@ import (
)
const (
- TypeAddMarkerRequest = "addmarker"
- TypeAddAccessRequest = "addaccess"
- TypeDeleteAccessRequest = "deleteaccess"
- TypeFinalizeRequest = "finalize"
- TypeActivateRequest = "activate"
- TypeCancelRequest = "cancel"
- TypeDeleteRequest = "delete"
- TypeMintRequest = "mint"
- TypeBurnRequest = "burn"
- TypeWithdrawRequest = "withdraw"
- TypeTransferRequest = "transfer"
- TypeIbcTransferRequest = "ibctransfer"
- TypeSetMetadataRequest = "setmetadata"
- TypeGrantAllowance = "grantallowance"
+ TypeAddMarkerRequest = "addmarker"
+ TypeAddAccessRequest = "addaccess"
+ TypeDeleteAccessRequest = "deleteaccess"
+ TypeFinalizeRequest = "finalize"
+ TypeActivateRequest = "activate"
+ TypeCancelRequest = "cancel"
+ TypeDeleteRequest = "delete"
+ TypeMintRequest = "mint"
+ TypeBurnRequest = "burn"
+ TypeWithdrawRequest = "withdraw"
+ TypeTransferRequest = "transfer"
+ TypeIbcTransferRequest = "ibctransfer"
+ TypeSetMetadataRequest = "setmetadata"
+ TypeGrantAllowance = "grantallowance"
+ TypeAddActivateFinalizeMarkerRequest = "addactivatefinalizemarker"
)
// Compile time interface check.
@@ -49,6 +50,7 @@ var (
_ sdk.Msg = &MsgTransferRequest{}
_ sdk.Msg = &MsgIbcTransferRequest{}
_ sdk.Msg = &MsgGrantAllowanceRequest{}
+ _ sdk.Msg = &MsgAddFinalizeActivateMarkerRequest{}
)
// Type returns the message action.
@@ -93,6 +95,12 @@ func (msg MsgSetDenomMetadataRequest) Type() string { return TypeSetMetadataRequ
// Type returns the message action.
func (msg MsgGrantAllowanceRequest) Type() string { return TypeGrantAllowance }
+// Type returns the message action.
+// These legacyMsg support should probably be removed but adding new message to this for consistency for now.
+func (msg MsgAddFinalizeActivateMarkerRequest) Type() string {
+ return TypeAddActivateFinalizeMarkerRequest
+}
+
// NewMsgAddMarkerRequest creates a new marker in a proposed state with a given total supply a denomination
func NewMsgAddMarkerRequest(
denom string, totalSupply sdkmath.Int, fromAddress sdk.AccAddress, manager sdk.AccAddress, markerType MarkerType, supplyFixed bool, allowGovernanceControl bool, //nolint:interfacer
@@ -642,3 +650,53 @@ func (msg MsgGrantAllowanceRequest) GetSignBytes() []byte {
func (msg MsgGrantAllowanceRequest) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{sdk.MustAccAddressFromBech32(msg.Administrator)}
}
+
+func NewMsgAddFinalizeActivateMarkerRequest(denom string, totalSupply sdkmath.Int, fromAddress sdk.AccAddress, manager sdk.AccAddress, markerType MarkerType, supplyFixed bool, allowGovernanceControl bool, accessGrants []AccessGrant) *MsgAddFinalizeActivateMarkerRequest {
+ return &MsgAddFinalizeActivateMarkerRequest{
+ Amount: sdk.NewCoin(denom, totalSupply),
+ Manager: manager.String(),
+ FromAddress: fromAddress.String(),
+ MarkerType: markerType,
+ SupplyFixed: supplyFixed,
+ AllowGovernanceControl: allowGovernanceControl,
+ AccessList: accessGrants,
+ }
+}
+
+// Route returns the name of the module.
+func (msg MsgAddFinalizeActivateMarkerRequest) Route() string { return ModuleName }
+
+// ValidateBasic runs stateless validation checks on the message.
+func (msg MsgAddFinalizeActivateMarkerRequest) ValidateBasic() error {
+ markerCoin := sdk.Coin{
+ Denom: msg.Amount.Denom,
+ Amount: msg.Amount.Amount,
+ }
+ // IsValid validates denom and amount is not negative.
+ if !markerCoin.IsValid() {
+ return fmt.Errorf("invalid marker denom/total supply: %w", sdkerrors.ErrInvalidCoins)
+ }
+
+ _, err := sdk.AccAddressFromBech32(msg.Manager)
+ if err != nil {
+ return err
+ }
+
+ // since this is a one shot process should have 1 access list member, to have any value for a marker
+ if msg.AccessList == nil || len(msg.AccessList) == 0 {
+ return fmt.Errorf("since this will activate the marker, must have access list defined")
+ }
+ return nil
+}
+
+// GetSignBytes encodes the message for signing.
+func (msg MsgAddFinalizeActivateMarkerRequest) GetSignBytes() []byte {
+ bz := ModuleCdc.MustMarshalJSON(&msg)
+ return sdk.MustSortJSON(bz)
+}
+
+// GetSigners indicates that the message must have been signed by the address provided.
+func (msg MsgAddFinalizeActivateMarkerRequest) GetSigners() []sdk.AccAddress {
+ addr := sdk.MustAccAddressFromBech32(msg.FromAddress)
+ return []sdk.AccAddress{addr}
+}
diff --git a/x/marker/types/msg_test.go b/x/marker/types/msg_test.go
index 19ff1a8f7d..d9ead06717 100644
--- a/x/marker/types/msg_test.go
+++ b/x/marker/types/msg_test.go
@@ -4,6 +4,8 @@ import (
"testing"
"time"
+ "cosmossdk.io/math"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/codec"
@@ -92,7 +94,7 @@ func TestMsgGrantAllowance(t *testing.T) {
}
}
-func TestMsgAssessCustomMsgFeeValidateBasic(t *testing.T) {
+func TestMsgIbcTransferRequestValidateBasic(t *testing.T) {
validAddress := "cosmos1sh49f6ze3vn7cdl2amh2gnc70z5mten3y08xck"
cases := []struct {
@@ -158,3 +160,85 @@ func TestMsgAssessCustomMsgFeeValidateBasic(t *testing.T) {
})
}
}
+
+func TestMsgAddFinalizeActivateMarkerRequestValidateBasic(t *testing.T) {
+ validAddress := sdk.MustAccAddressFromBech32("cosmos1sh49f6ze3vn7cdl2amh2gnc70z5mten3y08xck")
+
+ cases := []struct {
+ name string
+ msg MsgAddFinalizeActivateMarkerRequest
+ errorMsg string
+ }{
+ {
+ "should fail on invalid marker",
+ MsgAddFinalizeActivateMarkerRequest{
+ Amount: sdk.Coin{
+ Amount: math.NewInt(100),
+ Denom: "",
+ },
+ Manager: "cosmos1sh49f6ze3vn7cdl2amh2gnc70z5mten3y08xck",
+ FromAddress: "cosmos1sh49f6ze3vn7cdl2amh2gnc70z5mten3y08xck",
+ MarkerType: MarkerType_Coin,
+ SupplyFixed: true,
+ AllowGovernanceControl: true,
+ AccessList: []AccessGrant{*NewAccessGrant(validAddress, []Access{Access_Mint, Access_Admin})},
+ },
+ "invalid marker denom/total supply: invalid coins",
+ },
+ {
+ "should fail on invalid manager address",
+ MsgAddFinalizeActivateMarkerRequest{
+ Amount: sdk.NewInt64Coin("hotdog", 100),
+ Manager: "",
+ FromAddress: "",
+ MarkerType: MarkerType_Coin,
+ SupplyFixed: true,
+ AllowGovernanceControl: true,
+ AccessList: []AccessGrant{*NewAccessGrant(validAddress, []Access{Access_Mint, Access_Admin})},
+ },
+ "empty address string is not allowed",
+ },
+ {
+ "should fail on empty access list",
+ *NewMsgAddFinalizeActivateMarkerRequest(
+ "hotdog",
+ sdk.NewInt(100),
+ validAddress,
+ validAddress,
+ MarkerType_Coin,
+ true,
+ true,
+ []AccessGrant{},
+ ),
+ "since this will activate the marker, must have access list defined",
+ },
+ {
+ "should succeed",
+ *NewMsgAddFinalizeActivateMarkerRequest(
+ "hotdog",
+ sdk.NewInt(100),
+ validAddress,
+ validAddress,
+ MarkerType_Coin,
+ true,
+ true,
+ []AccessGrant{*NewAccessGrant(validAddress, []Access{Access_Mint, Access_Admin})},
+ ),
+ "",
+ },
+ }
+
+ for _, tc := range cases {
+ tc := tc
+
+ t.Run(tc.name, func(t *testing.T) {
+ err := tc.msg.ValidateBasic()
+ if len(tc.errorMsg) > 0 {
+ assert.Error(t, err)
+ assert.Equal(t, tc.errorMsg, err.Error())
+ } else {
+ assert.NoError(t, err)
+ }
+ })
+ }
+}
diff --git a/x/marker/types/tx.pb.go b/x/marker/types/tx.pb.go
index 248065971b..9a11db25ba 100644
--- a/x/marker/types/tx.pb.go
+++ b/x/marker/types/tx.pb.go
@@ -1369,6 +1369,129 @@ func (m *MsgSetDenomMetadataResponse) XXX_DiscardUnknown() {
var xxx_messageInfo_MsgSetDenomMetadataResponse proto.InternalMessageInfo
+// MsgAddFinalizeActivateMarkerRequest defines the Msg/AddFinalizeActivateMarker request type
+type MsgAddFinalizeActivateMarkerRequest struct {
+ Amount github_com_cosmos_cosmos_sdk_types.Coin `protobuf:"bytes,1,opt,name=amount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Coin" json:"amount"`
+ Manager string `protobuf:"bytes,3,opt,name=manager,proto3" json:"manager,omitempty"`
+ FromAddress string `protobuf:"bytes,4,opt,name=from_address,json=fromAddress,proto3" json:"from_address,omitempty"`
+ MarkerType MarkerType `protobuf:"varint,5,opt,name=marker_type,json=markerType,proto3,enum=provenance.marker.v1.MarkerType" json:"marker_type,omitempty"`
+ AccessList []AccessGrant `protobuf:"bytes,6,rep,name=access_list,json=accessList,proto3" json:"access_list"`
+ SupplyFixed bool `protobuf:"varint,7,opt,name=supply_fixed,json=supplyFixed,proto3" json:"supply_fixed,omitempty"`
+ AllowGovernanceControl bool `protobuf:"varint,8,opt,name=allow_governance_control,json=allowGovernanceControl,proto3" json:"allow_governance_control,omitempty"`
+}
+
+func (m *MsgAddFinalizeActivateMarkerRequest) Reset() { *m = MsgAddFinalizeActivateMarkerRequest{} }
+func (m *MsgAddFinalizeActivateMarkerRequest) String() string { return proto.CompactTextString(m) }
+func (*MsgAddFinalizeActivateMarkerRequest) ProtoMessage() {}
+func (*MsgAddFinalizeActivateMarkerRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_bcb203fb73175ed3, []int{28}
+}
+func (m *MsgAddFinalizeActivateMarkerRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgAddFinalizeActivateMarkerRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgAddFinalizeActivateMarkerRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgAddFinalizeActivateMarkerRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgAddFinalizeActivateMarkerRequest.Merge(m, src)
+}
+func (m *MsgAddFinalizeActivateMarkerRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgAddFinalizeActivateMarkerRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgAddFinalizeActivateMarkerRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgAddFinalizeActivateMarkerRequest proto.InternalMessageInfo
+
+func (m *MsgAddFinalizeActivateMarkerRequest) GetManager() string {
+ if m != nil {
+ return m.Manager
+ }
+ return ""
+}
+
+func (m *MsgAddFinalizeActivateMarkerRequest) GetFromAddress() string {
+ if m != nil {
+ return m.FromAddress
+ }
+ return ""
+}
+
+func (m *MsgAddFinalizeActivateMarkerRequest) GetMarkerType() MarkerType {
+ if m != nil {
+ return m.MarkerType
+ }
+ return MarkerType_Unknown
+}
+
+func (m *MsgAddFinalizeActivateMarkerRequest) GetAccessList() []AccessGrant {
+ if m != nil {
+ return m.AccessList
+ }
+ return nil
+}
+
+func (m *MsgAddFinalizeActivateMarkerRequest) GetSupplyFixed() bool {
+ if m != nil {
+ return m.SupplyFixed
+ }
+ return false
+}
+
+func (m *MsgAddFinalizeActivateMarkerRequest) GetAllowGovernanceControl() bool {
+ if m != nil {
+ return m.AllowGovernanceControl
+ }
+ return false
+}
+
+// MsgAddFinalizeActivateMarkerResponse defines the Msg/AddFinalizeActivateMarker response type
+type MsgAddFinalizeActivateMarkerResponse struct {
+}
+
+func (m *MsgAddFinalizeActivateMarkerResponse) Reset() { *m = MsgAddFinalizeActivateMarkerResponse{} }
+func (m *MsgAddFinalizeActivateMarkerResponse) String() string { return proto.CompactTextString(m) }
+func (*MsgAddFinalizeActivateMarkerResponse) ProtoMessage() {}
+func (*MsgAddFinalizeActivateMarkerResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_bcb203fb73175ed3, []int{29}
+}
+func (m *MsgAddFinalizeActivateMarkerResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgAddFinalizeActivateMarkerResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgAddFinalizeActivateMarkerResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgAddFinalizeActivateMarkerResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgAddFinalizeActivateMarkerResponse.Merge(m, src)
+}
+func (m *MsgAddFinalizeActivateMarkerResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgAddFinalizeActivateMarkerResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgAddFinalizeActivateMarkerResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgAddFinalizeActivateMarkerResponse proto.InternalMessageInfo
+
func init() {
proto.RegisterType((*MsgGrantAllowanceRequest)(nil), "provenance.marker.v1.MsgGrantAllowanceRequest")
proto.RegisterType((*MsgGrantAllowanceResponse)(nil), "provenance.marker.v1.MsgGrantAllowanceResponse")
@@ -1398,91 +1521,97 @@ func init() {
proto.RegisterType((*MsgIbcTransferResponse)(nil), "provenance.marker.v1.MsgIbcTransferResponse")
proto.RegisterType((*MsgSetDenomMetadataRequest)(nil), "provenance.marker.v1.MsgSetDenomMetadataRequest")
proto.RegisterType((*MsgSetDenomMetadataResponse)(nil), "provenance.marker.v1.MsgSetDenomMetadataResponse")
+ proto.RegisterType((*MsgAddFinalizeActivateMarkerRequest)(nil), "provenance.marker.v1.MsgAddFinalizeActivateMarkerRequest")
+ proto.RegisterType((*MsgAddFinalizeActivateMarkerResponse)(nil), "provenance.marker.v1.MsgAddFinalizeActivateMarkerResponse")
}
func init() { proto.RegisterFile("provenance/marker/v1/tx.proto", fileDescriptor_bcb203fb73175ed3) }
var fileDescriptor_bcb203fb73175ed3 = []byte{
- // 1252 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xdd, 0x6e, 0x1b, 0xc5,
- 0x17, 0xcf, 0xfe, 0x9d, 0xba, 0xf1, 0xb8, 0x4d, 0x9b, 0x69, 0x9a, 0x6e, 0x5c, 0xc5, 0x71, 0xac,
- 0xb6, 0x71, 0xff, 0x34, 0xbb, 0x8d, 0x11, 0x12, 0xea, 0x0d, 0xb2, 0x53, 0x52, 0x2a, 0x58, 0x54,
- 0x39, 0x95, 0x10, 0xdc, 0x58, 0xe3, 0xdd, 0xc9, 0x66, 0x15, 0xef, 0x8e, 0xbb, 0x33, 0x76, 0x12,
- 0x24, 0xde, 0x01, 0xf5, 0x92, 0x47, 0xe0, 0x1a, 0x09, 0xf1, 0x06, 0x15, 0x57, 0x15, 0xe2, 0x02,
- 0x21, 0x54, 0xaa, 0xe4, 0x15, 0x78, 0x00, 0xb4, 0x33, 0xb3, 0x9f, 0xb1, 0x37, 0xae, 0x64, 0x01,
- 0x57, 0xf6, 0xcc, 0xf9, 0xfc, 0x9d, 0x73, 0xf6, 0x9c, 0xb3, 0x0b, 0xd6, 0x06, 0x3e, 0x19, 0x61,
- 0x0f, 0x79, 0x26, 0xd6, 0x5d, 0xe4, 0x1f, 0x62, 0x5f, 0x1f, 0x6d, 0xeb, 0xec, 0x58, 0x1b, 0xf8,
- 0x84, 0x11, 0xb8, 0x1c, 0x93, 0x35, 0x41, 0xd6, 0x46, 0xdb, 0x95, 0x55, 0x9b, 0x10, 0xbb, 0x8f,
- 0x75, 0xce, 0xd3, 0x1b, 0xee, 0xeb, 0xc8, 0x3b, 0x11, 0x02, 0x95, 0x55, 0x93, 0x50, 0x97, 0xd0,
- 0x2e, 0x3f, 0xe9, 0xe2, 0x20, 0x49, 0xcb, 0x36, 0xb1, 0x89, 0xb8, 0x0f, 0xfe, 0xc9, 0xdb, 0xaa,
- 0xe0, 0xd1, 0x7b, 0x88, 0x62, 0x7d, 0xb4, 0xdd, 0xc3, 0x0c, 0x6d, 0xeb, 0x26, 0x71, 0xbc, 0x73,
- 0x74, 0xef, 0x30, 0xa2, 0x07, 0x07, 0x49, 0xbf, 0xeb, 0xf4, 0x4c, 0x1d, 0x0d, 0x06, 0x7d, 0xc7,
- 0x44, 0xcc, 0x21, 0x1e, 0xd5, 0x99, 0x8f, 0x3c, 0xba, 0x9f, 0x06, 0x52, 0xd9, 0x18, 0x8b, 0x53,
- 0x42, 0x12, 0x2c, 0xf7, 0xc6, 0xb2, 0x20, 0xd3, 0xc4, 0x94, 0xda, 0x3e, 0xf2, 0x98, 0xe0, 0xab,
- 0xff, 0xa8, 0x00, 0xd5, 0xa0, 0xf6, 0x93, 0xe0, 0xaa, 0xd5, 0xef, 0x93, 0xa3, 0x40, 0xa2, 0x83,
- 0x5f, 0x0c, 0x31, 0x65, 0x70, 0x19, 0x5c, 0xb2, 0xb0, 0x47, 0x5c, 0x55, 0xa9, 0x29, 0x8d, 0x52,
- 0x47, 0x1c, 0xe0, 0x1d, 0x70, 0x15, 0x59, 0xae, 0xe3, 0x39, 0x94, 0xf9, 0x88, 0x11, 0x5f, 0xfd,
- 0x1f, 0xa7, 0xa6, 0x2f, 0xa1, 0x0a, 0x2e, 0x73, 0x3b, 0x18, 0xab, 0x05, 0x4e, 0x0f, 0x8f, 0xf0,
- 0x63, 0x50, 0x42, 0xa1, 0x25, 0x75, 0xbe, 0xa6, 0x34, 0xca, 0xcd, 0x65, 0x4d, 0x24, 0x41, 0x0b,
- 0x93, 0xa0, 0xb5, 0xbc, 0x93, 0xf6, 0xd2, 0xcf, 0x3f, 0x6c, 0x5d, 0xdd, 0xc5, 0x38, 0xf2, 0xeb,
- 0x69, 0x27, 0x96, 0xac, 0xdf, 0x06, 0xab, 0x63, 0x1c, 0xa7, 0x03, 0xe2, 0x51, 0x5c, 0xff, 0xa3,
- 0x00, 0x6e, 0x18, 0xd4, 0x6e, 0x59, 0x96, 0xc1, 0xc1, 0x87, 0x88, 0x7a, 0xa0, 0x88, 0x5c, 0x32,
- 0xf4, 0x18, 0x87, 0x54, 0x6e, 0xae, 0x6a, 0x32, 0xab, 0x41, 0xc6, 0x34, 0x99, 0x11, 0x6d, 0x87,
- 0x38, 0x5e, 0x5b, 0x7f, 0xf5, 0x66, 0x7d, 0xee, 0xf7, 0x37, 0xeb, 0x9b, 0xb6, 0xc3, 0x0e, 0x86,
- 0x3d, 0xcd, 0x24, 0xae, 0x2c, 0x01, 0xf9, 0xb3, 0x45, 0xad, 0x43, 0x9d, 0x9d, 0x0c, 0x30, 0xe5,
- 0x02, 0x1d, 0xa9, 0x39, 0x40, 0xee, 0x22, 0x0f, 0xd9, 0xd8, 0x0f, 0x91, 0xcb, 0x23, 0xdc, 0x00,
- 0x57, 0xf6, 0x7d, 0xe2, 0x76, 0x91, 0x65, 0xf9, 0x98, 0x52, 0x0e, 0xbe, 0xd4, 0x29, 0x07, 0x77,
- 0x2d, 0x71, 0x05, 0x1f, 0x81, 0x22, 0x65, 0x88, 0x0d, 0xa9, 0x7a, 0xa9, 0xa6, 0x34, 0x16, 0x9b,
- 0x75, 0x6d, 0x5c, 0xd1, 0x6a, 0x02, 0xd5, 0x1e, 0xe7, 0xec, 0x48, 0x09, 0xd8, 0x02, 0x65, 0xc1,
- 0xd1, 0x0d, 0xbc, 0x52, 0x8b, 0x5c, 0x41, 0x2d, 0x4f, 0xc1, 0xf3, 0x93, 0x01, 0xee, 0x00, 0x37,
- 0xfa, 0x0f, 0x3f, 0x01, 0x65, 0x51, 0x23, 0xdd, 0xbe, 0x43, 0x99, 0x7a, 0xb9, 0x56, 0x68, 0x94,
- 0x9b, 0x1b, 0xe3, 0x55, 0xb4, 0x38, 0x23, 0x4f, 0x40, 0x7b, 0x3e, 0x08, 0x56, 0x07, 0x08, 0xd9,
- 0xcf, 0x1c, 0xca, 0x02, 0xac, 0x74, 0x38, 0x18, 0xf4, 0x4f, 0xba, 0xfb, 0xce, 0x31, 0xb6, 0xd4,
- 0x85, 0x9a, 0xd2, 0x58, 0xe8, 0x94, 0xc5, 0xdd, 0x6e, 0x70, 0x05, 0x3f, 0x04, 0x2a, 0x4f, 0x67,
- 0xd7, 0x26, 0x23, 0xec, 0x73, 0xf5, 0x5d, 0x93, 0x78, 0xcc, 0x27, 0x7d, 0xb5, 0xc4, 0xd9, 0x57,
- 0x38, 0xfd, 0x49, 0x44, 0xde, 0x11, 0xd4, 0xfa, 0x0a, 0x58, 0x4e, 0x67, 0x57, 0xa6, 0xfd, 0xa5,
- 0x12, 0xa6, 0x5d, 0x38, 0x37, 0x8b, 0x42, 0xfe, 0x08, 0x14, 0x05, 0x2c, 0xb5, 0xf0, 0x6e, 0xd1,
- 0x90, 0x62, 0xb1, 0xb3, 0xa1, 0x4f, 0xd2, 0xd9, 0x6f, 0xc0, 0x8a, 0x41, 0xed, 0xc7, 0xb8, 0x8f,
- 0x19, 0x9e, 0x9d, 0xbb, 0x9b, 0xe0, 0x9a, 0x8f, 0x5d, 0x32, 0xc2, 0x56, 0x54, 0x66, 0xa2, 0x0a,
- 0x17, 0xe5, 0xb5, 0xac, 0xb4, 0xfa, 0x2a, 0xb8, 0x75, 0xce, 0xbc, 0xf4, 0xec, 0x19, 0x80, 0x06,
- 0xb5, 0x77, 0x1d, 0x0f, 0xf5, 0x9d, 0xaf, 0x67, 0xd1, 0x0d, 0xea, 0x37, 0x79, 0x5e, 0x62, 0x8d,
- 0x29, 0x43, 0x2d, 0x93, 0x39, 0x23, 0xc4, 0x66, 0x68, 0x28, 0xd6, 0x28, 0x0d, 0x7d, 0x0e, 0xae,
- 0x1b, 0xd4, 0xde, 0x09, 0x72, 0xd6, 0x9f, 0x85, 0x99, 0x1b, 0x60, 0x29, 0xa1, 0x2f, 0x65, 0x44,
- 0x44, 0x74, 0x76, 0x46, 0x42, 0x7d, 0xd2, 0xc8, 0x77, 0x0a, 0x58, 0x34, 0xa8, 0x6d, 0x38, 0x1e,
- 0xfb, 0x27, 0x9b, 0xda, 0x74, 0x1e, 0x2f, 0x81, 0x6b, 0x91, 0x6f, 0x69, 0x7f, 0xdb, 0x43, 0xdf,
- 0xfb, 0xaf, 0xfa, 0x2b, 0x7c, 0x93, 0xfe, 0xfe, 0xaa, 0xf0, 0x9a, 0xfc, 0xc2, 0x61, 0x07, 0x96,
- 0x8f, 0x8e, 0x66, 0xf1, 0x48, 0xae, 0x01, 0xc0, 0x48, 0xe6, 0x69, 0x2c, 0x31, 0x12, 0xb6, 0x7c,
- 0x33, 0x0a, 0xc7, 0x3c, 0x6f, 0x30, 0x39, 0xe1, 0x78, 0x18, 0x84, 0xe3, 0xfb, 0x3f, 0xd7, 0x1b,
- 0x53, 0x86, 0x83, 0x86, 0xf1, 0x90, 0xcf, 0x45, 0x8c, 0x4a, 0xa2, 0x7d, 0x2b, 0xd0, 0x3e, 0x97,
- 0x5b, 0xc6, 0xbf, 0x9a, 0xa1, 0xc2, 0xb8, 0xd8, 0x4d, 0x31, 0x32, 0xd3, 0xe1, 0xbd, 0x94, 0x09,
- 0xaf, 0x44, 0x1e, 0x23, 0x94, 0xc8, 0x7f, 0x51, 0xc0, 0x4d, 0x83, 0xda, 0x4f, 0x7b, 0x66, 0x16,
- 0xfc, 0x4b, 0x05, 0x2c, 0x84, 0x6b, 0x97, 0xc4, 0x7f, 0x5f, 0x73, 0x7a, 0xa6, 0x96, 0x5c, 0xcc,
- 0xb4, 0x90, 0x83, 0x0f, 0xd3, 0x58, 0x7f, 0xfb, 0x53, 0x19, 0x8f, 0x9d, 0xf3, 0xf1, 0x70, 0x7a,
- 0xe6, 0x96, 0x4d, 0xf4, 0xd1, 0x07, 0xba, 0x4b, 0xac, 0x61, 0x1f, 0xd3, 0x60, 0xd5, 0x4b, 0xac,
- 0x78, 0x22, 0x48, 0x49, 0x67, 0x23, 0x3f, 0xa6, 0xac, 0x67, 0x95, 0x8f, 0x94, 0x14, 0x26, 0x09,
- 0xf7, 0x27, 0x05, 0x54, 0x0c, 0x6a, 0xef, 0x61, 0xf6, 0x38, 0xa8, 0x5c, 0x03, 0x33, 0x64, 0x21,
- 0x86, 0x42, 0xcc, 0x43, 0xb0, 0xe0, 0xca, 0x2b, 0x09, 0x79, 0x2d, 0x4e, 0xb9, 0x77, 0x18, 0xa5,
- 0x3c, 0x94, 0x6b, 0x3f, 0x92, 0x30, 0x9b, 0xb9, 0x69, 0x3f, 0x16, 0x9b, 0xae, 0x04, 0x16, 0xda,
- 0x8c, 0x4c, 0x4d, 0x89, 0x6a, 0x0d, 0xdc, 0x1e, 0xeb, 0xba, 0x80, 0xd6, 0xfc, 0x0b, 0x80, 0x82,
- 0x41, 0x6d, 0xd8, 0x05, 0x0b, 0xe1, 0x80, 0x81, 0x8d, 0x09, 0x5b, 0xcf, 0xb9, 0xa9, 0x56, 0xb9,
- 0x3f, 0x05, 0xa7, 0x30, 0x14, 0x18, 0x08, 0x07, 0x4b, 0x8e, 0x81, 0xcc, 0x34, 0xcb, 0x31, 0x90,
- 0x9d, 0x52, 0xf0, 0x4b, 0x50, 0x14, 0x23, 0x05, 0xde, 0x9b, 0x28, 0x94, 0x9a, 0x61, 0x95, 0xcd,
- 0x0b, 0xf9, 0x62, 0xd5, 0x62, 0x90, 0xe4, 0xa8, 0x4e, 0x4d, 0xae, 0x1c, 0xd5, 0xe9, 0x89, 0x04,
- 0xf7, 0xc0, 0x7c, 0xd0, 0xf1, 0xe1, 0x9d, 0x89, 0x02, 0x89, 0x61, 0x55, 0xb9, 0x7b, 0x01, 0x57,
- 0xac, 0x34, 0x68, 0xcb, 0x39, 0x4a, 0x13, 0x13, 0x25, 0x47, 0x69, 0xb2, 0xb7, 0xc3, 0x1e, 0x28,
- 0x45, 0x6b, 0x18, 0xcc, 0xc9, 0x4b, 0x66, 0x7d, 0xac, 0xfc, 0x7f, 0x1a, 0x56, 0x69, 0xe3, 0x10,
- 0x5c, 0x49, 0xee, 0x54, 0xf0, 0xc1, 0x05, 0x61, 0x4c, 0x5b, 0xda, 0x9a, 0x92, 0x3b, 0xae, 0xc8,
- 0xb0, 0xa5, 0xe7, 0x54, 0x64, 0x66, 0x96, 0xe5, 0x54, 0x64, 0x76, 0x3e, 0xc8, 0x88, 0x89, 0x2d,
- 0x3b, 0x3f, 0x62, 0xa9, 0xf7, 0xac, 0xfc, 0x88, 0xa5, 0x97, 0xf6, 0x00, 0x44, 0xd8, 0xae, 0x72,
- 0x40, 0x64, 0xba, 0x74, 0x0e, 0x88, 0x6c, 0xef, 0x83, 0x07, 0xa0, 0x9c, 0x68, 0x89, 0xf0, 0xbd,
- 0x89, 0x92, 0xe7, 0x87, 0x41, 0xe5, 0xc1, 0x74, 0xcc, 0xd2, 0xd2, 0x11, 0xb8, 0x9e, 0x6d, 0x53,
- 0xf0, 0xe1, 0x44, 0x0d, 0x13, 0x9a, 0x71, 0x65, 0xfb, 0x1d, 0x24, 0xa4, 0xe1, 0x17, 0x60, 0x31,
- 0xfd, 0x26, 0x0c, 0xb5, 0x89, 0x4a, 0xc6, 0xbe, 0xeb, 0x57, 0xf4, 0xa9, 0xf9, 0x85, 0xc9, 0xb6,
- 0xfd, 0xea, 0xb4, 0xaa, 0xbc, 0x3e, 0xad, 0x2a, 0x6f, 0x4f, 0xab, 0xca, 0xb7, 0x67, 0xd5, 0xb9,
- 0xd7, 0x67, 0xd5, 0xb9, 0xdf, 0xce, 0xaa, 0x73, 0xe0, 0x96, 0x43, 0xc6, 0x2a, 0x7b, 0xa6, 0x7c,
- 0x95, 0x1c, 0x17, 0x31, 0xcb, 0x96, 0x43, 0x12, 0x27, 0xfd, 0x38, 0xfc, 0x62, 0xc1, 0xe7, 0x46,
- 0xaf, 0xc8, 0x3f, 0x0a, 0xbc, 0xff, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x85, 0xd4, 0xbc, 0x93,
- 0xde, 0x11, 0x00, 0x00,
+ // 1315 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x58, 0x4d, 0x6f, 0x1b, 0xc5,
+ 0x1b, 0xcf, 0xfe, 0x9d, 0xb8, 0xf6, 0xb8, 0x4d, 0xdb, 0x69, 0xda, 0xae, 0xb7, 0x8a, 0xeb, 0xfa,
+ 0xdf, 0x17, 0x17, 0x9a, 0xdd, 0xc6, 0x08, 0x09, 0x7a, 0x41, 0x76, 0x4a, 0x4b, 0x05, 0x8b, 0x2a,
+ 0xa7, 0x12, 0x82, 0x8b, 0x35, 0xde, 0x9d, 0x6c, 0x56, 0xf1, 0xee, 0xb8, 0x3b, 0x63, 0x27, 0x41,
+ 0xe2, 0x03, 0x70, 0x43, 0x39, 0xf2, 0x11, 0x38, 0x71, 0x40, 0x42, 0x7c, 0x83, 0x8a, 0x53, 0x85,
+ 0x38, 0x20, 0x84, 0x4a, 0x95, 0x7c, 0x11, 0xb4, 0x33, 0xb3, 0x5e, 0xef, 0xc6, 0xde, 0x38, 0x60,
+ 0xf1, 0x72, 0x8a, 0x67, 0xe6, 0x79, 0xfb, 0x3d, 0xcf, 0x33, 0xf3, 0xfc, 0xb2, 0x60, 0xb5, 0x1f,
+ 0x90, 0x21, 0xf6, 0x91, 0x6f, 0x61, 0xc3, 0x43, 0xc1, 0x0e, 0x0e, 0x8c, 0xe1, 0xba, 0xc1, 0xf6,
+ 0xf4, 0x7e, 0x40, 0x18, 0x81, 0x2b, 0xf1, 0xb1, 0x2e, 0x8e, 0xf5, 0xe1, 0xba, 0x56, 0x76, 0x08,
+ 0x71, 0x7a, 0xd8, 0xe0, 0x32, 0xdd, 0xc1, 0x96, 0x81, 0xfc, 0x7d, 0xa1, 0xa0, 0x95, 0x2d, 0x42,
+ 0x3d, 0x42, 0x3b, 0x7c, 0x65, 0x88, 0x85, 0x3c, 0x5a, 0x71, 0x88, 0x43, 0xc4, 0x7e, 0xf8, 0x4b,
+ 0xee, 0x56, 0x84, 0x8c, 0xd1, 0x45, 0x14, 0x1b, 0xc3, 0xf5, 0x2e, 0x66, 0x68, 0xdd, 0xb0, 0x88,
+ 0xeb, 0x1f, 0x3b, 0xf7, 0x77, 0x46, 0xe7, 0xe1, 0x42, 0x9e, 0xdf, 0x72, 0xbb, 0x96, 0x81, 0xfa,
+ 0xfd, 0x9e, 0x6b, 0x21, 0xe6, 0x12, 0x9f, 0x1a, 0x2c, 0x40, 0x3e, 0xdd, 0x4a, 0x02, 0xd1, 0x6e,
+ 0x4c, 0xc4, 0x29, 0x21, 0x09, 0x91, 0xdb, 0x13, 0x45, 0x90, 0x65, 0x61, 0x4a, 0x9d, 0x00, 0xf9,
+ 0x4c, 0xc8, 0xd5, 0xbe, 0x57, 0x80, 0x6a, 0x52, 0xe7, 0x71, 0xb8, 0xd5, 0xec, 0xf5, 0xc8, 0x6e,
+ 0xa8, 0xd1, 0xc6, 0xcf, 0x07, 0x98, 0x32, 0xb8, 0x02, 0x96, 0x6c, 0xec, 0x13, 0x4f, 0x55, 0xaa,
+ 0x4a, 0xbd, 0xd8, 0x16, 0x0b, 0x78, 0x13, 0x9c, 0x43, 0xb6, 0xe7, 0xfa, 0x2e, 0x65, 0x01, 0x62,
+ 0x24, 0x50, 0xff, 0xc7, 0x4f, 0x93, 0x9b, 0x50, 0x05, 0x67, 0xb8, 0x1f, 0x8c, 0xd5, 0x1c, 0x3f,
+ 0x8f, 0x96, 0xf0, 0x7d, 0x50, 0x44, 0x91, 0x27, 0x75, 0xb1, 0xaa, 0xd4, 0x4b, 0x8d, 0x15, 0x5d,
+ 0x14, 0x41, 0x8f, 0x8a, 0xa0, 0x37, 0xfd, 0xfd, 0xd6, 0xc5, 0x1f, 0xbf, 0x5b, 0x3b, 0xf7, 0x08,
+ 0xe3, 0x51, 0x5c, 0x4f, 0xda, 0xb1, 0x66, 0xed, 0x1a, 0x28, 0x4f, 0x08, 0x9c, 0xf6, 0x89, 0x4f,
+ 0x71, 0xed, 0xb7, 0x1c, 0xb8, 0x64, 0x52, 0xa7, 0x69, 0xdb, 0x26, 0x07, 0x1f, 0x21, 0xea, 0x82,
+ 0x3c, 0xf2, 0xc8, 0xc0, 0x67, 0x1c, 0x52, 0xa9, 0x51, 0xd6, 0x65, 0x55, 0xc3, 0x8a, 0xe9, 0xb2,
+ 0x22, 0xfa, 0x06, 0x71, 0xfd, 0x96, 0xf1, 0xe2, 0xd5, 0xf5, 0x85, 0x5f, 0x5f, 0x5d, 0xbf, 0xe3,
+ 0xb8, 0x6c, 0x7b, 0xd0, 0xd5, 0x2d, 0xe2, 0xc9, 0x16, 0x90, 0x7f, 0xd6, 0xa8, 0xbd, 0x63, 0xb0,
+ 0xfd, 0x3e, 0xa6, 0x5c, 0xa1, 0x2d, 0x2d, 0x87, 0xc8, 0x3d, 0xe4, 0x23, 0x07, 0x07, 0x11, 0x72,
+ 0xb9, 0x84, 0x37, 0xc0, 0xd9, 0xad, 0x80, 0x78, 0x1d, 0x64, 0xdb, 0x01, 0xa6, 0x94, 0x83, 0x2f,
+ 0xb6, 0x4b, 0xe1, 0x5e, 0x53, 0x6c, 0xc1, 0x07, 0x20, 0x4f, 0x19, 0x62, 0x03, 0xaa, 0x2e, 0x55,
+ 0x95, 0xfa, 0x72, 0xa3, 0xa6, 0x4f, 0x6a, 0x5a, 0x5d, 0xa0, 0xda, 0xe4, 0x92, 0x6d, 0xa9, 0x01,
+ 0x9b, 0xa0, 0x24, 0x24, 0x3a, 0x61, 0x54, 0x6a, 0x9e, 0x1b, 0xa8, 0x66, 0x19, 0x78, 0xb6, 0xdf,
+ 0xc7, 0x6d, 0xe0, 0x8d, 0x7e, 0xc3, 0x0f, 0x40, 0x49, 0xf4, 0x48, 0xa7, 0xe7, 0x52, 0xa6, 0x9e,
+ 0xa9, 0xe6, 0xea, 0xa5, 0xc6, 0x8d, 0xc9, 0x26, 0x9a, 0x5c, 0x90, 0x17, 0xa0, 0xb5, 0x18, 0x26,
+ 0xab, 0x0d, 0x84, 0xee, 0x47, 0x2e, 0x65, 0x21, 0x56, 0x3a, 0xe8, 0xf7, 0x7b, 0xfb, 0x9d, 0x2d,
+ 0x77, 0x0f, 0xdb, 0x6a, 0xa1, 0xaa, 0xd4, 0x0b, 0xed, 0x92, 0xd8, 0x7b, 0x14, 0x6e, 0xc1, 0x77,
+ 0x80, 0xca, 0xcb, 0xd9, 0x71, 0xc8, 0x10, 0x07, 0xdc, 0x7c, 0xc7, 0x22, 0x3e, 0x0b, 0x48, 0x4f,
+ 0x2d, 0x72, 0xf1, 0x2b, 0xfc, 0xfc, 0xf1, 0xe8, 0x78, 0x43, 0x9c, 0xd6, 0xae, 0x80, 0x95, 0x64,
+ 0x75, 0x65, 0xd9, 0x0f, 0x94, 0xa8, 0xec, 0x22, 0xb8, 0x79, 0x34, 0xf2, 0x7b, 0x20, 0x2f, 0x60,
+ 0xa9, 0xb9, 0xd3, 0x65, 0x43, 0xaa, 0xc5, 0xc1, 0x46, 0x31, 0xc9, 0x60, 0xbf, 0x00, 0x57, 0x4c,
+ 0xea, 0x3c, 0xc4, 0x3d, 0xcc, 0xf0, 0xfc, 0xc2, 0xbd, 0x03, 0xce, 0x07, 0xd8, 0x23, 0x43, 0x6c,
+ 0x8f, 0xda, 0x4c, 0x74, 0xe1, 0xb2, 0xdc, 0x96, 0x9d, 0x56, 0x2b, 0x83, 0xab, 0xc7, 0xdc, 0xcb,
+ 0xc8, 0x9e, 0x02, 0x68, 0x52, 0xe7, 0x91, 0xeb, 0xa3, 0x9e, 0xfb, 0xf9, 0x3c, 0x5e, 0x83, 0xda,
+ 0x65, 0x5e, 0x97, 0xd8, 0x62, 0xc2, 0x51, 0xd3, 0x62, 0xee, 0x10, 0xb1, 0x39, 0x3a, 0x8a, 0x2d,
+ 0x4a, 0x47, 0x1f, 0x83, 0x0b, 0x26, 0x75, 0x36, 0xc2, 0x9a, 0xf5, 0xe6, 0xe1, 0xe6, 0x12, 0xb8,
+ 0x38, 0x66, 0x2f, 0xe1, 0x44, 0x64, 0x74, 0x7e, 0x4e, 0x22, 0x7b, 0xd2, 0xc9, 0xd7, 0x0a, 0x58,
+ 0x36, 0xa9, 0x63, 0xba, 0x3e, 0xfb, 0x3b, 0x1f, 0xb5, 0xd9, 0x22, 0xbe, 0x08, 0xce, 0x8f, 0x62,
+ 0x4b, 0xc6, 0xdb, 0x1a, 0x04, 0xfe, 0xbf, 0x35, 0x5e, 0x11, 0x9b, 0x8c, 0xf7, 0x67, 0x85, 0xf7,
+ 0xe4, 0x27, 0x2e, 0xdb, 0xb6, 0x03, 0xb4, 0x3b, 0x8f, 0x2b, 0xb9, 0x0a, 0x00, 0x23, 0xa9, 0xdb,
+ 0x58, 0x64, 0x24, 0x7a, 0xf2, 0xad, 0x51, 0x3a, 0x16, 0xf9, 0x03, 0x93, 0x91, 0x8e, 0xfb, 0x61,
+ 0x3a, 0xbe, 0xf9, 0xfd, 0x7a, 0x7d, 0xc6, 0x74, 0xd0, 0x28, 0x1f, 0xf2, 0x5e, 0xc4, 0xa8, 0x24,
+ 0xda, 0xd7, 0x02, 0xed, 0x33, 0xc9, 0x32, 0xfe, 0xd1, 0x0a, 0xe5, 0x26, 0xe5, 0x6e, 0x86, 0x91,
+ 0x99, 0x4c, 0xef, 0x52, 0x2a, 0xbd, 0x12, 0x79, 0x8c, 0x50, 0x22, 0xff, 0x49, 0x01, 0x97, 0x4d,
+ 0xea, 0x3c, 0xe9, 0x5a, 0x69, 0xf0, 0x07, 0x0a, 0x28, 0x44, 0xb4, 0x4b, 0xe2, 0xbf, 0xab, 0xbb,
+ 0x5d, 0x4b, 0x1f, 0x27, 0x66, 0x7a, 0x24, 0xc1, 0x87, 0x69, 0x6c, 0xbf, 0xf5, 0xa1, 0xcc, 0xc7,
+ 0xc6, 0xf1, 0x7c, 0xb8, 0x5d, 0x6b, 0xcd, 0x21, 0xc6, 0xf0, 0x6d, 0xc3, 0x23, 0xf6, 0xa0, 0x87,
+ 0x69, 0x48, 0xf5, 0xc6, 0x28, 0x9e, 0x48, 0xd2, 0x78, 0xb0, 0xa3, 0x38, 0x66, 0xec, 0x67, 0x95,
+ 0x8f, 0x94, 0x04, 0x26, 0x09, 0xf7, 0x07, 0x05, 0x68, 0x26, 0x75, 0x36, 0x31, 0x7b, 0x18, 0x76,
+ 0xae, 0x89, 0x19, 0xb2, 0x11, 0x43, 0x11, 0xe6, 0x01, 0x28, 0x78, 0x72, 0x4b, 0x42, 0x5e, 0x8d,
+ 0x4b, 0xee, 0xef, 0x8c, 0x4a, 0x1e, 0xe9, 0xb5, 0x1e, 0x48, 0x98, 0x8d, 0xcc, 0xb2, 0xef, 0x09,
+ 0xa6, 0x2b, 0x81, 0x45, 0x3e, 0x47, 0xae, 0x66, 0x44, 0xb5, 0x0a, 0xae, 0x4d, 0x0c, 0x5d, 0x42,
+ 0xfb, 0x36, 0x07, 0xfe, 0x2f, 0x06, 0x6c, 0x34, 0x5f, 0xa2, 0xe7, 0xff, 0x3f, 0xc6, 0xfd, 0x52,
+ 0xfc, 0x6d, 0xe9, 0xaf, 0xf3, 0xb7, 0xfc, 0xfc, 0xf8, 0xdb, 0x99, 0xd3, 0xf1, 0xb7, 0x42, 0x26,
+ 0x7f, 0xbb, 0x0d, 0x6e, 0x66, 0x57, 0x4c, 0x94, 0xb6, 0xf1, 0xe5, 0x59, 0x90, 0x33, 0xa9, 0x03,
+ 0x3b, 0xa0, 0x10, 0x49, 0xc2, 0xfa, 0x94, 0x84, 0x1c, 0x23, 0x2c, 0xda, 0xdd, 0x19, 0x24, 0x85,
+ 0xa3, 0xd0, 0x41, 0x14, 0x42, 0x86, 0x83, 0x14, 0x51, 0xc9, 0x70, 0x90, 0x26, 0x20, 0xf0, 0x53,
+ 0x90, 0x17, 0x6c, 0x01, 0xde, 0x9e, 0xaa, 0x94, 0xa0, 0x27, 0xda, 0x9d, 0x13, 0xe5, 0x62, 0xd3,
+ 0x82, 0x23, 0x64, 0x98, 0x4e, 0x90, 0x92, 0x0c, 0xd3, 0x49, 0xb2, 0x01, 0x37, 0xc1, 0x62, 0x38,
+ 0xcc, 0xe1, 0xcd, 0xa9, 0x0a, 0x63, 0x3c, 0x44, 0xbb, 0x75, 0x82, 0x54, 0x6c, 0x34, 0x9c, 0xb8,
+ 0x19, 0x46, 0xc7, 0xc8, 0x42, 0x86, 0xd1, 0xf1, 0xb1, 0x0d, 0xbb, 0xa0, 0x38, 0x62, 0xd8, 0x30,
+ 0xa3, 0x2e, 0xa9, 0xff, 0x0c, 0xb4, 0x37, 0x66, 0x11, 0x95, 0x3e, 0x76, 0xc0, 0xd9, 0x71, 0xba,
+ 0x0c, 0xef, 0x9d, 0x90, 0xc6, 0xa4, 0xa7, 0xb5, 0x19, 0xa5, 0xe3, 0x8e, 0x8c, 0xa6, 0x75, 0x46,
+ 0x47, 0xa6, 0x68, 0x4a, 0x46, 0x47, 0xa6, 0x47, 0xbf, 0xcc, 0x98, 0xb8, 0x70, 0xd9, 0x19, 0x4b,
+ 0x3c, 0xa3, 0xd9, 0x19, 0x4b, 0xde, 0xdf, 0x10, 0x44, 0x34, 0x89, 0x32, 0x40, 0xa4, 0x06, 0x70,
+ 0x06, 0x88, 0xf4, 0x58, 0x83, 0xdb, 0xa0, 0x34, 0x36, 0xed, 0xe0, 0x9b, 0x53, 0x35, 0x8f, 0xcf,
+ 0x79, 0xed, 0xde, 0x6c, 0xc2, 0xd2, 0xd3, 0x2e, 0xb8, 0x90, 0x9e, 0x40, 0xf0, 0xfe, 0x54, 0x0b,
+ 0x53, 0xe6, 0xac, 0xb6, 0x7e, 0x0a, 0x0d, 0xe9, 0xf8, 0x39, 0x58, 0x4e, 0x7e, 0xe4, 0x80, 0xfa,
+ 0x54, 0x23, 0x13, 0x3f, 0xe3, 0x68, 0xc6, 0xcc, 0xf2, 0xd2, 0xe5, 0x81, 0x02, 0xca, 0x53, 0x1f,
+ 0x67, 0xf8, 0x6e, 0x56, 0x03, 0x64, 0x8e, 0x60, 0xed, 0xc1, 0x9f, 0x51, 0x15, 0x41, 0xb5, 0x9c,
+ 0x17, 0x87, 0x15, 0xe5, 0xe5, 0x61, 0x45, 0x79, 0x7d, 0x58, 0x51, 0xbe, 0x3a, 0xaa, 0x2c, 0xbc,
+ 0x3c, 0xaa, 0x2c, 0xfc, 0x72, 0x54, 0x59, 0x00, 0x57, 0x5d, 0x32, 0xd1, 0xee, 0x53, 0xe5, 0xb3,
+ 0x71, 0x7a, 0x12, 0x8b, 0xac, 0xb9, 0x64, 0x6c, 0x65, 0xec, 0x45, 0x5f, 0xc8, 0xf8, 0x40, 0xef,
+ 0xe6, 0xf9, 0x47, 0xa8, 0xb7, 0xfe, 0x08, 0x00, 0x00, 0xff, 0xff, 0xcb, 0x26, 0x97, 0xbf, 0x4e,
+ 0x14, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -1527,6 +1656,8 @@ type MsgClient interface {
// GrantAllowance grants fee allowance to the grantee on the granter's
// account with the provided expiration time.
GrantAllowance(ctx context.Context, in *MsgGrantAllowanceRequest, opts ...grpc.CallOption) (*MsgGrantAllowanceResponse, error)
+ // AddFinalizeActivateMarker
+ AddFinalizeActivateMarker(ctx context.Context, in *MsgAddFinalizeActivateMarkerRequest, opts ...grpc.CallOption) (*MsgAddFinalizeActivateMarkerResponse, error)
}
type msgClient struct {
@@ -1663,6 +1794,15 @@ func (c *msgClient) GrantAllowance(ctx context.Context, in *MsgGrantAllowanceReq
return out, nil
}
+func (c *msgClient) AddFinalizeActivateMarker(ctx context.Context, in *MsgAddFinalizeActivateMarkerRequest, opts ...grpc.CallOption) (*MsgAddFinalizeActivateMarkerResponse, error) {
+ out := new(MsgAddFinalizeActivateMarkerResponse)
+ err := c.cc.Invoke(ctx, "/provenance.marker.v1.Msg/AddFinalizeActivateMarker", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
// MsgServer is the server API for Msg service.
type MsgServer interface {
// Finalize
@@ -1695,6 +1835,8 @@ type MsgServer interface {
// GrantAllowance grants fee allowance to the grantee on the granter's
// account with the provided expiration time.
GrantAllowance(context.Context, *MsgGrantAllowanceRequest) (*MsgGrantAllowanceResponse, error)
+ // AddFinalizeActivateMarker
+ AddFinalizeActivateMarker(context.Context, *MsgAddFinalizeActivateMarkerRequest) (*MsgAddFinalizeActivateMarkerResponse, error)
}
// UnimplementedMsgServer can be embedded to have forward compatible implementations.
@@ -1743,6 +1885,9 @@ func (*UnimplementedMsgServer) SetDenomMetadata(ctx context.Context, req *MsgSet
func (*UnimplementedMsgServer) GrantAllowance(ctx context.Context, req *MsgGrantAllowanceRequest) (*MsgGrantAllowanceResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GrantAllowance not implemented")
}
+func (*UnimplementedMsgServer) AddFinalizeActivateMarker(ctx context.Context, req *MsgAddFinalizeActivateMarkerRequest) (*MsgAddFinalizeActivateMarkerResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method AddFinalizeActivateMarker not implemented")
+}
func RegisterMsgServer(s grpc1.Server, srv MsgServer) {
s.RegisterService(&_Msg_serviceDesc, srv)
@@ -2000,6 +2145,24 @@ func _Msg_GrantAllowance_Handler(srv interface{}, ctx context.Context, dec func(
return interceptor(ctx, in, info, handler)
}
+func _Msg_AddFinalizeActivateMarker_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(MsgAddFinalizeActivateMarkerRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(MsgServer).AddFinalizeActivateMarker(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/provenance.marker.v1.Msg/AddFinalizeActivateMarker",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(MsgServer).AddFinalizeActivateMarker(ctx, req.(*MsgAddFinalizeActivateMarkerRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
var _Msg_serviceDesc = grpc.ServiceDesc{
ServiceName: "provenance.marker.v1.Msg",
HandlerType: (*MsgServer)(nil),
@@ -2060,6 +2223,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{
MethodName: "GrantAllowance",
Handler: _Msg_GrantAllowance_Handler,
},
+ {
+ MethodName: "AddFinalizeActivateMarker",
+ Handler: _Msg_AddFinalizeActivateMarker_Handler,
+ },
},
Streams: []grpc.StreamDesc{},
Metadata: "provenance/marker/v1/tx.proto",
@@ -3049,6 +3216,115 @@ func (m *MsgSetDenomMetadataResponse) MarshalToSizedBuffer(dAtA []byte) (int, er
return len(dAtA) - i, nil
}
+func (m *MsgAddFinalizeActivateMarkerRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgAddFinalizeActivateMarkerRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgAddFinalizeActivateMarkerRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.AllowGovernanceControl {
+ i--
+ if m.AllowGovernanceControl {
+ dAtA[i] = 1
+ } else {
+ dAtA[i] = 0
+ }
+ i--
+ dAtA[i] = 0x40
+ }
+ if m.SupplyFixed {
+ i--
+ if m.SupplyFixed {
+ dAtA[i] = 1
+ } else {
+ dAtA[i] = 0
+ }
+ i--
+ dAtA[i] = 0x38
+ }
+ if len(m.AccessList) > 0 {
+ for iNdEx := len(m.AccessList) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.AccessList[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintTx(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x32
+ }
+ }
+ if m.MarkerType != 0 {
+ i = encodeVarintTx(dAtA, i, uint64(m.MarkerType))
+ i--
+ dAtA[i] = 0x28
+ }
+ if len(m.FromAddress) > 0 {
+ i -= len(m.FromAddress)
+ copy(dAtA[i:], m.FromAddress)
+ i = encodeVarintTx(dAtA, i, uint64(len(m.FromAddress)))
+ i--
+ dAtA[i] = 0x22
+ }
+ if len(m.Manager) > 0 {
+ i -= len(m.Manager)
+ copy(dAtA[i:], m.Manager)
+ i = encodeVarintTx(dAtA, i, uint64(len(m.Manager)))
+ i--
+ dAtA[i] = 0x1a
+ }
+ {
+ size := m.Amount.Size()
+ i -= size
+ if _, err := m.Amount.MarshalTo(dAtA[i:]); err != nil {
+ return 0, err
+ }
+ i = encodeVarintTx(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ return len(dAtA) - i, nil
+}
+
+func (m *MsgAddFinalizeActivateMarkerResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgAddFinalizeActivateMarkerResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgAddFinalizeActivateMarkerResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ return len(dAtA) - i, nil
+}
+
func encodeVarintTx(dAtA []byte, offset int, v uint64) int {
offset -= sovTx(v)
base := offset
@@ -3470,6 +3746,49 @@ func (m *MsgSetDenomMetadataResponse) Size() (n int) {
return n
}
+func (m *MsgAddFinalizeActivateMarkerRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = m.Amount.Size()
+ n += 1 + l + sovTx(uint64(l))
+ l = len(m.Manager)
+ if l > 0 {
+ n += 1 + l + sovTx(uint64(l))
+ }
+ l = len(m.FromAddress)
+ if l > 0 {
+ n += 1 + l + sovTx(uint64(l))
+ }
+ if m.MarkerType != 0 {
+ n += 1 + sovTx(uint64(m.MarkerType))
+ }
+ if len(m.AccessList) > 0 {
+ for _, e := range m.AccessList {
+ l = e.Size()
+ n += 1 + l + sovTx(uint64(l))
+ }
+ }
+ if m.SupplyFixed {
+ n += 2
+ }
+ if m.AllowGovernanceControl {
+ n += 2
+ }
+ return n
+}
+
+func (m *MsgAddFinalizeActivateMarkerResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ return n
+}
+
func sovTx(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
@@ -6186,6 +6505,296 @@ func (m *MsgSetDenomMetadataResponse) Unmarshal(dAtA []byte) error {
}
return nil
}
+func (m *MsgAddFinalizeActivateMarkerRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTx
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgAddFinalizeActivateMarkerRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgAddFinalizeActivateMarkerRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTx
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthTx
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthTx
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.Amount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Manager", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTx
+ }
+ 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 ErrInvalidLengthTx
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthTx
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Manager = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field FromAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTx
+ }
+ 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 ErrInvalidLengthTx
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthTx
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.FromAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 5:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field MarkerType", wireType)
+ }
+ m.MarkerType = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTx
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.MarkerType |= MarkerType(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 6:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field AccessList", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTx
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthTx
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthTx
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.AccessList = append(m.AccessList, AccessGrant{})
+ if err := m.AccessList[len(m.AccessList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 7:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SupplyFixed", wireType)
+ }
+ var v int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTx
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ v |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ m.SupplyFixed = bool(v != 0)
+ case 8:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field AllowGovernanceControl", wireType)
+ }
+ var v int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTx
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ v |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ m.AllowGovernanceControl = bool(v != 0)
+ default:
+ iNdEx = preIndex
+ skippy, err := skipTx(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthTx
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MsgAddFinalizeActivateMarkerResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTx
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgAddFinalizeActivateMarkerResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgAddFinalizeActivateMarkerResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ default:
+ iNdEx = preIndex
+ skippy, err := skipTx(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthTx
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
func skipTx(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0