feat: attribute typing (#40)

* marshal and unmarshal

* attributes proto

* fix

* process attributes and create secondary mappings

* get records from attributes

* fix

* fix lint errors

* fix gosec

* lower case

* go mod tidy

* Fix tests

* "add search test"

* req attributes

* grpc tests

* fix tests

* register interface

* fix tests

* Remove git diff from test workflows

* fix workflow file

* fix simulations

* fix names and add checks for attributes in tests

* Add comment for attribute prefix
This commit is contained in:
Murali Krishna Komatireddy
2022-11-15 11:51:14 +05:30
committed by GitHub
parent 72ec75a857
commit 6b04c0ee5e
35 changed files with 2187 additions and 601 deletions
+4 -4
View File
@@ -162,7 +162,7 @@ func (s *IntegrationTestSuite) TestGRPCGetBondByID() {
// extract bond id from bonds list
bond := queryResponse.GetBonds()[0]
return bond.GetID()
return bond.GetId()
},
},
}
@@ -181,11 +181,11 @@ func (s *IntegrationTestSuite) TestGRPCGetBondByID() {
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &bonds)
if tc.expErr {
sr.Empty(bonds.GetBond().GetID())
sr.Empty(bonds.GetBond().GetId())
} else {
sr.NoError(err)
sr.NotZero(bonds.GetBond().GetID())
sr.Equal(bonds.GetBond().GetID(), bondID)
sr.NotZero(bonds.GetBond().GetId())
sr.Equal(bonds.GetBond().GetId(), bondID)
}
})
}
+3 -3
View File
@@ -205,7 +205,7 @@ func (s *IntegrationTestSuite) TestGetQueryBondByID() {
// extract bond id from bonds list
bond := queryResponse.GetBonds()[0]
return bond.GetID()
return bond.GetId()
},
},
}
@@ -225,9 +225,9 @@ func (s *IntegrationTestSuite) TestGetQueryBondByID() {
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
sr.NoError(err)
if tc.err {
sr.Zero(len(queryResponse.GetBond().GetID()))
sr.Zero(len(queryResponse.GetBond().GetId()))
} else {
sr.NotZero(len(queryResponse.GetBond().GetID()))
sr.NotZero(len(queryResponse.GetBond().GetId()))
sr.Equal(s.accountAddress, queryResponse.GetBond().GetOwner())
}
})
+4 -4
View File
@@ -118,7 +118,7 @@ func (s *IntegrationTestSuite) TestTxRefillBond() {
// extract bond id from bonds list
bond := queryResponse.GetBonds()[0]
tc.args = append([]string{bond.GetID()}, tc.args...)
tc.args = append([]string{bond.GetId()}, tc.args...)
}
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
if tc.err {
@@ -204,7 +204,7 @@ func (s *IntegrationTestSuite) TestTxWithdrawAmountFromBond() {
// extract bond id from bonds list
bond := queryResponse.GetBonds()[0]
tc.args = append([]string{bond.GetID()}, tc.args...)
tc.args = append([]string{bond.GetId()}, tc.args...)
}
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
if tc.err {
@@ -288,7 +288,7 @@ func (s *IntegrationTestSuite) TestTxCancelBond() {
// extract bond id from bonds list
bond := queryResponse.GetBonds()[0]
tc.args = append([]string{bond.GetID()}, tc.args...)
tc.args = append([]string{bond.GetId()}, tc.args...)
}
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
if tc.err {
@@ -312,7 +312,7 @@ func (s *IntegrationTestSuite) TestTxCancelBond() {
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
sr.NoError(err)
sr.Zero(queryResponse.GetBond().GetID())
sr.Zero(queryResponse.GetBond().GetId())
}
})
}
+2 -2
View File
@@ -28,11 +28,11 @@ func (q Querier) Params(c context.Context, _ *types.QueryParamsRequest) (*types.
func (q Querier) GetBondByID(c context.Context, req *types.QueryGetBondByIDRequest) (*types.QueryGetBondByIDResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
bondID := req.GetID()
bondID := req.GetId()
if len(bondID) == 0 {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "bond id required")
}
bond := q.Keeper.GetBond(ctx, req.GetID())
bond := q.Keeper.GetBond(ctx, req.GetId())
return &types.QueryGetBondByIDResponse{Bond: &bond}, nil
}
+1 -1
View File
@@ -124,7 +124,7 @@ func (suite *KeeperTestSuite) TestGrpcQueryBondBondId() {
if !test.errResponse {
suiteRequire.Nil(err)
suiteRequire.NotNil(resp.GetBond())
suiteRequire.Equal(test.req.Id, resp.GetBond().GetID())
suiteRequire.Equal(test.req.Id, resp.GetBond().GetId())
} else {
suiteRequire.NotNil(err)
suiteRequire.Error(err)
+1 -1
View File
@@ -114,7 +114,7 @@ func (m *Bond) XXX_DiscardUnknown() {
var xxx_messageInfo_Bond proto.InternalMessageInfo
func (m *Bond) GetID() string {
func (m *Bond) GetId() string {
if m != nil {
return m.Id
}
+1 -1
View File
@@ -252,7 +252,7 @@ func (m *QueryGetBondByIDRequest) XXX_DiscardUnknown() {
var xxx_messageInfo_QueryGetBondByIDRequest proto.InternalMessageInfo
func (m *QueryGetBondByIDRequest) GetID() string {
func (m *QueryGetBondByIDRequest) GetId() string {
if m != nil {
return m.Id
}
+1 -1
View File
@@ -58,7 +58,7 @@ $ ./build/laconicd q nameservice params -o json | jq .
> First you have to Create bond
```bash
$ ./build/laconicd tx nameservice set ~/Desktop/examples/records/example1.yml 95f68b1b862bfd1609b0c9aaf7300287b92fec90ac64027092c3e723af36e83d --from root --chain-id ethermint_9000-1 --yes -o json
$ ./build/laconicd tx nameservice set ~/Desktop/examples/records/service_provider_example.yml 95f68b1b862bfd1609b0c9aaf7300287b92fec90ac64027092c3e723af36e83d --from root --chain-id ethermint_9000-1 --yes -o json
{
"height": "0",
"txhash": "BA44ABE1194724694E7CB290F9F3121DB4E63E1A030D95CB84813EEA132CF95F",
+3 -3
View File
@@ -14,14 +14,14 @@ import (
// GetQueryCmd returns the cli query commands for this module
func GetQueryCmd() *cobra.Command {
bondQueryCmd := &cobra.Command{
nameserviceQueryCmd := &cobra.Command{
Use: types.ModuleName,
Short: "Querying commands for the nameservice module",
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}
bondQueryCmd.AddCommand(
nameserviceQueryCmd.AddCommand(
GetCmdWhoIs(),
GetCmdResolve(),
GetCmdLookupCRN(),
@@ -34,7 +34,7 @@ func GetQueryCmd() *cobra.Command {
GetCmdBalance(),
GetCmdNames(),
)
return bondQueryCmd
return nameserviceQueryCmd
}
// GetCmdWhoIs queries a whois info for a name.
+10 -5
View File
@@ -17,7 +17,7 @@ import (
// NewTxCmd returns a root CLI command handler for all x/bond transaction commands.
func NewTxCmd() *cobra.Command {
bondTxCmd := &cobra.Command{
nameserviceTxCmd := &cobra.Command{
Use: types.ModuleName,
Short: "nameservice transaction subcommands",
DisableFlagParsing: true,
@@ -25,7 +25,7 @@ func NewTxCmd() *cobra.Command {
RunE: client.ValidateCmd,
}
bondTxCmd.AddCommand(
nameserviceTxCmd.AddCommand(
GetCmdSetRecord(),
GetCmdRenewRecord(),
GetCmdAssociateBond(),
@@ -38,7 +38,7 @@ func NewTxCmd() *cobra.Command {
GetCmdDeleteName(),
)
return bondTxCmd
return nameserviceTxCmd
}
// GetCmdSetRecord is the CLI command for creating/updating a record.
@@ -61,12 +61,17 @@ $ %s tx %s set [payload file path] [bond-id]
return err
}
payload, err := GetPayloadFromFile(args[0])
payloadType, err := GetPayloadFromFile(args[0])
if err != nil {
return err
}
msg := types.NewMsgSetRecord(payload.ToPayload(), args[1], clientCtx.GetFromAddress())
payload, err := payloadType.ToPayload()
if err != nil {
return err
}
msg := types.NewMsgSetRecord(payload, args[1], clientCtx.GetFromAddress())
err = msg.ValidateBasic()
if err != nil {
return err
+5 -5
View File
@@ -209,7 +209,7 @@ func (s *IntegrationTestSuite) TestGRPCQueryRecordExpiryQueue() {
func(bondId string) {
dir, err := os.Getwd()
sr.NoError(err)
payloadPath := dir + "/example1.yml"
payloadPath := dir + "/service_provider_example.yml"
args := []string{
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
@@ -353,7 +353,7 @@ func (s *IntegrationTestSuite) TestGRPCQueryListRecords() {
func(bondId string) {
dir, err := os.Getwd()
sr.NoError(err)
payloadPath := dir + "/example1.yml"
payloadPath := dir + "/service_provider_example.yml"
args := []string{
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
@@ -457,8 +457,8 @@ func (s *IntegrationTestSuite) TestGRPCQueryGetRecordByID() {
err := val.ClientCtx.Codec.UnmarshalJSON(resp, &response)
sr.NoError(err)
record := response.GetRecord()
sr.NotZero(len(record.GetID()))
sr.Equal(record.GetID(), recordID)
sr.NotZero(len(record.GetId()))
sr.Equal(record.GetId(), recordID)
}
})
}
@@ -626,7 +626,7 @@ func createRecord(bondID string, s *IntegrationTestSuite) {
dir, err := os.Getwd()
sr.NoError(err)
payloadPath := dir + "/example1.yml"
payloadPath := dir + "/service_provider_example.yml"
args := []string{
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
+1 -1
View File
@@ -79,7 +79,7 @@ func (s *IntegrationTestSuite) TestGetCmdQueryForRecords() {
bondID := GetBondID(s)
dir, err := os.Getwd()
sr.NoError(err)
payloadPath := dir + "/example1.yml"
payloadPath := dir + "/service_provider_example.yml"
args := []string{
payloadPath, bondID,
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
@@ -0,0 +1,12 @@
record:
type: ServiceProviderRegistration
bond_id: madeUpBondID
laconic_id: madeUpLaconicID
x500:
common_name: cerc-io
organization_unit: xyz
organization_name: abc
state_name: california
country: US
locality_name: local
+4 -4
View File
@@ -153,7 +153,7 @@ func GetBondID(s *IntegrationTestSuite) string {
// extract bond id from bonds list
bond := queryResponse.GetBonds()[0]
return bond.GetID()
return bond.GetId()
}
func (s *IntegrationTestSuite) TestGetCmdSetRecord() {
@@ -198,7 +198,7 @@ func (s *IntegrationTestSuite) TestGetCmdSetRecord() {
bondID := GetBondID(s)
dir, err := os.Getwd()
sr.NoError(err)
payloadPath := dir + "/example1.yml"
payloadPath := dir + "/service_provider_example.yml"
tc.args = append([]string{payloadPath, bondID}, tc.args...)
}
@@ -580,7 +580,7 @@ func (s *IntegrationTestSuite) TestGetCmdDissociateBond() {
bondID := GetBondID(s)
dir, err := os.Getwd()
sr.NoError(err)
payloadPath := dir + "/example1.yml"
payloadPath := dir + "/service_provider_example.yml"
args := []string{
payloadPath, bondID,
@@ -822,7 +822,7 @@ func (s *IntegrationTestSuite) TestGetCmdAssociateBond() {
bondID := GetBondID(s)
dir, err := os.Getwd()
sr.NoError(err)
payloadPath := dir + "/example1.yml"
payloadPath := dir + "/service_provider_example.yml"
txArgs := []string{
payloadPath, bondID,
@@ -0,0 +1,6 @@
record:
type: WebsiteRegistrationRecord
url: https://cerc.io
repo_registration_record_cid: QmSnuWmxptJZdLJpKRarxBMS2Ju2oANVrgbr2xWbie9b2D
build_artifact_cid: QmP8jTG1m9GSDJLCbeWhVSVgEzCPPwXRdCRuJtQ5Tz9Kc9
tls_cert_cid: QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR
@@ -0,0 +1,12 @@
record:
type: ServiceProviderRegistration
bond_id: madeUpBondID
laconic_id: madeUpLaconicID
x500:
common_name: cerc-io
organization_unit: xyz
organization_name: abc
state_name: california
country: US
locality_name: local
@@ -0,0 +1,6 @@
record:
type: WebsiteRegistrationRecord
url: https://cerc.io
repo_registration_record_cid: QmSnuWmxptJZdLJpKRarxBMS2Ju2oANVrgbr2xWbie9b2D
build_artifact_cid: QmP8jTG1m9GSDJLCbeWhVSVgEzCPPwXRdCRuJtQ5Tz9Kc9
tls_cerc_cid: QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR
+1 -1
View File
@@ -62,7 +62,7 @@ func UnMarshalMapFromJSONBytes(bytes []byte) map[string]interface{} {
var val map[string]interface{}
err := json.Unmarshal(bytes, &val)
if err != nil {
panic("Marshal error.")
panic("Unmarshal error.")
}
return val
+5 -115
View File
@@ -32,9 +32,11 @@ func (q Querier) ListRecords(c context.Context, req *types.QueryListRecordsReque
all := req.GetAll()
var records []types.Record
if len(attributes) > 0 {
records = q.Keeper.MatchRecords(ctx, func(record *types.RecordType) bool {
return MatchOnAttributes(record, attributes, all)
})
var err error
records, err = q.Keeper.RecordsFromAttributes(ctx, attributes, all)
if err != nil {
return nil, err
}
} else {
records = q.Keeper.ListRecords(ctx)
}
@@ -112,115 +114,3 @@ func (q Querier) GetAuthorityExpiryQueue(c context.Context, _ *types.QueryGetAut
authorities := q.Keeper.GetAuthorityExpiryQueue(ctx)
return &types.QueryGetAuthorityExpiryQueueResponse{Authorities: authorities}, nil
}
func matchOnRecordField(record *types.RecordType, attr *types.QueryListRecordsRequest_KeyValueInput) (fieldFound bool, matched bool) {
fieldFound = false
matched = true
switch attr.Key {
case BondIDAttributeName:
{
fieldFound = true
if record.BondID != attr.Value.GetString_() {
matched = false
return
}
}
case ExpiryTimeAttributeName:
{
fieldFound = true
if record.ExpiryTime != attr.Value.GetString_() {
matched = false
return
}
}
}
return
}
func MatchOnAttributes(record *types.RecordType, attributes []*types.QueryListRecordsRequest_KeyValueInput, all bool) bool {
// Filter deleted records.
if record.Deleted {
return false
}
// If ONLY named records are requested, check for that condition first.
if !all && len(record.Names) == 0 {
return false
}
recAttrs := record.Attributes
for _, attr := range attributes {
// First try matching on record struct fields.
fieldFound, matched := matchOnRecordField(record, attr)
if fieldFound {
if !matched {
return false
}
continue
}
recAttrVal, recAttrFound := recAttrs[attr.Key]
if !recAttrFound {
return false
}
if attr.Value.Type == "int" {
recAttrValInt, ok := recAttrVal.(int)
if !ok || int(attr.Value.GetInt()) != recAttrValInt {
return false
}
}
if attr.Value.Type == "float" {
recAttrValFloat, ok := recAttrVal.(float64)
if !ok || attr.Value.GetFloat() != recAttrValFloat {
return false
}
}
if attr.Value.Type == "string" {
recAttrValString, ok := recAttrVal.(string)
if !ok {
return false
}
if attr.Value.GetString_() != recAttrValString {
return false
}
}
if attr.Value.Type == "boolean" {
recAttrValBool, ok := recAttrVal.(bool)
if !ok || attr.Value.GetBoolean() != recAttrValBool {
return false
}
}
if attr.Value.Type == "reference" {
obj, ok := recAttrVal.(map[string]interface{})
if !ok {
// Attr value is not an object.
return false
}
if _, ok := obj["/"].(string); !ok {
// Attr value is not a reference.
return false
}
recAttrValRefID := obj["/"].(string)
if recAttrValRefID != attr.Value.GetReference().GetId() {
return false
}
}
// TODO: Handle arrays.
}
return true
}
+106 -39
View File
@@ -6,6 +6,8 @@ import (
"os"
"github.com/cerc-io/laconicd/x/nameservice/client/cli"
"github.com/cerc-io/laconicd/x/nameservice/helpers"
"github.com/cerc-io/laconicd/x/nameservice/keeper"
nameservicetypes "github.com/cerc-io/laconicd/x/nameservice/types"
)
@@ -34,12 +36,16 @@ func (suite *KeeperTestSuite) TestGrpcGetRecordLists() {
grpcClient, ctx := suite.queryClient, suite.ctx
sr := suite.Require()
var recordId string
examples := []string{
"/../helpers/examples/service_provider_example.yml",
"/../helpers/examples/website_registration_example.yml",
}
testCases := []struct {
msg string
req *nameservicetypes.QueryListRecordsRequest
createRecord bool
expErr bool
noOfRecords int
msg string
req *nameservicetypes.QueryListRecordsRequest
createRecords bool
expErr bool
noOfRecords int
}{
{
"Empty Records",
@@ -53,23 +59,63 @@ func (suite *KeeperTestSuite) TestGrpcGetRecordLists() {
&nameservicetypes.QueryListRecordsRequest{},
true,
false,
2,
},
{
"Filter with type",
&nameservicetypes.QueryListRecordsRequest{
Attributes: []*nameservicetypes.QueryListRecordsRequest_KeyValueInput{
{
Key: "type",
Value: &nameservicetypes.QueryListRecordsRequest_ValueInput{
Type: "string",
String_: "WebsiteRegistrationRecord",
},
},
},
All: true,
},
true,
false,
1,
},
{
"Filter with attributes ServiceProviderRegistration",
&nameservicetypes.QueryListRecordsRequest{
Attributes: []*nameservicetypes.QueryListRecordsRequest_KeyValueInput{
{
Key: "x500state_name",
Value: &nameservicetypes.QueryListRecordsRequest_ValueInput{
Type: "string",
String_: "california",
},
},
},
All: true,
},
true,
false,
1,
},
}
for _, test := range testCases {
suite.Run(fmt.Sprintf("Case %s ", test.msg), func() {
if test.createRecord {
dir, err := os.Getwd()
sr.NoError(err)
payload, err := cli.GetPayloadFromFile(dir + "/../helpers/examples/example1.yml")
sr.NoError(err)
record, err := suite.app.NameServiceKeeper.ProcessSetRecord(ctx, nameservicetypes.MsgSetRecord{
BondId: suite.bond.GetID(),
Signer: suite.accounts[0].String(),
Payload: payload.ToPayload(),
})
sr.NoError(err)
sr.NotNil(record.ID)
if test.createRecords {
for _, example := range examples {
dir, err := os.Getwd()
sr.NoError(err)
payloadType, err := cli.GetPayloadFromFile(fmt.Sprint(dir, example))
sr.NoError(err)
payload, err := payloadType.ToPayload()
sr.NoError(err)
record, err := suite.app.NameServiceKeeper.ProcessSetRecord(ctx, nameservicetypes.MsgSetRecord{
BondId: suite.bond.GetId(),
Signer: suite.accounts[0].String(),
Payload: payload,
})
sr.NoError(err)
sr.NotNil(record.ID)
}
}
resp, err := grpcClient.ListRecords(context.Background(), test.req)
if test.expErr {
@@ -77,10 +123,23 @@ func (suite *KeeperTestSuite) TestGrpcGetRecordLists() {
} else {
sr.NoError(err)
sr.Equal(test.noOfRecords, len(resp.GetRecords()))
if test.createRecord {
recordId = resp.GetRecords()[0].GetID()
if test.createRecords {
recordId = resp.GetRecords()[0].GetId()
sr.NotZero(resp.GetRecords())
sr.Equal(resp.GetRecords()[0].GetBondId(), suite.bond.GetID())
sr.Equal(resp.GetRecords()[0].GetBondId(), suite.bond.GetId())
for _, record := range resp.GetRecords() {
bz, err := nameservicetypes.GetJSONBytesFromAny(*record.Attributes)
sr.NoError(err)
recAttr := helpers.UnMarshalMapFromJSONBytes(bz)
for _, attr := range test.req.GetAttributes() {
if attr.Key[:4] == "x500" {
sr.Equal(keeper.GetAttributeValue(attr.Value), recAttr["x500"].(map[string]interface{})[attr.Key[4:]])
} else {
sr.Equal(keeper.GetAttributeValue(attr.Value), recAttr[attr.Key])
}
}
}
}
}
})
@@ -120,7 +179,7 @@ func (suite *KeeperTestSuite) TestGrpcGetRecordLists() {
sr.NoError(err)
sr.NotNil(resp.GetRecord())
if test.createRecord {
sr.Equal(resp.GetRecord().BondId, suite.bond.GetID())
sr.Equal(resp.GetRecord().BondId, suite.bond.GetId())
sr.Equal(resp.GetRecord().Id, recordId)
}
}
@@ -145,7 +204,7 @@ func (suite *KeeperTestSuite) TestGrpcGetRecordLists() {
{
"With Bond ID",
&nameservicetypes.QueryRecordByBondIDRequest{
Id: suite.bond.GetID(),
Id: suite.bond.GetId(),
},
true,
false,
@@ -162,7 +221,7 @@ func (suite *KeeperTestSuite) TestGrpcGetRecordLists() {
sr.NotNil(resp.GetRecords())
if test.createRecord {
sr.NotZero(resp.GetRecords())
sr.Equal(resp.GetRecords()[0].GetBondId(), suite.bond.GetID())
sr.Equal(resp.GetRecords()[0].GetBondId(), suite.bond.GetId())
}
}
})
@@ -172,12 +231,16 @@ func (suite *KeeperTestSuite) TestGrpcGetRecordLists() {
func (suite *KeeperTestSuite) TestGrpcQueryNameserviceModuleBalance() {
grpcClient, ctx := suite.queryClient, suite.ctx
sr := suite.Require()
examples := []string{
"/../helpers/examples/service_provider_example.yml",
"/../helpers/examples/website_registration_example.yml",
}
testCases := []struct {
msg string
req *nameservicetypes.GetNameServiceModuleBalanceRequest
createRecord bool
expErr bool
noOfRecords int
msg string
req *nameservicetypes.GetNameServiceModuleBalanceRequest
createRecords bool
expErr bool
noOfRecords int
}{
{
"Get Module Balance",
@@ -189,18 +252,22 @@ func (suite *KeeperTestSuite) TestGrpcQueryNameserviceModuleBalance() {
}
for _, test := range testCases {
suite.Run(fmt.Sprintf("Case %s ", test.msg), func() {
if test.createRecord {
if test.createRecords {
dir, err := os.Getwd()
sr.NoError(err)
payload, err := cli.GetPayloadFromFile(dir + "/../helpers/examples/example1.yml")
sr.NoError(err)
record, err := suite.app.NameServiceKeeper.ProcessSetRecord(ctx, nameservicetypes.MsgSetRecord{
BondId: suite.bond.GetID(),
Signer: suite.accounts[0].String(),
Payload: payload.ToPayload(),
})
sr.NoError(err)
sr.NotNil(record.ID)
for _, example := range examples {
payloadType, err := cli.GetPayloadFromFile(fmt.Sprint(dir, example))
sr.NoError(err)
payload, err := payloadType.ToPayload()
sr.NoError(err)
record, err := suite.app.NameServiceKeeper.ProcessSetRecord(ctx, nameservicetypes.MsgSetRecord{
BondId: suite.bond.GetId(),
Signer: suite.accounts[0].String(),
Payload: payload,
})
sr.NoError(err)
sr.NotNil(record.ID)
}
}
resp, err := grpcClient.GetNameServiceModuleBalance(context.Background(), test.req)
if test.expErr {
@@ -208,7 +275,7 @@ func (suite *KeeperTestSuite) TestGrpcQueryNameserviceModuleBalance() {
} else {
sr.NoError(err)
sr.Equal(test.noOfRecords, len(resp.GetBalances()))
if test.createRecord {
if test.createRecords {
balance := resp.GetBalances()[0]
sr.Equal(balance.AccountName, nameservicetypes.RecordRentModuleAccountName)
}
+170 -20
View File
@@ -2,6 +2,7 @@ package keeper
import (
"bytes"
"encoding/json"
"fmt"
"sort"
"time"
@@ -45,6 +46,9 @@ var (
// PrefixBondIDToAuthoritiesIndex is the prefix for the Bond ID -> [Authority] index.
PrefixBondIDToAuthoritiesIndex = []byte{0x06}
// PrefixAttributesIndex is the prefix for the nameservice Record.Attribute -> []Record.ID index
PrefixAttributesIndex = []byte{0x07}
// PrefixExpiryTimeToRecordsIndex is the prefix for the Expiry Time -> [Record] index.
PrefixExpiryTimeToRecordsIndex = []byte{0x10}
@@ -129,27 +133,80 @@ func (k Keeper) ListRecords(ctx sdk.Context) []types.Record {
return records
}
// MatchRecords - get all matching records.
func (k Keeper) MatchRecords(ctx sdk.Context, matchFn func(*types.RecordType) bool) []types.Record {
var records []types.Record
store := ctx.KVStore(k.storeKey)
itr := sdk.KVStorePrefixIterator(store, PrefixCIDToRecordIndex)
defer itr.Close()
for ; itr.Valid(); itr.Next() {
bz := store.Get(itr.Key())
if bz != nil {
var obj types.Record
k.cdc.MustUnmarshal(bz, &obj)
obj = recordObjToRecord(store, obj)
record := obj.ToRecordType()
if matchFn(&record) {
records = append(records, obj)
}
func (k Keeper) RecordsFromAttributes(ctx sdk.Context, attributes []*types.QueryListRecordsRequest_KeyValueInput, all bool) ([]types.Record, error) {
resultRecordIds := []string{}
for i, attr := range attributes {
val := GetAttributeValue(attr.Value)
attributeIndex := GetAttributesIndexKey(attr.Key, val)
recordIds, err := k.GetAttributeMapping(ctx, attributeIndex)
if err != nil {
return nil, err
}
if i == 0 {
resultRecordIds = recordIds
} else {
resultRecordIds = getIntersection(recordIds, resultRecordIds)
}
}
return records
records := []types.Record{}
for _, id := range resultRecordIds {
record := k.GetRecord(ctx, id)
if record.Deleted {
continue
}
if !all && len(record.Names) == 0 {
continue
}
records = append(records, record)
}
return records, nil
}
func GetAttributeValue(input *types.QueryListRecordsRequest_ValueInput) interface{} {
if input.Type == "int" {
return input.GetInt()
}
if input.Type == "float" {
return input.GetFloat()
}
if input.Type == "string" {
return input.GetString_()
}
if input.Type == "boolean" {
return input.GetBoolean()
}
if input.Type == "reference" {
return input.GetReference().GetId()
}
return nil
}
func getIntersection(a []string, b []string) []string {
result := []string{}
if len(a) < len(b) {
for _, str := range a {
if contains(b, str) {
result = append(result, str)
}
}
} else {
for _, str := range b {
if contains(a, str) {
result = append(result, str)
}
}
}
return result
}
func contains(arr []string, str string) bool {
for _, s := range arr {
if s == str {
return true
}
}
return false
}
func (k Keeper) GetRecordExpiryQueue(ctx sdk.Context) []*types.ExpiryQueueRecord {
@@ -229,8 +286,17 @@ func (k Keeper) processRecord(ctx sdk.Context, record *types.RecordType, isRenew
record.ExpiryTime = ctx.BlockHeader().Time.Add(params.RecordRentDuration).Format(time.RFC3339)
record.Deleted = false
k.PutRecord(ctx, record.ToRecordObj())
k.InsertRecordExpiryQueue(ctx, record.ToRecordObj())
recordObj, err := record.ToRecordObj()
if err != nil {
return err
}
k.PutRecord(ctx, recordObj)
if err := k.ProcessAttributes(ctx, *record); err != nil {
return err
}
k.InsertRecordExpiryQueue(ctx, recordObj)
// Renewal doesn't change the name and bond indexes.
if !isRenewal {
@@ -247,6 +313,90 @@ func (k Keeper) PutRecord(ctx sdk.Context, record types.Record) {
k.updateBlockChangeSetForRecord(ctx, record.Id)
}
func (k Keeper) ProcessAttributes(ctx sdk.Context, record types.RecordType) error {
switch record.Attributes["type"] {
case "ServiceProviderRegistration":
{
// #nosec G705
for key := range record.Attributes {
if key == "x500" {
// #nosec G705
for x500Key, x500Val := range record.Attributes[key].(map[string]interface{}) {
indexKey := GetAttributesIndexKey(fmt.Sprintf("x500%s", x500Key), x500Val)
if err := k.SetAttributeMapping(ctx, indexKey, record.ID); err != nil {
return err
}
}
} else {
indexKey := GetAttributesIndexKey(key, record.Attributes[key])
if err := k.SetAttributeMapping(ctx, indexKey, record.ID); err != nil {
return err
}
}
}
}
case "WebsiteRegistrationRecord":
{
// #nosec G705
for key := range record.Attributes {
indexKey := GetAttributesIndexKey(key, record.Attributes[key])
if err := k.SetAttributeMapping(ctx, indexKey, record.ID); err != nil {
return err
}
}
}
default:
return fmt.Errorf("unsupported record type %s", record.Attributes["type"])
}
expiryTimeKey := GetAttributesIndexKey(ExpiryTimeAttributeName, record.ExpiryTime)
if err := k.SetAttributeMapping(ctx, expiryTimeKey, record.ID); err != nil {
return err
}
return nil
}
func GetAttributesIndexKey(key string, value interface{}) []byte {
keyString := fmt.Sprintf("%s%s", key, value)
return append(PrefixAttributesIndex, []byte(keyString)...)
}
func (k Keeper) SetAttributeMapping(ctx sdk.Context, key []byte, recordID string) error {
store := ctx.KVStore(k.storeKey)
var recordIds []string
if store.Has(key) {
err := json.Unmarshal(store.Get(key), &recordIds)
if err != nil {
return fmt.Errorf("cannot unmarshal byte array, error, %w", err)
}
} else {
recordIds = []string{}
}
recordIds = append(recordIds, recordID)
bz, err := json.Marshal(recordIds)
if err != nil {
return fmt.Errorf("cannot marshal string array, error, %w", err)
}
store.Set(key, bz)
return nil
}
func (k Keeper) GetAttributeMapping(ctx sdk.Context, key []byte) ([]string, error) {
store := ctx.KVStore(k.storeKey)
if !store.Has(key) {
return nil, fmt.Errorf("store doesn't have key")
}
var recordIds []string
if err := json.Unmarshal(store.Get(key), &recordIds); err != nil {
return nil, fmt.Errorf("cannont unmarshal byte array, error, %w", err)
}
return recordIds, nil
}
// AddBondToRecordIndexEntry adds the Bond ID -> [Record] index entry.
func (k Keeper) AddBondToRecordIndexEntry(ctx sdk.Context, bondID string, id string) {
store := ctx.KVStore(k.storeKey)
+1 -2
View File
@@ -39,7 +39,7 @@ func (m msgServer) SetRecord(c context.Context, msg *types.MsgSetRecord) (*types
types.EventTypeSetRecord,
sdk.NewAttribute(types.AttributeKeySigner, msg.GetSigner()),
sdk.NewAttribute(types.AttributeKeyBondID, msg.GetBondId()),
sdk.NewAttribute(types.AttributeKeyPayload, msg.Payload.String()),
sdk.NewAttribute(types.AttributeKeyPayload, msg.Payload.Record.Id),
),
sdk.NewEvent(
sdk.EventTypeMessage,
@@ -273,7 +273,6 @@ func (m msgServer) ReAssociateRecords(c context.Context, msg *types.MsgReAssocia
if err != nil {
return nil, err
}
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeReAssociateRecords,
+5
View File
@@ -0,0 +1,5 @@
package types
type Attributes interface {
GetType() string
}
File diff suppressed because it is too large Load Diff
+12
View File
@@ -38,6 +38,18 @@ func RegisterInterfaces(registry types.InterfaceRegistry) {
&MsgDissociateRecords{},
&MsgReAssociateRecords{},
)
registry.RegisterInterface(
"vulcanize.nameservice.v1beta1.ServiceProvideRegistration",
(*Attributes)(nil),
&ServiceProviderRegistration{},
)
registry.RegisterInterface(
"vulcanize.nameservice.v1beta1.WebsiteRegistrationRecord",
(*Attributes)(nil),
&WebsiteRegistrationRecord{},
)
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
}
+175 -112
View File
@@ -5,6 +5,7 @@ package types
import (
fmt "fmt"
types1 "github.com/cosmos/cosmos-sdk/codec/types"
types "github.com/cosmos/cosmos-sdk/types"
_ "github.com/gogo/protobuf/gogoproto"
proto "github.com/gogo/protobuf/proto"
@@ -156,14 +157,15 @@ func (m *Params) GetAuthorityAuctionMinimumBid() types.Coin {
// Params defines the nameservice module records
type Record struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" json:"id" yaml:"id"`
BondId string `protobuf:"bytes,2,opt,name=bond_id,json=bondId,proto3" json:"bond_id,omitempty" json:"bondId" yaml:"bondId"`
CreateTime string `protobuf:"bytes,3,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty" json:"createTime" yaml:"createTime"`
ExpiryTime string `protobuf:"bytes,4,opt,name=expiry_time,json=expiryTime,proto3" json:"expiry_time,omitempty" json:"expiryTime" yaml:"expiryTime"`
Deleted bool `protobuf:"varint,5,opt,name=deleted,proto3" json:"deleted,omitempty"`
Owners []string `protobuf:"bytes,6,rep,name=owners,proto3" json:"owners,omitempty" json:"owners" yaml:"owners"`
Attributes string `protobuf:"bytes,7,opt,name=attributes,proto3" json:"attributes,omitempty" json:"attributes" yaml:"attributes"`
Names []string `protobuf:"bytes,8,rep,name=names,proto3" json:"names,omitempty" json:"names" yaml:"names"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" json:"id" yaml:"id"`
BondId string `protobuf:"bytes,2,opt,name=bond_id,json=bondId,proto3" json:"bond_id,omitempty" json:"bondId" yaml:"bondId"`
CreateTime string `protobuf:"bytes,3,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty" json:"createTime" yaml:"createTime"`
ExpiryTime string `protobuf:"bytes,4,opt,name=expiry_time,json=expiryTime,proto3" json:"expiry_time,omitempty" json:"expiryTime" yaml:"expiryTime"`
Deleted bool `protobuf:"varint,5,opt,name=deleted,proto3" json:"deleted,omitempty"`
Owners []string `protobuf:"bytes,6,rep,name=owners,proto3" json:"owners,omitempty" json:"owners" yaml:"owners"`
Attributes *types1.Any `protobuf:"bytes,7,opt,name=attributes,proto3" json:"attributes,omitempty" json:"attributes" yaml:"attributes"`
Names []string `protobuf:"bytes,8,rep,name=names,proto3" json:"names,omitempty" json:"names" yaml:"names"`
Type string `protobuf:"bytes,9,opt,name=type,proto3" json:"type,omitempty" json:"types" yaml:"types"`
}
func (m *Record) Reset() { *m = Record{} }
@@ -199,7 +201,7 @@ func (m *Record) XXX_DiscardUnknown() {
var xxx_messageInfo_Record proto.InternalMessageInfo
func (m *Record) GetID() string {
func (m *Record) GetId() string {
if m != nil {
return m.Id
}
@@ -241,11 +243,11 @@ func (m *Record) GetOwners() []string {
return nil
}
func (m *Record) GetAttributes() string {
func (m *Record) GetAttributes() *types1.Any {
if m != nil {
return m.Attributes
}
return ""
return nil
}
func (m *Record) GetNames() []string {
@@ -255,6 +257,13 @@ func (m *Record) GetNames() []string {
return nil
}
func (m *Record) GetType() string {
if m != nil {
return m.Type
}
return ""
}
// AuthorityEntry defines the nameservice module AuthorityEntries
type AuthorityEntry struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
@@ -772,90 +781,92 @@ func init() {
}
var fileDescriptor_c2009c2df775dbad = []byte{
// 1325 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0xdd, 0x6e, 0x1b, 0xc5,
0x17, 0xcf, 0xc6, 0x89, 0x13, 0x4f, 0x9a, 0xfc, 0xff, 0x1a, 0xd2, 0x76, 0x13, 0xa8, 0x37, 0x18,
0x55, 0x6d, 0x55, 0xe2, 0x55, 0xe9, 0x45, 0xf9, 0x10, 0x42, 0xd9, 0xa4, 0x4d, 0x2d, 0x04, 0x84,
0x69, 0x6f, 0xe0, 0xc6, 0xcc, 0xee, 0x4e, 0xed, 0xa1, 0xde, 0x1d, 0x6b, 0x77, 0x36, 0xd4, 0x70,
0xc5, 0x1b, 0x54, 0xe2, 0xa6, 0x17, 0x88, 0x17, 0x00, 0x89, 0xc7, 0xa0, 0x97, 0xbd, 0x44, 0x48,
0x18, 0xd4, 0xbe, 0x81, 0x9f, 0x00, 0xed, 0x7c, 0xec, 0x97, 0xed, 0x3a, 0x6a, 0xef, 0xf6, 0x9c,
0xdf, 0x39, 0x67, 0x7e, 0x73, 0xe6, 0x9c, 0x33, 0xb3, 0xc0, 0x3e, 0x4d, 0x06, 0x1e, 0x0e, 0xe9,
0xf7, 0xc4, 0x0e, 0x71, 0x40, 0x62, 0x12, 0x9d, 0x52, 0x8f, 0xd8, 0xa7, 0x37, 0x5c, 0xc2, 0xf1,
0x8d, 0xa2, 0xae, 0x3d, 0x8c, 0x18, 0x67, 0xf0, 0x52, 0xe6, 0xd0, 0x2e, 0x82, 0xca, 0x61, 0xb7,
0xd9, 0x63, 0xac, 0x37, 0x20, 0xb6, 0x30, 0x76, 0x93, 0x07, 0xb6, 0x9f, 0x44, 0x98, 0x53, 0x16,
0x4a, 0xf7, 0x5d, 0xab, 0x8a, 0x73, 0x1a, 0x90, 0x98, 0xe3, 0x60, 0xa8, 0x0c, 0xb6, 0x7b, 0xac,
0xc7, 0xc4, 0xa7, 0x9d, 0x7e, 0x29, 0x6d, 0xd3, 0x63, 0x71, 0xc0, 0x62, 0xdb, 0xc5, 0x71, 0x4e,
0xce, 0x63, 0x54, 0x85, 0x6d, 0xfd, 0xbd, 0x09, 0xea, 0x27, 0x38, 0xc2, 0x41, 0x0c, 0x29, 0xd8,
0x88, 0x88, 0xc7, 0x22, 0xbf, 0x1b, 0x91, 0x90, 0x9b, 0xc6, 0x9e, 0x71, 0x75, 0xe3, 0xbd, 0x9d,
0xb6, 0x0c, 0xd0, 0x4e, 0x03, 0x68, 0xb2, 0xed, 0x43, 0x46, 0x43, 0x67, 0xff, 0xe9, 0xd8, 0x5a,
0x9a, 0x8c, 0xad, 0xcb, 0xdf, 0xc6, 0x2c, 0xfc, 0xb0, 0x55, 0xf0, 0x6d, 0xed, 0x8d, 0x70, 0x30,
0x28, 0xab, 0x10, 0x90, 0x12, 0x22, 0x21, 0x87, 0x8f, 0x0d, 0xb0, 0x5d, 0x00, 0xbb, 0x7a, 0xaf,
0xe6, 0xb2, 0x5a, 0x54, 0x6e, 0xb6, 0xad, 0x37, 0xdb, 0x3e, 0x52, 0x06, 0xce, 0xa1, 0x5a, 0xf4,
0xd6, 0xd4, 0xa2, 0x59, 0x90, 0x19, 0xab, 0xe7, 0xd8, 0x93, 0x7f, 0x2c, 0x03, 0xc1, 0x9c, 0x8a,
0x0e, 0x0c, 0x13, 0xb0, 0x85, 0x13, 0xde, 0x67, 0x11, 0xe5, 0x23, 0x99, 0x80, 0xda, 0xa2, 0x04,
0xdc, 0x54, 0x5c, 0xae, 0x4b, 0x2e, 0x65, 0x77, 0xcd, 0xa2, 0xa2, 0x45, 0x9b, 0x99, 0x42, 0x64,
0xe2, 0x67, 0x03, 0x5c, 0x2c, 0x9b, 0xe4, 0xc9, 0x58, 0x59, 0x94, 0x8c, 0x8e, 0x22, 0xf0, 0xf1,
0x2c, 0x02, 0x53, 0xf9, 0x98, 0x07, 0x8b, 0x94, 0x9c, 0x2f, 0xd1, 0xca, 0xb2, 0xf2, 0xc4, 0x00,
0x17, 0x72, 0xbf, 0x5e, 0x84, 0x3d, 0xd2, 0x1d, 0x92, 0x88, 0x32, 0xdf, 0x5c, 0x5d, 0xc4, 0xee,
0x58, 0xb1, 0xfb, 0xa8, 0xca, 0xae, 0x18, 0x66, 0x9a, 0x5c, 0x09, 0x15, 0xdc, 0xb6, 0x33, 0xf0,
0x38, 0xc5, 0x4e, 0x04, 0x04, 0x7f, 0x34, 0xc0, 0x4e, 0xee, 0x85, 0x13, 0x2f, 0x5d, 0xb4, 0x4b,
0x42, 0xec, 0x0e, 0x88, 0x6f, 0xd6, 0xf7, 0x8c, 0xab, 0xeb, 0xce, 0xed, 0xc9, 0xd8, 0x3a, 0xa8,
0x2e, 0x5f, 0x31, 0x9d, 0x66, 0x50, 0x35, 0x40, 0xf9, 0x09, 0x1d, 0x48, 0xe8, 0xb6, 0x44, 0xe0,
0x1f, 0x06, 0x98, 0xe1, 0xe7, 0xb1, 0x20, 0xa0, 0x3c, 0xce, 0x0f, 0x72, 0x6d, 0x51, 0xaa, 0xba,
0x2a, 0x55, 0xf7, 0xe6, 0x71, 0xad, 0x86, 0x9c, 0x4f, 0x7a, 0xca, 0x52, 0xa4, 0xd0, 0xaa, 0xee,
0xe0, 0x50, 0x9a, 0x65, 0x07, 0x3d, 0x7b, 0x27, 0x11, 0x39, 0x25, 0x78, 0x50, 0xd8, 0xc9, 0xfa,
0x6b, 0xef, 0xa4, 0x1a, 0x72, 0xfe, 0x4e, 0xa6, 0x2c, 0x67, 0xef, 0x04, 0x49, 0xb3, 0x6c, 0x27,
0xbf, 0x1a, 0xe0, 0xad, 0x79, 0x69, 0xe9, 0x3e, 0x20, 0xc4, 0x6c, 0x2c, 0xea, 0xeb, 0x2f, 0xd4,
0x1e, 0x8e, 0x5f, 0x7e, 0x1a, 0x69, 0xb0, 0x45, 0xe7, 0x20, 0x6c, 0xd0, 0xce, 0xec, 0xec, 0xdf,
0x21, 0x64, 0x0e, 0x5b, 0xb9, 0x75, 0xc1, 0x16, 0xbc, 0x36, 0xdb, 0x3c, 0xd8, 0xa2, 0x5c, 0xcf,
0x61, 0x2b, 0x33, 0x9c, 0xb2, 0xfd, 0xdd, 0x00, 0x97, 0xa6, 0x9d, 0x03, 0x1a, 0xd2, 0x20, 0x09,
0xba, 0x2e, 0xf5, 0xcd, 0x8d, 0x45, 0x74, 0xbf, 0x54, 0x74, 0x3b, 0xf3, 0xe8, 0x16, 0xa2, 0xcd,
0xe7, 0x5b, 0x34, 0x42, 0xbb, 0x55, 0xc2, 0x9f, 0x49, 0xd4, 0xa1, 0x7e, 0xeb, 0x59, 0x0d, 0xd4,
0x91, 0x98, 0xf6, 0xf0, 0x0a, 0x58, 0xa6, 0xbe, 0xb8, 0xd6, 0x1a, 0xce, 0xc5, 0xc9, 0xd8, 0x7a,
0x43, 0x32, 0xc8, 0x97, 0x49, 0x63, 0x2d, 0x53, 0x1f, 0xbe, 0x0f, 0xd6, 0x5c, 0x16, 0xfa, 0x5d,
0xea, 0x8b, 0xfb, 0xa8, 0xe1, 0x58, 0x93, 0xb1, 0xf5, 0xa6, 0xb4, 0x4e, 0x81, 0x4e, 0xe6, 0xa1,
0x24, 0x54, 0x97, 0x1f, 0xf0, 0x2e, 0xd8, 0xf0, 0x22, 0x82, 0x39, 0xe9, 0xa6, 0xb7, 0xb3, 0xb8,
0x41, 0x1a, 0xce, 0x95, 0xc9, 0xd8, 0x7a, 0x47, 0x7a, 0x4b, 0xf0, 0x3e, 0x0d, 0xb2, 0xa3, 0x28,
0x68, 0x10, 0xc8, 0x85, 0x34, 0x12, 0x79, 0x34, 0xa4, 0xd1, 0x48, 0x46, 0x5a, 0xa9, 0x46, 0x92,
0x60, 0x31, 0x52, 0x41, 0x83, 0x40, 0x2e, 0x40, 0x13, 0xac, 0xf9, 0x64, 0x40, 0x38, 0x91, 0x23,
0x7b, 0x1d, 0x69, 0x11, 0xde, 0x02, 0x75, 0xf6, 0x5d, 0x48, 0xa2, 0xd8, 0xac, 0xef, 0xd5, 0xca,
0xdb, 0x94, 0x7a, 0x1d, 0x5a, 0x49, 0x48, 0x99, 0xc3, 0x63, 0x00, 0x30, 0xe7, 0x11, 0x75, 0x13,
0x4e, 0x62, 0x31, 0xdd, 0x4a, 0xdc, 0x72, 0x2c, 0x3b, 0xc0, 0x5c, 0x83, 0x0a, 0xae, 0xf0, 0x26,
0x58, 0x15, 0x6f, 0x21, 0x73, 0x5d, 0x10, 0xb8, 0x34, 0x19, 0x5b, 0x3b, 0x32, 0x86, 0x50, 0x6b,
0x77, 0x29, 0x20, 0x69, 0xdb, 0xea, 0x83, 0xad, 0x03, 0x7d, 0xe0, 0xb7, 0x43, 0x1e, 0x8d, 0x20,
0x04, 0x2b, 0x29, 0x24, 0xcf, 0x16, 0x89, 0x6f, 0xe8, 0x80, 0x55, 0x92, 0x82, 0xea, 0x49, 0xf1,
0x6e, 0xfb, 0xa5, 0xcf, 0xaf, 0xf6, 0xe7, 0x38, 0x20, 0x59, 0x54, 0x24, 0x5d, 0x5b, 0x7f, 0xd5,
0xc0, 0x66, 0x09, 0x80, 0x5f, 0x81, 0xff, 0x8b, 0x1c, 0x74, 0x87, 0x89, 0x3b, 0xa0, 0x5e, 0xf7,
0x21, 0x19, 0xa9, 0x8a, 0xb2, 0xf3, 0x87, 0x80, 0xb0, 0x38, 0x11, 0x06, 0x9f, 0x92, 0x51, 0x29,
0x89, 0xb9, 0x16, 0x6d, 0x95, 0x15, 0xf0, 0x04, 0x6c, 0xca, 0xd0, 0xd8, 0xf7, 0x23, 0x12, 0xc7,
0xaa, 0xf6, 0xae, 0x4f, 0xc6, 0xd6, 0x95, 0x42, 0xdc, 0x03, 0x89, 0x96, 0xa2, 0x6a, 0x1d, 0x3a,
0x57, 0x14, 0xe1, 0x05, 0x50, 0xef, 0x13, 0xda, 0xeb, 0xcb, 0xa7, 0xcc, 0x0a, 0x52, 0x52, 0xaa,
0x8f, 0x39, 0xe6, 0x49, 0x2c, 0xcb, 0x0a, 0x29, 0x09, 0x1e, 0x01, 0xa0, 0xfb, 0x8b, 0xca, 0x62,
0x69, 0x38, 0x97, 0x27, 0x63, 0xeb, 0x6d, 0xdd, 0xaa, 0x02, 0xeb, 0x1c, 0xe5, 0x6d, 0xa9, 0x15,
0xa8, 0xa1, 0xbf, 0x4b, 0xdd, 0x53, 0x9f, 0xd9, 0x3d, 0x47, 0xa5, 0xee, 0x39, 0xca, 0xbb, 0x67,
0x50, 0xae, 0x79, 0x79, 0x6b, 0xee, 0x4e, 0xdd, 0x35, 0xf7, 0xf5, 0xc3, 0xd7, 0xb1, 0xd5, 0x2c,
0x39, 0x4b, 0x4f, 0x3c, 0x4e, 0x2f, 0x8f, 0x42, 0x5f, 0xb4, 0xbe, 0x01, 0x8d, 0xf4, 0x6c, 0xe7,
0x57, 0xd0, 0x27, 0xe5, 0x0a, 0xba, 0x76, 0x86, 0x0a, 0x92, 0x93, 0x46, 0x97, 0xcf, 0x2f, 0x06,
0x00, 0xb9, 0x16, 0xde, 0x01, 0xf5, 0x01, 0xe6, 0x24, 0xd6, 0x4f, 0xeb, 0xf6, 0x99, 0x03, 0x0a,
0x8e, 0x48, 0x79, 0xc3, 0xbb, 0x60, 0xad, 0x4f, 0x63, 0xce, 0x04, 0xb3, 0xda, 0x2b, 0x04, 0xd2,
0xee, 0xad, 0x0f, 0xc0, 0xff, 0x2a, 0x18, 0xdc, 0xca, 0x87, 0xa4, 0x98, 0x85, 0x79, 0x0d, 0x2d,
0x17, 0x6b, 0xa8, 0x15, 0x81, 0xc6, 0x3d, 0xda, 0x0b, 0x31, 0x4f, 0x22, 0x02, 0xaf, 0x83, 0x5a,
0x4c, 0x7b, 0xaa, 0x11, 0x76, 0x26, 0x63, 0xeb, 0xbc, 0x3c, 0x90, 0x98, 0xf6, 0xf4, 0x49, 0xa4,
0x9f, 0x28, 0xb5, 0x4a, 0xeb, 0x63, 0x98, 0xb8, 0xa2, 0x73, 0xa6, 0xa6, 0xeb, 0x30, 0x71, 0x0b,
0x1d, 0xa3, 0x24, 0x54, 0x57, 0x1f, 0x3f, 0x2d, 0x83, 0x2d, 0x67, 0xc0, 0xbc, 0x87, 0x87, 0x7d,
0x1c, 0xf6, 0xc8, 0x3d, 0xc2, 0x0b, 0xf4, 0xd2, 0xc5, 0x6b, 0x59, 0x89, 0x9b, 0x60, 0x4d, 0xbe,
0xf1, 0x63, 0x91, 0xa3, 0x06, 0xd2, 0x22, 0xdc, 0x05, 0xeb, 0xaa, 0x56, 0x63, 0xb3, 0x26, 0xa0,
0x4c, 0x86, 0x3f, 0x80, 0x73, 0xba, 0x01, 0x5c, 0xea, 0xa7, 0xed, 0x91, 0xa6, 0x77, 0x7f, 0x41,
0x7a, 0xd5, 0xa5, 0xe3, 0x50, 0xbf, 0x13, 0x3e, 0x60, 0xce, 0xb5, 0xfc, 0x97, 0x08, 0x67, 0x48,
0x5c, 0xe9, 0x19, 0xa1, 0x42, 0x1b, 0x05, 0x09, 0xee, 0x81, 0x0d, 0x7d, 0x8f, 0x51, 0x12, 0x9b,
0xab, 0x82, 0x5b, 0x51, 0x05, 0xb7, 0xf5, 0xb4, 0x14, 0xe3, 0x5a, 0x8f, 0xc3, 0xdf, 0x8c, 0x74,
0x1e, 0x16, 0x29, 0x54, 0x1a, 0xd9, 0x78, 0xc5, 0x46, 0xbe, 0x0f, 0xb6, 0x5c, 0xea, 0xfb, 0x53,
0x13, 0x69, 0x7f, 0x32, 0xb6, 0xae, 0xa9, 0x7e, 0x16, 0x78, 0x65, 0x24, 0x95, 0x95, 0x68, 0xb3,
0x24, 0x3b, 0x9d, 0xa7, 0xcf, 0x9b, 0xc6, 0xb3, 0xe7, 0x4d, 0xe3, 0xdf, 0xe7, 0x4d, 0xe3, 0xf1,
0x8b, 0xe6, 0xd2, 0xb3, 0x17, 0xcd, 0xa5, 0x3f, 0x5f, 0x34, 0x97, 0xbe, 0xb6, 0x7b, 0x94, 0xf7,
0x13, 0xb7, 0xed, 0xb1, 0xc0, 0xf6, 0x48, 0xe4, 0xed, 0x53, 0x66, 0x0f, 0xb0, 0xc7, 0x42, 0xea,
0xf9, 0xf6, 0xa3, 0xd2, 0x5f, 0x36, 0x1f, 0x0d, 0x49, 0xec, 0xd6, 0xc5, 0x48, 0xb8, 0xf9, 0x5f,
0x00, 0x00, 0x00, 0xff, 0xff, 0xe8, 0x01, 0x83, 0xe6, 0x8b, 0x0f, 0x00, 0x00,
// 1353 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0x5b, 0x6f, 0x1b, 0xc5,
0x17, 0xcf, 0xc6, 0x89, 0x13, 0x9f, 0x34, 0xf9, 0xff, 0x35, 0xa4, 0xed, 0x26, 0x50, 0x6f, 0x30,
0xaa, 0xda, 0xaa, 0xc4, 0xab, 0xd2, 0x87, 0x72, 0x11, 0x42, 0xd9, 0xa4, 0x17, 0x0b, 0x01, 0x61,
0xda, 0x17, 0x90, 0x90, 0x99, 0xdd, 0x9d, 0xda, 0x43, 0xbd, 0xbb, 0xd6, 0x5e, 0x42, 0x0d, 0x4f,
0x7c, 0x83, 0x4a, 0xbc, 0x14, 0x09, 0xf1, 0x05, 0x40, 0xe2, 0x63, 0xd0, 0xc7, 0x3e, 0x22, 0x24,
0x0c, 0x6a, 0xbf, 0x81, 0x3f, 0x01, 0xda, 0xb9, 0xec, 0xcd, 0x76, 0x1d, 0xb5, 0x6f, 0x7b, 0x6e,
0xbf, 0xf9, 0xcd, 0x99, 0x73, 0xce, 0xcc, 0x82, 0x79, 0x92, 0x0c, 0x1c, 0xe2, 0xb3, 0xef, 0xa8,
0xe9, 0x13, 0x8f, 0x46, 0x34, 0x3c, 0x61, 0x0e, 0x35, 0x4f, 0xae, 0xd9, 0x34, 0x26, 0xd7, 0x8a,
0xba, 0xf6, 0x30, 0x0c, 0xe2, 0x00, 0x5d, 0xc8, 0x02, 0xda, 0x45, 0xa3, 0x0c, 0xd8, 0x6d, 0xf6,
0x82, 0xa0, 0x37, 0xa0, 0x26, 0x77, 0xb6, 0x93, 0xfb, 0xa6, 0x9b, 0x84, 0x24, 0x66, 0x81, 0x2f,
0xc2, 0x77, 0x8d, 0xaa, 0x3d, 0x66, 0x1e, 0x8d, 0x62, 0xe2, 0x0d, 0xa5, 0xc3, 0x76, 0x2f, 0xe8,
0x05, 0xfc, 0xd3, 0x4c, 0xbf, 0xa4, 0xb6, 0xe9, 0x04, 0x91, 0x17, 0x44, 0xa6, 0x4d, 0xa2, 0x9c,
0x9c, 0x13, 0x30, 0x05, 0xbb, 0x53, 0x85, 0x25, 0xfe, 0x48, 0x98, 0x5a, 0x7f, 0x6f, 0x42, 0xfd,
0x98, 0x84, 0xc4, 0x8b, 0x10, 0x83, 0x8d, 0x90, 0x3a, 0x41, 0xe8, 0x76, 0x43, 0xea, 0xc7, 0xba,
0xb6, 0xa7, 0x5d, 0xde, 0x78, 0x67, 0xa7, 0x2d, 0xb0, 0xdb, 0x29, 0xb6, 0xda, 0x47, 0xfb, 0x30,
0x60, 0xbe, 0xb5, 0xff, 0x64, 0x6c, 0x2c, 0x4d, 0xc6, 0xc6, 0xc5, 0x6f, 0xa2, 0xc0, 0x7f, 0xbf,
0x55, 0x88, 0x6d, 0xed, 0x8d, 0x88, 0x37, 0x28, 0xab, 0x30, 0x08, 0x09, 0x53, 0x3f, 0x46, 0x8f,
0x34, 0xd8, 0x2e, 0x18, 0xbb, 0x2a, 0x0d, 0xfa, 0xb2, 0x5c, 0x54, 0x10, 0x6e, 0x2b, 0xc2, 0xed,
0x23, 0xe9, 0x60, 0x1d, 0xca, 0x45, 0x6f, 0x4c, 0x2d, 0x9a, 0x81, 0xcc, 0x58, 0x3d, 0xb7, 0x3d,
0xfe, 0xc7, 0xd0, 0x30, 0xca, 0xa9, 0x28, 0x60, 0x94, 0xc0, 0x16, 0x49, 0xe2, 0x7e, 0x10, 0xb2,
0x78, 0x24, 0x12, 0x50, 0x5b, 0x94, 0x80, 0xeb, 0x92, 0xcb, 0x55, 0xc1, 0xa5, 0x1c, 0xae, 0x58,
0x54, 0xb4, 0x78, 0x33, 0x53, 0xf0, 0x4c, 0xfc, 0xac, 0xc1, 0xf9, 0xb2, 0x4b, 0x9e, 0x8c, 0x95,
0x45, 0xc9, 0xe8, 0x48, 0x02, 0x1f, 0xce, 0x22, 0x30, 0x95, 0x8f, 0x79, 0x66, 0x9e, 0x92, 0xb3,
0x25, 0x5a, 0x59, 0x56, 0x1e, 0x6b, 0x70, 0x2e, 0x8f, 0xeb, 0x85, 0xc4, 0xa1, 0xdd, 0x21, 0x0d,
0x59, 0xe0, 0xea, 0xab, 0x8b, 0xd8, 0xdd, 0x96, 0xec, 0x3e, 0xa8, 0xb2, 0x2b, 0xc2, 0x4c, 0x93,
0x2b, 0x59, 0x39, 0xb7, 0xed, 0xcc, 0x78, 0x3b, 0xb5, 0x1d, 0x73, 0x13, 0xfa, 0x41, 0x83, 0x9d,
0x3c, 0x8a, 0x24, 0x4e, 0xba, 0x68, 0x97, 0xfa, 0xc4, 0x1e, 0x50, 0x57, 0xaf, 0xef, 0x69, 0x97,
0xd7, 0xad, 0x9b, 0x93, 0xb1, 0x71, 0x50, 0x5d, 0xbe, 0xe2, 0x3a, 0xcd, 0xa0, 0xea, 0x80, 0xf3,
0x13, 0x3a, 0x10, 0xa6, 0x9b, 0xc2, 0x82, 0xfe, 0xd0, 0x60, 0x46, 0x9c, 0x13, 0x78, 0x1e, 0x8b,
0xa3, 0xfc, 0x20, 0xd7, 0x16, 0xa5, 0xaa, 0x2b, 0x53, 0x75, 0x77, 0x1e, 0xd7, 0x2a, 0xe4, 0x7c,
0xd2, 0x53, 0x9e, 0x3c, 0x85, 0x46, 0x75, 0x07, 0x87, 0xc2, 0x2d, 0x3b, 0xe8, 0xd9, 0x3b, 0x09,
0xe9, 0x09, 0x25, 0x83, 0xc2, 0x4e, 0xd6, 0x5f, 0x79, 0x27, 0x55, 0xc8, 0xf9, 0x3b, 0x99, 0xf2,
0x9c, 0xbd, 0x13, 0x2c, 0xdc, 0xb2, 0x9d, 0xfc, 0xaa, 0xc1, 0x1b, 0xf3, 0xd2, 0xd2, 0xbd, 0x4f,
0xa9, 0xde, 0x58, 0xd4, 0xd7, 0x9f, 0xc9, 0x3d, 0xdc, 0x7e, 0xf1, 0x69, 0xa4, 0x60, 0x8b, 0xce,
0x81, 0xfb, 0xe0, 0x9d, 0xd9, 0xd9, 0xbf, 0x45, 0xe9, 0x1c, 0xb6, 0x62, 0xeb, 0x9c, 0x2d, 0xbc,
0x32, 0xdb, 0x1c, 0x6c, 0x51, 0xae, 0xe7, 0xb0, 0x15, 0x19, 0x4e, 0xd9, 0xfe, 0xae, 0xc1, 0x85,
0xe9, 0x60, 0x8f, 0xf9, 0xcc, 0x4b, 0xbc, 0xae, 0xcd, 0x5c, 0x7d, 0x63, 0x11, 0xdd, 0xcf, 0x25,
0xdd, 0xce, 0x3c, 0xba, 0x05, 0xb4, 0xf9, 0x7c, 0x8b, 0x4e, 0x78, 0xb7, 0x4a, 0xf8, 0x13, 0x61,
0xb5, 0x98, 0xdb, 0xfa, 0x69, 0x05, 0xea, 0x98, 0x4f, 0x7b, 0x74, 0x09, 0x96, 0x99, 0xcb, 0xaf,
0xb5, 0x86, 0x75, 0x7e, 0x32, 0x36, 0x5e, 0x13, 0x0c, 0xf2, 0x65, 0x52, 0xac, 0x65, 0xe6, 0xa2,
0x77, 0x61, 0xcd, 0x0e, 0x7c, 0xb7, 0xcb, 0x5c, 0x7e, 0x1f, 0x35, 0x2c, 0x63, 0x32, 0x36, 0x5e,
0x17, 0xde, 0xa9, 0xa1, 0x93, 0x45, 0x48, 0x09, 0xd7, 0xc5, 0x07, 0xba, 0x03, 0x1b, 0x4e, 0x48,
0x49, 0x4c, 0xbb, 0xe9, 0xc5, 0xcd, 0x6f, 0x90, 0x86, 0x75, 0x69, 0x32, 0x36, 0xde, 0x12, 0xd1,
0xc2, 0x78, 0x8f, 0x79, 0xd9, 0x51, 0x14, 0x34, 0x18, 0x72, 0x21, 0x45, 0xa2, 0x0f, 0x87, 0x2c,
0x1c, 0x09, 0xa4, 0x95, 0x2a, 0x92, 0x30, 0x16, 0x91, 0x0a, 0x1a, 0x0c, 0xb9, 0x80, 0x74, 0x58,
0x73, 0xe9, 0x80, 0xc6, 0x54, 0x8c, 0xec, 0x75, 0xac, 0x44, 0x74, 0x03, 0xea, 0xc1, 0xb7, 0x3e,
0x0d, 0x23, 0xbd, 0xbe, 0x57, 0x2b, 0x6f, 0x53, 0xe8, 0x15, 0xb4, 0x94, 0xb0, 0x74, 0x47, 0x5f,
0x01, 0x90, 0x38, 0x0e, 0x99, 0x9d, 0xc4, 0x34, 0x92, 0xd3, 0x6d, 0x7b, 0x6a, 0x26, 0x1c, 0xf8,
0xa3, 0x22, 0xe3, 0x3c, 0x22, 0x3b, 0xd6, 0x5c, 0x83, 0x0b, 0x80, 0xe8, 0x3a, 0xac, 0xf2, 0xc7,
0x93, 0xbe, 0xce, 0x69, 0x5d, 0x98, 0x8c, 0x8d, 0x1d, 0x81, 0xc1, 0xd5, 0x2a, 0x5c, 0x08, 0x58,
0xf8, 0xa2, 0x6b, 0xb0, 0x12, 0x8f, 0x86, 0xa2, 0xbb, 0x4b, 0x31, 0xa9, 0x36, 0x8b, 0x11, 0x02,
0xe6, 0xae, 0xad, 0x3e, 0x6c, 0x1d, 0xa8, 0xca, 0xb9, 0xe9, 0xc7, 0xe1, 0x08, 0x21, 0x58, 0x49,
0xd1, 0x44, 0x91, 0x60, 0xfe, 0x8d, 0x2c, 0x58, 0xa5, 0xa9, 0x51, 0xbe, 0x4d, 0xde, 0x6e, 0xbf,
0xf0, 0x89, 0xd7, 0xfe, 0x94, 0x78, 0x34, 0x43, 0xc5, 0x22, 0xb4, 0xf5, 0x57, 0x0d, 0x36, 0x4b,
0x06, 0xf4, 0x05, 0xfc, 0x9f, 0x27, 0xb3, 0x3b, 0x4c, 0xec, 0x01, 0x73, 0xba, 0x0f, 0xe8, 0x48,
0x96, 0xa6, 0x99, 0xbf, 0x28, 0xb8, 0xc7, 0x31, 0x77, 0xf8, 0x98, 0x8e, 0x4a, 0xa7, 0x91, 0x6b,
0xf1, 0x56, 0x59, 0x81, 0x8e, 0x61, 0x53, 0x40, 0x13, 0xd7, 0x0d, 0x69, 0x14, 0xc9, 0x22, 0xbe,
0x3a, 0x19, 0x1b, 0x97, 0x0a, 0xb8, 0x07, 0xc2, 0x5a, 0x42, 0x55, 0x3a, 0x7c, 0xa6, 0x28, 0xa2,
0x73, 0x50, 0xef, 0x53, 0xd6, 0xeb, 0x8b, 0x37, 0xd1, 0x0a, 0x96, 0x52, 0xaa, 0x8f, 0x62, 0x12,
0x27, 0x91, 0xa8, 0x4f, 0x2c, 0x25, 0x74, 0x04, 0xa0, 0x1a, 0x95, 0x89, 0xaa, 0x6b, 0x58, 0x17,
0x27, 0x63, 0xe3, 0x4d, 0xd5, 0xf3, 0xdc, 0xd6, 0x39, 0xca, 0xfb, 0x5b, 0x29, 0x70, 0x43, 0x7d,
0x97, 0xda, 0xb0, 0x3e, 0xb3, 0x0d, 0x8f, 0x4a, 0x6d, 0x78, 0x94, 0xb7, 0xe1, 0xa0, 0xdc, 0x3c,
0xa2, 0x40, 0x77, 0xa7, 0x0a, 0xf4, 0x9e, 0x7a, 0x5c, 0x5b, 0xa6, 0x1c, 0x4a, 0xa7, 0x69, 0xae,
0x47, 0xe9, 0x2d, 0x54, 0x68, 0xb0, 0xd6, 0xd7, 0xd0, 0x48, 0xcf, 0x76, 0x7e, 0x05, 0x7d, 0x54,
0xae, 0xa0, 0x2b, 0xa7, 0xa8, 0x20, 0x31, 0xb2, 0x54, 0xf9, 0xfc, 0xa2, 0x01, 0xe4, 0x5a, 0x74,
0x0b, 0xea, 0x03, 0x12, 0xd3, 0x48, 0xbd, 0xd1, 0xdb, 0xa7, 0x06, 0xe4, 0x1c, 0xb1, 0x8c, 0x46,
0x77, 0x60, 0xad, 0xcf, 0xa2, 0x38, 0xe0, 0xcc, 0x6a, 0x2f, 0x01, 0xa4, 0xc2, 0x5b, 0xef, 0xc1,
0xff, 0x2a, 0x36, 0xb4, 0x95, 0x4f, 0x5b, 0x3e, 0x54, 0xf3, 0x1a, 0x5a, 0x2e, 0xd6, 0x50, 0x2b,
0x84, 0xc6, 0x5d, 0xd6, 0xf3, 0x49, 0x9c, 0x84, 0x14, 0x5d, 0x85, 0x5a, 0xc4, 0x7a, 0xb2, 0x11,
0x76, 0x26, 0x63, 0xe3, 0xac, 0x38, 0x90, 0x88, 0xf5, 0xd4, 0x49, 0xa4, 0x9f, 0x38, 0xf5, 0x4a,
0xeb, 0x63, 0x98, 0xd8, 0xbc, 0x73, 0xa6, 0xc6, 0xf4, 0x30, 0xb1, 0x0b, 0x1d, 0x23, 0x25, 0x5c,
0x97, 0x1f, 0x3f, 0x2e, 0xc3, 0x96, 0x35, 0x08, 0x9c, 0x07, 0x87, 0x7d, 0xe2, 0xf7, 0xe8, 0x5d,
0x1a, 0x17, 0xe8, 0xa5, 0x8b, 0xd7, 0xb2, 0x12, 0xd7, 0x61, 0x4d, 0xfc, 0x2c, 0x44, 0x3c, 0x47,
0x0d, 0xac, 0x44, 0xb4, 0x0b, 0xeb, 0xb2, 0x56, 0x23, 0xbd, 0xc6, 0x4d, 0x99, 0x8c, 0xbe, 0x87,
0x33, 0xaa, 0x01, 0x6c, 0xe6, 0xa6, 0xed, 0x91, 0xa6, 0x77, 0x7f, 0x41, 0x7a, 0xe5, 0xed, 0x65,
0x31, 0xb7, 0xe3, 0xdf, 0x0f, 0xac, 0x2b, 0xf9, 0xbf, 0x15, 0xc9, 0x2c, 0x51, 0xa5, 0x67, 0xb8,
0x0a, 0x6f, 0x14, 0x24, 0xb4, 0x07, 0x1b, 0xea, 0x42, 0x64, 0x34, 0xd2, 0x57, 0x39, 0xb7, 0xa2,
0x0a, 0x6d, 0xab, 0x01, 0xcb, 0xe7, 0xbe, 0x9c, 0xa0, 0xad, 0xdf, 0xb4, 0x74, 0x1e, 0x16, 0x29,
0x54, 0x1a, 0x59, 0x7b, 0xc9, 0x46, 0xbe, 0x07, 0x5b, 0x36, 0x73, 0xdd, 0xa9, 0x89, 0xb4, 0x3f,
0x19, 0x1b, 0x57, 0x64, 0x3f, 0x73, 0x7b, 0x65, 0x24, 0x95, 0x95, 0x78, 0xb3, 0x24, 0x5b, 0x9d,
0x27, 0xcf, 0x9a, 0xda, 0xd3, 0x67, 0x4d, 0xed, 0xdf, 0x67, 0x4d, 0xed, 0xd1, 0xf3, 0xe6, 0xd2,
0xd3, 0xe7, 0xcd, 0xa5, 0x3f, 0x9f, 0x37, 0x97, 0xbe, 0x34, 0x7b, 0x2c, 0xee, 0x27, 0x76, 0xdb,
0x09, 0x3c, 0xd3, 0xa1, 0xa1, 0xb3, 0xcf, 0x02, 0x73, 0x40, 0x9c, 0xc0, 0x67, 0x8e, 0x6b, 0x3e,
0x2c, 0xfd, 0xc9, 0xf3, 0xfb, 0xc0, 0xae, 0xf3, 0x91, 0x70, 0xfd, 0xbf, 0x00, 0x00, 0x00, 0xff,
0xff, 0x74, 0x45, 0xc5, 0x43, 0xef, 0x0f, 0x00, 0x00,
}
func (m *Params) Marshal() (dAtA []byte, err error) {
@@ -1001,6 +1012,13 @@ func (m *Record) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if len(m.Type) > 0 {
i -= len(m.Type)
copy(dAtA[i:], m.Type)
i = encodeVarintNameservice(dAtA, i, uint64(len(m.Type)))
i--
dAtA[i] = 0x4a
}
if len(m.Names) > 0 {
for iNdEx := len(m.Names) - 1; iNdEx >= 0; iNdEx-- {
i -= len(m.Names[iNdEx])
@@ -1010,10 +1028,15 @@ func (m *Record) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0x42
}
}
if len(m.Attributes) > 0 {
i -= len(m.Attributes)
copy(dAtA[i:], m.Attributes)
i = encodeVarintNameservice(dAtA, i, uint64(len(m.Attributes)))
if m.Attributes != nil {
{
size, err := m.Attributes.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintNameservice(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x3a
}
@@ -1129,12 +1152,12 @@ func (m *NameAuthority) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
n12, err12 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.ExpiryTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.ExpiryTime):])
if err12 != nil {
return 0, err12
n13, err13 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.ExpiryTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.ExpiryTime):])
if err13 != nil {
return 0, err13
}
i -= n12
i = encodeVarintNameservice(dAtA, i, uint64(n12))
i -= n13
i = encodeVarintNameservice(dAtA, i, uint64(n13))
i--
dAtA[i] = 0x3a
if len(m.BondId) > 0 {
@@ -1532,8 +1555,8 @@ func (m *Record) Size() (n int) {
n += 1 + l + sovNameservice(uint64(l))
}
}
l = len(m.Attributes)
if l > 0 {
if m.Attributes != nil {
l = m.Attributes.Size()
n += 1 + l + sovNameservice(uint64(l))
}
if len(m.Names) > 0 {
@@ -1542,6 +1565,10 @@ func (m *Record) Size() (n int) {
n += 1 + l + sovNameservice(uint64(l))
}
}
l = len(m.Type)
if l > 0 {
n += 1 + l + sovNameservice(uint64(l))
}
return n
}
@@ -2343,7 +2370,7 @@ func (m *Record) Unmarshal(dAtA []byte) error {
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Attributes", wireType)
}
var stringLen uint64
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowNameservice
@@ -2353,23 +2380,27 @@ func (m *Record) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
if msglen < 0 {
return ErrInvalidLengthNameservice
}
postIndex := iNdEx + intStringLen
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthNameservice
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Attributes = string(dAtA[iNdEx:postIndex])
if m.Attributes == nil {
m.Attributes = &types1.Any{}
}
if err := m.Attributes.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 8:
if wireType != 2 {
@@ -2403,6 +2434,38 @@ func (m *Record) Unmarshal(dAtA []byte) error {
}
m.Names = append(m.Names, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
case 9:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowNameservice
}
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 ErrInvalidLengthNameservice
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthNameservice
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Type = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipNameservice(dAtA[iNdEx:])
+99 -9
View File
@@ -2,9 +2,14 @@ package types
import (
"crypto/sha256"
"encoding/json"
"fmt"
"strings"
"github.com/cerc-io/laconicd/x/nameservice/helpers"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
canonicalJson "github.com/gibson042/canonicaljson-go"
"github.com/gogo/protobuf/proto"
)
const (
@@ -21,25 +26,63 @@ type PayloadType struct {
// ToPayload converts PayloadType to Payload object.
// Why? Because go-amino can't handle maps: https://github.com/tendermint/go-amino/issues/4.
func (payloadObj *PayloadType) ToPayload() Payload {
func (payloadObj *PayloadType) ToPayload() (Payload, error) {
attributes, err := payLoadAttributes(payloadObj.Record)
if err != nil {
return Payload{}, err
}
payload := Payload{
Record: &Record{
Deleted: false,
Owners: nil,
Attributes: helpers.BytesToBase64(helpers.MarshalMapToJSONBytes(payloadObj.Record)),
Attributes: attributes,
},
Signatures: payloadObj.Signatures,
}
return payload
return payload, nil
}
func payLoadAttributes(recordPayLoad map[string]interface{}) (*codectypes.Any, error) {
recordType, ok := recordPayLoad["type"]
if !ok {
return &codectypes.Any{}, fmt.Errorf("cannot get type from payload")
}
bz := helpers.MarshalMapToJSONBytes(recordPayLoad)
switch recordType.(string) {
case "ServiceProviderRegistration":
{
var attributes ServiceProviderRegistration
err := json.Unmarshal(bz, &attributes)
if err != nil {
return &codectypes.Any{}, err
}
return codectypes.NewAnyWithValue(&attributes)
}
case "WebsiteRegistrationRecord":
{
var attributes WebsiteRegistrationRecord
err := json.Unmarshal(bz, &attributes)
if err != nil {
return &codectypes.Any{}, err
}
return codectypes.NewAnyWithValue(&attributes)
}
default:
return &codectypes.Any{}, fmt.Errorf("unsupported record type %s", recordType.(string))
}
}
// ToReadablePayload converts Payload to PayloadType
// It will unmarshal with record attributes
func (payload Payload) ToReadablePayload() PayloadType {
var payloadType PayloadType
bz, err := GetJSONBytesFromAny(*payload.Record.Attributes)
if err != nil {
panic(err)
}
payloadType.Record = helpers.UnMarshalMapFromJSONBytes(helpers.BytesFromBase64(payload.Record.Attributes))
payloadType.Record = helpers.UnMarshalMapFromJSONBytes(bz)
payloadType.Signatures = payload.Signatures
return payloadType
@@ -57,11 +100,53 @@ func (r *Record) ToRecordType() RecordType {
resourceObj.Deleted = r.Deleted
resourceObj.Owners = r.Owners
resourceObj.Names = r.Names
resourceObj.Attributes = helpers.UnMarshalMapFromJSONBytes(helpers.BytesFromBase64(r.Attributes))
bz, err := GetJSONBytesFromAny(*r.Attributes)
if err != nil {
panic(err)
}
resourceObj.Attributes = helpers.UnMarshalMapFromJSONBytes(bz)
return resourceObj
}
func GetJSONBytesFromAny(any codectypes.Any) ([]byte, error) {
var bz []byte
s := strings.Split(any.TypeUrl, ".")
switch s[len(s)-1] {
case "ServiceProviderRegistration":
{
var attributes ServiceProviderRegistration
err := proto.Unmarshal(any.Value, &attributes)
if err != nil {
panic("Proto unmarshal error")
}
bz, err = json.Marshal(attributes)
if err != nil {
panic("JSON marshal error")
}
}
case "WebsiteRegistrationRecord":
{
var attributes WebsiteRegistrationRecord
err := proto.Unmarshal(any.Value, &attributes)
if err != nil {
panic("Proto unmarshal error")
}
bz, err = json.Marshal(attributes)
if err != nil {
panic("JSON marshal error")
}
}
default:
return nil, fmt.Errorf("unsupported type %s", s[len(s)-1])
}
return bz, nil
}
// RecordType represents a WNS record.
type RecordType struct {
ID string `json:"id,omitempty"`
@@ -76,7 +161,12 @@ type RecordType struct {
// ToRecordObj converts Record to RecordObj.
// Why? Because go-amino can't handle maps: https://github.com/tendermint/go-amino/issues/4.
func (r *RecordType) ToRecordObj() Record {
func (r *RecordType) ToRecordObj() (Record, error) {
attributes, err := payLoadAttributes(r.Attributes)
if err != nil {
return Record{}, err
}
var resourceObj Record
resourceObj.Id = r.ID
@@ -85,9 +175,9 @@ func (r *RecordType) ToRecordObj() Record {
resourceObj.ExpiryTime = r.ExpiryTime
resourceObj.Deleted = r.Deleted
resourceObj.Owners = r.Owners
resourceObj.Attributes = helpers.BytesToBase64(helpers.MarshalMapToJSONBytes(r.Attributes))
resourceObj.Attributes = attributes
return resourceObj
return resourceObj, nil
}
// CanonicalJSON returns the canonical JSON representation of the record.