From 28f5fa3d861d8113bd6917d3863e9a7421b15463 Mon Sep 17 00:00:00 2001 From: Jaeseung Lee <41176085+tkxkd0159@users.noreply.github.com> Date: Tue, 7 May 2024 20:49:01 +0900 Subject: [PATCH] feat: add role-based access control for bridge (#1350) * add submitting role proposal feature * feat: addVote * feat: role proposal confirmation logic * add gRPC for RBAC * fix checking trustLevel condition * validate role metadata during initialization * add invariants for metadata * delete expired proposal at begin blocker * add memStore and halting feature * remove redundant gRPC queries * fix endblock logic * add Params test * add dummy guardian for testing * remove redundant invariants * set bridge switch at missing parts * add gov authority * add guardian invariant * add single member query * return error if the address has no role * append genesis validation * add CLI * return all registered members if there is no query string * add unit tests for RBAC * merge `halt` with `resume` as `set-bridge-status` * Add CHANGELOG * add ERRORS docs * apply 0tech review * enhance bridge switch unit test * maintain bridge status metadata based on permanent states * change panic msg for unimplemented features * check duplicate seq in genesis * bridge inactive counter must always be initialization * bridge is always inactive if there is no guardian * start fbridge module after auth/bank * remove redundant invariant checking --- CHANGELOG.md | 1 + client/docs/config.json | 9 +- client/docs/swagger-ui/swagger.yaml | 992 ++++++++---- docs/core/proto-docs.md | 520 +++++-- proto/lbm/fbridge/v1/event.proto | 16 + proto/lbm/fbridge/v1/fbridge.proto | 69 +- proto/lbm/fbridge/v1/genesis.proto | 16 + proto/lbm/fbridge/v1/query.proto | 96 +- proto/lbm/fbridge/v1/tx.proto | 26 +- simapp/app.go | 6 +- x/ERRORS.md | 12 + x/fbridge/client/cli/query.go | 234 ++- x/fbridge/client/cli/tx.go | 130 +- x/fbridge/keeper/abci.go | 65 + x/fbridge/keeper/auth.go | 331 ++++ x/fbridge/keeper/auth_test.go | 89 ++ x/fbridge/keeper/genesis.go | 58 + x/fbridge/keeper/grpc_query.go | 137 +- x/fbridge/keeper/keeper.go | 122 +- x/fbridge/keeper/msg_server.go | 87 +- x/fbridge/keeper/params.go | 24 + x/fbridge/keeper/transfer_test.go | 7 +- x/fbridge/module/module.go | 24 +- x/fbridge/testutil/setup.go | 18 +- x/fbridge/types/codec.go | 6 +- x/fbridge/types/errors.go | 9 + x/fbridge/types/event.pb.go | 468 +++++- x/fbridge/types/fbridge.go | 39 + x/fbridge/types/fbridge.pb.go | 1145 ++++++++++++-- x/fbridge/types/genesis.go | 88 +- x/fbridge/types/genesis.pb.go | 589 +++++++- x/fbridge/types/keys.go | 88 +- x/fbridge/types/msgs.go | 19 +- x/fbridge/types/params.go | 64 + x/fbridge/types/params_test.go | 62 + x/fbridge/types/query.pb.go | 2161 +++++++++++++++++++-------- x/fbridge/types/query.pb.gw.go | 402 ++++- x/fbridge/types/tx.pb.go | 579 ++----- 38 files changed, 6931 insertions(+), 1877 deletions(-) create mode 100644 x/fbridge/keeper/abci.go create mode 100644 x/fbridge/keeper/auth.go create mode 100644 x/fbridge/keeper/auth_test.go create mode 100644 x/fbridge/keeper/params.go create mode 100644 x/fbridge/types/errors.go create mode 100644 x/fbridge/types/fbridge.go create mode 100644 x/fbridge/types/params_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e2c15134a..317a2b61fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/fbridge) [\#1347](https://github.com/Finschia/finschia-sdk/pull/1347) Implement bridge transfer feature (sending side) * (x/fbridge) [\#1351](https://github.com/Finschia/finschia-sdk/pull/1351) Map a sequence to block number for every bridge request (sending side) * (x/fswap) [\#1345](https://github.com/Finschia/finschia-sdk/pull/1345) Implement fswap's basic functionality(MsgSwap, MsgSwapAll, Query, Proposal) +* (x/fbridge) [\#1350](https://github.com/Finschia/finschia-sdk/pull/1350) Add Role-based Access Control ### Improvements * (docs) [\#1120](https://github.com/Finschia/finschia-sdk/pull/1120) Update links in x/foundation README.md diff --git a/client/docs/config.json b/client/docs/config.json index 4a1968c6ee..6670e56370 100644 --- a/client/docs/config.json +++ b/client/docs/config.json @@ -171,11 +171,12 @@ "rename": { "Params": "FBridgeParams", "Commitments": "FBridgeCommitments", - "Guardians": "FBridgeGuardians", - "Operators": "FBridgeOperators", - "Judges": "FBridgeJudges", + "Members": "FBridgeMembers", + "Member": "FBridgeMember", "Proposals": "FBridgeProposals", - "Proposal": "FBridgeProposal" + "Proposal": "FBridgeProposal", + "Votes": "FBridgeVotes", + "Vote": "FBridgeVote" } } } diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 30b1c66412..de9fab3eff 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -29799,17 +29799,17 @@ paths: format: byte tags: - Service - /lbm/fbridge/v1/guardians: + /lbm/fbridge/v1/members: get: - summary: Guardians queries a list of Guardians registered on the bridge - operationId: FBridgeGuardians + summary: Members queries the members of spcific group registered on the bridge + operationId: FBridgeMembers responses: '200': description: A successful response. schema: type: object properties: - guardians: + members: type: array items: type: string @@ -29835,60 +29835,26 @@ paths: value: type: string format: byte + parameters: + - name: role + description: 'the role name (guardian, operator, judge).' + in: query + required: false + type: string tags: - Query - /lbm/fbridge/v1/judges: + '/lbm/fbridge/v1/members/{address}': get: - summary: Judges queries a list of Judges registered on the bridge - operationId: FBridgeJudges + summary: Member queries the role of a specific member + operationId: FBridgeMember responses: '200': description: A successful response. schema: type: object properties: - judges: - type: array - items: - type: string - default: - description: An unexpected error response - schema: - type: object - properties: - error: - type: string - code: - type: integer - format: int32 - message: + role: type: string - details: - type: array - items: - type: object - properties: - type_url: - type: string - value: - type: string - format: byte - tags: - - Query - /lbm/fbridge/v1/operators: - get: - summary: Operators queries a list of Operators registered on the bridge - operationId: FBridgeOperators - responses: - '200': - description: A successful response. - schema: - type: object - properties: - operators: - type: array - items: - type: string default: description: An unexpected error response schema: @@ -29911,6 +29877,11 @@ paths: value: type: string format: byte + parameters: + - name: address + in: path + required: true + type: string tags: - Query /lbm/fbridge/v1/params: @@ -29996,6 +29967,371 @@ paths: format: byte tags: - Query + /lbm/fbridge/v1/proposals: + get: + summary: Proposals queries a list of SuggestRole Proposals + operationId: FBridgeProposals + responses: + '200': + description: A successful response. + schema: + type: object + properties: + proposals: + type: array + items: + type: object + properties: + id: + type: string + format: uint64 + proposer: + type: string + title: the proposer address + target: + type: string + title: the address to update the role + role: + title: >- + the role to be updated + + - unspecified : 0, used to remove the address from a + group + + - guardian : 1 + + - operator : 2 + + - judge : 3 + type: string + enum: + - UNSPECIFIED + - GUARDIAN + - OPERATOR + - JUDGE + default: UNSPECIFIED + description: >- + Role defines the role of the operator, guardian, and + judge. + expired_at: + type: string + format: date-time + title: >- + the unix timestamp the proposal will be expired (unix + timestamp) + pagination: + description: pagination defines an pagination for the response. + type: object + properties: + next_key: + type: string + format: byte + title: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total + + was set, its value is undefined otherwise + default: + description: An unexpected error response + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: pagination.key + description: |- + key is a value returned in PageResponse.next_key to begin + querying the next page most efficiently. Only one of offset or key + should be set. + in: query + required: false + type: string + format: byte + - name: pagination.offset + description: >- + offset is a numeric offset that can be used when key is unavailable. + + It is less efficient than using key. Only one of offset or key + should + + be set. + in: query + required: false + type: string + format: uint64 + - name: pagination.limit + description: >- + limit is the total number of results to be returned in the result + page. + + If left empty it will default to a value to be set by each app. + in: query + required: false + type: string + format: uint64 + - name: pagination.count_total + description: >- + count_total is set to true to indicate that the result set should + include + + a count of the total number of items available for pagination in + UIs. + + count_total is only respected when offset is used. It is ignored + when key + + is set. + in: query + required: false + type: boolean + format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean + format: boolean + tags: + - Query + '/lbm/fbridge/v1/proposals/{proposal_id}': + get: + summary: Proposal queries a SuggestRole Proposal + operationId: FBridgeProposal + responses: + '200': + description: A successful response. + schema: + type: object + properties: + proposal: + type: object + properties: + id: + type: string + format: uint64 + proposer: + type: string + title: the proposer address + target: + type: string + title: the address to update the role + role: + title: |- + the role to be updated + - unspecified : 0, used to remove the address from a group + - guardian : 1 + - operator : 2 + - judge : 3 + type: string + enum: + - UNSPECIFIED + - GUARDIAN + - OPERATOR + - JUDGE + default: UNSPECIFIED + description: >- + Role defines the role of the operator, guardian, and + judge. + expired_at: + type: string + format: date-time + title: >- + the unix timestamp the proposal will be expired (unix + timestamp) + default: + description: An unexpected error response + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: proposal_id + description: the proposal id + in: path + required: true + type: string + format: uint64 + tags: + - Query + '/lbm/fbridge/v1/proposals/{proposal_id}/votes': + get: + summary: Votes queries votes of a given proposal. + operationId: FBridgeVotes + responses: + '200': + description: A successful response. + schema: + type: object + properties: + votes: + type: array + items: + type: object + properties: + proposal_id: + type: string + format: uint64 + voter: + type: string + option: + type: string + enum: + - VOTE_OPTION_UNSPECIFIED + - VOTE_OPTION_YES + - VOTE_OPTION_NO + default: VOTE_OPTION_UNSPECIFIED + description: >- + VoteOption enumerates the valid vote options for a given + role proposal. + + - VOTE_OPTION_UNSPECIFIED: VOTE_OPTION_UNSPECIFIED defines a no-op vote option. + - VOTE_OPTION_YES: VOTE_OPTION_YES defines a yes vote option. + - VOTE_OPTION_NO: VOTE_OPTION_NO defines a no vote option. + description: Vote defines a vote on a role proposal. + description: votes defined the queried votes. + default: + description: An unexpected error response + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: proposal_id + description: proposal_id defines the unique id of the proposal. + in: path + required: true + type: string + format: uint64 + tags: + - Query + '/lbm/fbridge/v1/proposals/{proposal_id}/votes/{voter}': + get: + summary: 'Vote queries voted information based on proposalID, voterAddr.' + operationId: FBridgeVote + responses: + '200': + description: A successful response. + schema: + type: object + properties: + vote: + type: object + properties: + proposal_id: + type: string + format: uint64 + voter: + type: string + option: + type: string + enum: + - VOTE_OPTION_UNSPECIFIED + - VOTE_OPTION_YES + - VOTE_OPTION_NO + default: VOTE_OPTION_UNSPECIFIED + description: >- + VoteOption enumerates the valid vote options for a given + role proposal. + + - VOTE_OPTION_UNSPECIFIED: VOTE_OPTION_UNSPECIFIED defines a no-op vote option. + - VOTE_OPTION_YES: VOTE_OPTION_YES defines a yes vote option. + - VOTE_OPTION_NO: VOTE_OPTION_NO defines a no vote option. + description: Vote defines a vote on a role proposal. + default: + description: An unexpected error response + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: proposal_id + description: proposal_id defines the unique id of the proposal. + in: path + required: true + type: string + format: uint64 + - name: voter + description: voter defines the oter address for the proposals. + in: path + required: true + type: string + tags: + - Query '/lbm/fbridge/v1/receiving/commitments/{seq}': get: summary: Commitments queries commitments of a specific sequence number @@ -30258,287 +30594,76 @@ paths: format: int32 message: type: string - details: - type: array - items: - type: object - properties: - type_url: - type: string - value: - type: string - format: byte - parameters: - - name: operator - description: the address of the operator - in: path - required: true - type: string - tags: - - Query - '/lbm/fbridge/v1/receiving/provision/{seq}': - get: - summary: ConfirmedProvision queries a particular sequence of confirmed provisions - operationId: ConfirmedProvision - responses: - '200': - description: A successful response. - schema: - type: object - properties: - data: - type: object - properties: - seq: - type: string - format: uint64 - title: the sequence number of the bridge request - amount: - type: string - title: the amount of token to be claimed - sender: - type: string - title: the sender address on the source chain - receiver: - type: string - title: the recipient address on the destination chain - description: Provision is a struct that represents a provision internally. - status: - type: object - properties: - timelock_end: - type: string - format: uint64 - title: >- - the unix timestamp the provision will be able to be - claimed (unix timestamp) - confirm_counts: - type: integer - format: int32 - title: >- - a value that tells how many operators have submitted this - provision - is_claimed: - type: boolean - format: boolean - title: whether the provision has been claimed - description: >- - ProvisionStatus is a struct that represents the status of a - provision. - - To optimize computational cost, we have collected frequently - changing values from provision. - default: - description: An unexpected error response - schema: - type: object - properties: - error: - type: string - code: - type: integer - format: int32 - message: - type: string - details: - type: array - items: - type: object - properties: - type_url: - type: string - value: - type: string - format: byte - parameters: - - name: seq - description: the sequence number of the bridge request - in: path - required: true - type: string - format: uint64 - tags: - - Query - /lbm/fbridge/v1/role/proposals: - get: - summary: Proposals queries a list of SuggestRole Proposals - operationId: FBridgeProposals - responses: - '200': - description: A successful response. - schema: - type: object - properties: - proposals: - type: array - items: - type: object - properties: - id: - type: string - format: uint64 - proposer: - type: string - title: the proposer address - target: - type: string - title: the address to update the role - role: - title: >- - the role to be updated - - - unspecified : 0, used to remove the address from a - group - - - guardian : 1 - - - operator : 2 - - - judge : 3 - type: string - enum: - - UNSPECIFIED - - GUARDIAN - - OPERATOR - - JUDGE - default: UNSPECIFIED - description: >- - Role defines the role of the operator, guardian, and - judge. - expired_at: - type: string - format: uint64 - title: >- - the unix timestamp the proposal will be expired (unix - timestamp) - default: - description: An unexpected error response - schema: - type: object - properties: - error: - type: string - code: - type: integer - format: int32 - message: - type: string - details: - type: array - items: - type: object - properties: - type_url: - type: string - value: - type: string - format: byte - parameters: - - name: pagination.key - description: |- - key is a value returned in PageResponse.next_key to begin - querying the next page most efficiently. Only one of offset or key - should be set. - in: query - required: false - type: string - format: byte - - name: pagination.offset - description: >- - offset is a numeric offset that can be used when key is unavailable. - - It is less efficient than using key. Only one of offset or key - should - - be set. - in: query - required: false - type: string - format: uint64 - - name: pagination.limit - description: >- - limit is the total number of results to be returned in the result - page. - - If left empty it will default to a value to be set by each app. - in: query - required: false - type: string - format: uint64 - - name: pagination.count_total - description: >- - count_total is set to true to indicate that the result set should - include - - a count of the total number of items available for pagination in - UIs. - - count_total is only respected when offset is used. It is ignored - when key - - is set. - in: query - required: false - type: boolean - format: boolean - - name: pagination.reverse - description: >- - reverse is set to true if results are to be returned in the - descending order. - - - Since: cosmos-sdk 0.43 - in: query - required: false - type: boolean - format: boolean + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: operator + description: the address of the operator + in: path + required: true + type: string tags: - Query - '/lbm/fbridge/v1/role/proposals/{proposal_id}': + '/lbm/fbridge/v1/receiving/provision/{seq}': get: - summary: Proposal queries a SuggestRole Proposal - operationId: FBridgeProposal + summary: ConfirmedProvision queries a particular sequence of confirmed provisions + operationId: ConfirmedProvision responses: '200': description: A successful response. schema: type: object properties: - proposal: + data: type: object properties: - id: + seq: type: string format: uint64 - proposer: + title: the sequence number of the bridge request + amount: type: string - title: the proposer address - target: + title: the amount of token to be claimed + sender: type: string - title: the address to update the role - role: - title: |- - the role to be updated - - unspecified : 0, used to remove the address from a group - - guardian : 1 - - operator : 2 - - judge : 3 + title: the sender address on the source chain + receiver: type: string - enum: - - UNSPECIFIED - - GUARDIAN - - OPERATOR - - JUDGE - default: UNSPECIFIED - description: >- - Role defines the role of the operator, guardian, and - judge. - expired_at: + title: the recipient address on the destination chain + description: Provision is a struct that represents a provision internally. + status: + type: object + properties: + timelock_end: type: string format: uint64 title: >- - the unix timestamp the proposal will be expired (unix - timestamp) + the unix timestamp the provision will be able to be + claimed (unix timestamp) + confirm_counts: + type: integer + format: int32 + title: >- + a value that tells how many operators have submitted this + provision + is_claimed: + type: boolean + format: boolean + title: whether the provision has been claimed + description: >- + ProvisionStatus is a struct that represents the status of a + provision. + + To optimize computational cost, we have collected frequently + changing values from provision. default: description: An unexpected error response schema: @@ -30562,11 +30687,12 @@ paths: type: string format: byte parameters: - - name: proposal_id - description: the proposal id + - name: seq + description: the sequence number of the bridge request in: path required: true type: string + format: uint64 tags: - Query /lbm/fbridge/v1/sending/blocknums: @@ -30657,6 +30783,65 @@ paths: format: byte tags: - Query + /lbm/fbridge/v1/status: + get: + summary: BridgeStatus queries the status of the bridge + operationId: BridgeStatus + responses: + '200': + description: A successful response. + schema: + type: object + properties: + status: + type: string + enum: + - BRIDGE_STATUS_UNSPECIFIED + - BRIDGE_STATUS_ACTIVE + - BRIDGE_STATUS_INACTIVE + default: BRIDGE_STATUS_UNSPECIFIED + description: |2- + - BRIDGE_STATUS_UNSPECIFIED: BRIDGE_STATUS_UNSPECIFIED defines an unspecified bridge status. + - BRIDGE_STATUS_ACTIVE: BRIDGE_STATUS_ACTIVE defines an active bridge status. + - BRIDGE_STATUS_INACTIVE: BRIDGE_STATUS_INACTIVE defines an inactive bridge status. + metadata: + type: object + properties: + inactive: + type: string + format: uint64 + title: the number of inactived bridge switch + active: + type: string + format: uint64 + title: the number of activated bridge switch + description: >- + BridgeStatusMetadata defines the metadata of the bridge + status. + default: + description: An unexpected error response + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + tags: + - Query definitions: cosmos.auth.v1beta1.Params: type: object @@ -50202,6 +50387,29 @@ definitions: minimum_gas_price: type: string description: ConfigResponse defines the response structure for the Config gRPC query. + lbm.fbridge.v1.BridgeStatus: + type: string + enum: + - BRIDGE_STATUS_UNSPECIFIED + - BRIDGE_STATUS_ACTIVE + - BRIDGE_STATUS_INACTIVE + default: BRIDGE_STATUS_UNSPECIFIED + description: |2- + - BRIDGE_STATUS_UNSPECIFIED: BRIDGE_STATUS_UNSPECIFIED defines an unspecified bridge status. + - BRIDGE_STATUS_ACTIVE: BRIDGE_STATUS_ACTIVE defines an active bridge status. + - BRIDGE_STATUS_INACTIVE: BRIDGE_STATUS_INACTIVE defines an inactive bridge status. + lbm.fbridge.v1.BridgeStatusMetadata: + type: object + properties: + inactive: + type: string + format: uint64 + title: the number of inactived bridge switch + active: + type: string + format: uint64 + title: the number of activated bridge switch + description: BridgeStatusMetadata defines the metadata of the bridge status. lbm.fbridge.v1.Fraction: type: object properties: @@ -50294,6 +50502,32 @@ definitions: To optimize computational cost, we have collected frequently changing values from provision. + lbm.fbridge.v1.QueryBridgeStatusResponse: + type: object + properties: + status: + type: string + enum: + - BRIDGE_STATUS_UNSPECIFIED + - BRIDGE_STATUS_ACTIVE + - BRIDGE_STATUS_INACTIVE + default: BRIDGE_STATUS_UNSPECIFIED + description: |2- + - BRIDGE_STATUS_UNSPECIFIED: BRIDGE_STATUS_UNSPECIFIED defines an unspecified bridge status. + - BRIDGE_STATUS_ACTIVE: BRIDGE_STATUS_ACTIVE defines an active bridge status. + - BRIDGE_STATUS_INACTIVE: BRIDGE_STATUS_INACTIVE defines an inactive bridge status. + metadata: + type: object + properties: + inactive: + type: string + format: uint64 + title: the number of inactived bridge switch + active: + type: string + format: uint64 + title: the number of activated bridge switch + description: BridgeStatusMetadata defines the metadata of the bridge status. lbm.fbridge.v1.QueryCommitmentsResponse: type: object properties: @@ -50357,17 +50591,15 @@ definitions: seq: type: string format: uint64 - lbm.fbridge.v1.QueryGuardiansResponse: + lbm.fbridge.v1.QueryMemberResponse: type: object properties: - guardians: - type: array - items: - type: string - lbm.fbridge.v1.QueryJudgesResponse: + role: + type: string + lbm.fbridge.v1.QueryMembersResponse: type: object properties: - judges: + members: type: array items: type: string @@ -50385,13 +50617,6 @@ definitions: seq: type: string format: uint64 - lbm.fbridge.v1.QueryOperatorsResponse: - type: object - properties: - operators: - type: array - items: - type: string lbm.fbridge.v1.QueryParamsResponse: type: object properties: @@ -50468,7 +50693,7 @@ definitions: description: 'Role defines the role of the operator, guardian, and judge.' expired_at: type: string - format: uint64 + format: date-time title: the unix timestamp the proposal will be expired (unix timestamp) lbm.fbridge.v1.QueryProposalsResponse: type: object @@ -50504,8 +50729,26 @@ definitions: description: 'Role defines the role of the operator, guardian, and judge.' expired_at: type: string - format: uint64 + format: date-time title: the unix timestamp the proposal will be expired (unix timestamp) + pagination: + description: pagination defines an pagination for the response. + type: object + properties: + next_key: + type: string + format: byte + title: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total + + was set, its value is undefined otherwise lbm.fbridge.v1.QuerySeqToBlocknumsResponse: type: object properties: @@ -50558,6 +50801,61 @@ definitions: To optimize computational cost, we have collected frequently changing values from provision. + lbm.fbridge.v1.QueryVoteResponse: + type: object + properties: + vote: + type: object + properties: + proposal_id: + type: string + format: uint64 + voter: + type: string + option: + type: string + enum: + - VOTE_OPTION_UNSPECIFIED + - VOTE_OPTION_YES + - VOTE_OPTION_NO + default: VOTE_OPTION_UNSPECIFIED + description: >- + VoteOption enumerates the valid vote options for a given role + proposal. + + - VOTE_OPTION_UNSPECIFIED: VOTE_OPTION_UNSPECIFIED defines a no-op vote option. + - VOTE_OPTION_YES: VOTE_OPTION_YES defines a yes vote option. + - VOTE_OPTION_NO: VOTE_OPTION_NO defines a no vote option. + description: Vote defines a vote on a role proposal. + lbm.fbridge.v1.QueryVotesResponse: + type: object + properties: + votes: + type: array + items: + type: object + properties: + proposal_id: + type: string + format: uint64 + voter: + type: string + option: + type: string + enum: + - VOTE_OPTION_UNSPECIFIED + - VOTE_OPTION_YES + - VOTE_OPTION_NO + default: VOTE_OPTION_UNSPECIFIED + description: >- + VoteOption enumerates the valid vote options for a given role + proposal. + + - VOTE_OPTION_UNSPECIFIED: VOTE_OPTION_UNSPECIFIED defines a no-op vote option. + - VOTE_OPTION_YES: VOTE_OPTION_YES defines a yes vote option. + - VOTE_OPTION_NO: VOTE_OPTION_NO defines a no vote option. + description: Vote defines a vote on a role proposal. + description: votes defined the queried votes. lbm.fbridge.v1.Role: type: string enum: @@ -50596,5 +50894,41 @@ definitions: description: 'Role defines the role of the operator, guardian, and judge.' expired_at: type: string - format: uint64 + format: date-time title: the unix timestamp the proposal will be expired (unix timestamp) + lbm.fbridge.v1.Vote: + type: object + properties: + proposal_id: + type: string + format: uint64 + voter: + type: string + option: + type: string + enum: + - VOTE_OPTION_UNSPECIFIED + - VOTE_OPTION_YES + - VOTE_OPTION_NO + default: VOTE_OPTION_UNSPECIFIED + description: >- + VoteOption enumerates the valid vote options for a given role + proposal. + + - VOTE_OPTION_UNSPECIFIED: VOTE_OPTION_UNSPECIFIED defines a no-op vote option. + - VOTE_OPTION_YES: VOTE_OPTION_YES defines a yes vote option. + - VOTE_OPTION_NO: VOTE_OPTION_NO defines a no vote option. + description: Vote defines a vote on a role proposal. + lbm.fbridge.v1.VoteOption: + type: string + enum: + - VOTE_OPTION_UNSPECIFIED + - VOTE_OPTION_YES + - VOTE_OPTION_NO + default: VOTE_OPTION_UNSPECIFIED + description: |- + VoteOption enumerates the valid vote options for a given role proposal. + + - VOTE_OPTION_UNSPECIFIED: VOTE_OPTION_UNSPECIFIED defines a no-op vote option. + - VOTE_OPTION_YES: VOTE_OPTION_YES defines a yes vote option. + - VOTE_OPTION_NO: VOTE_OPTION_NO defines a no vote option. diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index 56d2cf5fd1..379b2d65ea 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -754,23 +754,32 @@ - [Msg](#lbm.collection.v1.Msg) -- [lbm/fbridge/v1/event.proto](#lbm/fbridge/v1/event.proto) - - [EventClaim](#lbm.fbridge.v1.EventClaim) - - [EventConfirmProvision](#lbm.fbridge.v1.EventConfirmProvision) - - [EventProvision](#lbm.fbridge.v1.EventProvision) - - [EventTransfer](#lbm.fbridge.v1.EventTransfer) - - [lbm/fbridge/v1/fbridge.proto](#lbm/fbridge/v1/fbridge.proto) + - [BridgeStatusMetadata](#lbm.fbridge.v1.BridgeStatusMetadata) - [Fraction](#lbm.fbridge.v1.Fraction) - [Params](#lbm.fbridge.v1.Params) - [ProvisionData](#lbm.fbridge.v1.ProvisionData) - [ProvisionStatus](#lbm.fbridge.v1.ProvisionStatus) + - [RoleMetadata](#lbm.fbridge.v1.RoleMetadata) + - [RolePair](#lbm.fbridge.v1.RolePair) - [RoleProposal](#lbm.fbridge.v1.RoleProposal) + - [Vote](#lbm.fbridge.v1.Vote) + - [BridgeStatus](#lbm.fbridge.v1.BridgeStatus) - [Role](#lbm.fbridge.v1.Role) + - [VoteOption](#lbm.fbridge.v1.VoteOption) + +- [lbm/fbridge/v1/event.proto](#lbm/fbridge/v1/event.proto) + - [EventAddVoteForRole](#lbm.fbridge.v1.EventAddVoteForRole) + - [EventClaim](#lbm.fbridge.v1.EventClaim) + - [EventConfirmProvision](#lbm.fbridge.v1.EventConfirmProvision) + - [EventProvision](#lbm.fbridge.v1.EventProvision) + - [EventSuggestRole](#lbm.fbridge.v1.EventSuggestRole) + - [EventTransfer](#lbm.fbridge.v1.EventTransfer) - [lbm/fbridge/v1/genesis.proto](#lbm/fbridge/v1/genesis.proto) - [BlockSeqInfo](#lbm.fbridge.v1.BlockSeqInfo) + - [BridgeSwitch](#lbm.fbridge.v1.BridgeSwitch) - [Commitment](#lbm.fbridge.v1.Commitment) - [ConfirmedProvision](#lbm.fbridge.v1.ConfirmedProvision) - [GenesisState](#lbm.fbridge.v1.GenesisState) @@ -780,6 +789,8 @@ - [SendingState](#lbm.fbridge.v1.SendingState) - [lbm/fbridge/v1/query.proto](#lbm/fbridge/v1/query.proto) + - [QueryBridgeStatusRequest](#lbm.fbridge.v1.QueryBridgeStatusRequest) + - [QueryBridgeStatusResponse](#lbm.fbridge.v1.QueryBridgeStatusResponse) - [QueryCommitmentsRequest](#lbm.fbridge.v1.QueryCommitmentsRequest) - [QueryCommitmentsResponse](#lbm.fbridge.v1.QueryCommitmentsResponse) - [QueryConfirmedProvisionRequest](#lbm.fbridge.v1.QueryConfirmedProvisionRequest) @@ -788,16 +799,14 @@ - [QueryGreatestConsecutiveConfirmedSeqResponse](#lbm.fbridge.v1.QueryGreatestConsecutiveConfirmedSeqResponse) - [QueryGreatestSeqByOperatorRequest](#lbm.fbridge.v1.QueryGreatestSeqByOperatorRequest) - [QueryGreatestSeqByOperatorResponse](#lbm.fbridge.v1.QueryGreatestSeqByOperatorResponse) - - [QueryGuardiansRequest](#lbm.fbridge.v1.QueryGuardiansRequest) - - [QueryGuardiansResponse](#lbm.fbridge.v1.QueryGuardiansResponse) - - [QueryJudgesRequest](#lbm.fbridge.v1.QueryJudgesRequest) - - [QueryJudgesResponse](#lbm.fbridge.v1.QueryJudgesResponse) + - [QueryMemberRequest](#lbm.fbridge.v1.QueryMemberRequest) + - [QueryMemberResponse](#lbm.fbridge.v1.QueryMemberResponse) + - [QueryMembersRequest](#lbm.fbridge.v1.QueryMembersRequest) + - [QueryMembersResponse](#lbm.fbridge.v1.QueryMembersResponse) - [QueryNeededSubmissionSeqsRequest](#lbm.fbridge.v1.QueryNeededSubmissionSeqsRequest) - [QueryNeededSubmissionSeqsResponse](#lbm.fbridge.v1.QueryNeededSubmissionSeqsResponse) - [QueryNextSeqSendRequest](#lbm.fbridge.v1.QueryNextSeqSendRequest) - [QueryNextSeqSendResponse](#lbm.fbridge.v1.QueryNextSeqSendResponse) - - [QueryOperatorsRequest](#lbm.fbridge.v1.QueryOperatorsRequest) - - [QueryOperatorsResponse](#lbm.fbridge.v1.QueryOperatorsResponse) - [QueryParamsRequest](#lbm.fbridge.v1.QueryParamsRequest) - [QueryParamsResponse](#lbm.fbridge.v1.QueryParamsResponse) - [QueryProposalRequest](#lbm.fbridge.v1.QueryProposalRequest) @@ -808,6 +817,10 @@ - [QuerySeqToBlocknumsResponse](#lbm.fbridge.v1.QuerySeqToBlocknumsResponse) - [QuerySubmittedProvisionRequest](#lbm.fbridge.v1.QuerySubmittedProvisionRequest) - [QuerySubmittedProvisionResponse](#lbm.fbridge.v1.QuerySubmittedProvisionResponse) + - [QueryVoteRequest](#lbm.fbridge.v1.QueryVoteRequest) + - [QueryVoteResponse](#lbm.fbridge.v1.QueryVoteResponse) + - [QueryVotesRequest](#lbm.fbridge.v1.QueryVotesRequest) + - [QueryVotesResponse](#lbm.fbridge.v1.QueryVotesResponse) - [Query](#lbm.fbridge.v1.Query) @@ -818,8 +831,6 @@ - [MsgClaimBatch](#lbm.fbridge.v1.MsgClaimBatch) - [MsgClaimBatchResponse](#lbm.fbridge.v1.MsgClaimBatchResponse) - [MsgClaimResponse](#lbm.fbridge.v1.MsgClaimResponse) - - [MsgHalt](#lbm.fbridge.v1.MsgHalt) - - [MsgHaltResponse](#lbm.fbridge.v1.MsgHaltResponse) - [MsgHoldTransfer](#lbm.fbridge.v1.MsgHoldTransfer) - [MsgHoldTransferResponse](#lbm.fbridge.v1.MsgHoldTransferResponse) - [MsgProvision](#lbm.fbridge.v1.MsgProvision) @@ -828,8 +839,8 @@ - [MsgReleaseTransferResponse](#lbm.fbridge.v1.MsgReleaseTransferResponse) - [MsgRemoveProvision](#lbm.fbridge.v1.MsgRemoveProvision) - [MsgRemoveProvisionResponse](#lbm.fbridge.v1.MsgRemoveProvisionResponse) - - [MsgResume](#lbm.fbridge.v1.MsgResume) - - [MsgResumeResponse](#lbm.fbridge.v1.MsgResumeResponse) + - [MsgSetBridgeStatus](#lbm.fbridge.v1.MsgSetBridgeStatus) + - [MsgSetBridgeStatusResponse](#lbm.fbridge.v1.MsgSetBridgeStatusResponse) - [MsgSuggestRole](#lbm.fbridge.v1.MsgSuggestRole) - [MsgSuggestRoleResponse](#lbm.fbridge.v1.MsgSuggestRoleResponse) - [MsgTransfer](#lbm.fbridge.v1.MsgTransfer) @@ -11385,77 +11396,164 @@ Msg defines the collection Msg service. - +
-## lbm/fbridge/v1/event.proto +## lbm/fbridge/v1/fbridge.proto - + -### EventClaim +### BridgeStatusMetadata +BridgeStatusMetadata defines the metadata of the bridge status. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `inactive` | [uint64](#uint64) | | the number of inactived bridge switch | +| `active` | [uint64](#uint64) | | the number of activated bridge switch | + + + + + + + + +### Fraction +Fraction defines the protobuf message type for tmmath.Fraction that only +supports positive values. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `numerator` | [uint64](#uint64) | | | +| `denominator` | [uint64](#uint64) | | | + + + + + + + + +### Params +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `operator_trust_level` | [Fraction](#lbm.fbridge.v1.Fraction) | | ratio of how many operators' confirmations are needed to be valid. | +| `guardian_trust_level` | [Fraction](#lbm.fbridge.v1.Fraction) | | ratio of how many guardians' confirmations are needed to be valid. | +| `judge_trust_level` | [Fraction](#lbm.fbridge.v1.Fraction) | | ratio of how many judges' confirmations are needed to be valid. | +| `timelock_period` | [uint64](#uint64) | | default timelock period for each provision (unix timestamp) | +| `proposal_period` | [uint64](#uint64) | | default period of the proposal to update the role | + + + + + + + + +### ProvisionData +Provision is a struct that represents a provision internally. + + | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | `seq` | [uint64](#uint64) | | the sequence number of the bridge request | +| `amount` | [string](#string) | | the amount of token to be claimed | | `sender` | [string](#string) | | the sender address on the source chain | | `receiver` | [string](#string) | | the recipient address on the destination chain | -| `amount` | [string](#string) | | the amount of token to be claimed | - + + +### ProvisionStatus +ProvisionStatus is a struct that represents the status of a provision. +To optimize computational cost, we have collected frequently changing values from provision. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `timelock_end` | [uint64](#uint64) | | the unix timestamp the provision will be able to be claimed (unix timestamp) | +| `confirm_counts` | [int32](#int32) | | a value that tells how many operators have submitted this provision | +| `is_claimed` | [bool](#bool) | | whether the provision has been claimed | + -### EventConfirmProvision + + + +### RoleMetadata +RoleMetadata defines the metadata of the role. + + | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `seq` | [uint64](#uint64) | | the sequence number of the bridge request | +| `guardian` | [uint64](#uint64) | | the number of registered guardians | +| `operator` | [uint64](#uint64) | | the number of the operators | +| `judge` | [uint64](#uint64) | | the number of the judges | - + -### EventProvision +### RolePair | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `seq` | [uint64](#uint64) | | the sequence number of the bridge request | -| `sender` | [string](#string) | | the sender address on the source chain | -| `receiver` | [string](#string) | | the recipient address on the destination chain | -| `amount` | [string](#string) | | the amount of token to be claimed | -| `operator` | [string](#string) | | the address of the operator | +| `address` | [string](#string) | | | +| `role` | [Role](#lbm.fbridge.v1.Role) | | | - + -### EventTransfer +### RoleProposal | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `seq` | [uint64](#uint64) | | the sequence number of the bridge request | -| `sender` | [string](#string) | | the sender address on the source chain | -| `receiver` | [string](#string) | | the recipient address on the destination chain | -| `amount` | [string](#string) | | the amount of token to be transferred | +| `id` | [uint64](#uint64) | | | +| `proposer` | [string](#string) | | the proposer address | +| `target` | [string](#string) | | the address to update the role | +| `role` | [Role](#lbm.fbridge.v1.Role) | | the role to be updated - unspecified : 0, used to remove the address from a group - guardian : 1 - operator : 2 - judge : 3 | +| `expired_at` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | the unix timestamp the proposal will be expired (unix timestamp) | + + + + + + + + +### Vote +Vote defines a vote on a role proposal. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `proposal_id` | [uint64](#uint64) | | | +| `voter` | [string](#string) | | | +| `option` | [VoteOption](#lbm.fbridge.v1.VoteOption) | | | @@ -11463,6 +11561,46 @@ Msg defines the collection Msg service. + + + +### BridgeStatus + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| BRIDGE_STATUS_UNSPECIFIED | 0 | BRIDGE_STATUS_UNSPECIFIED defines an unspecified bridge status. | +| BRIDGE_STATUS_ACTIVE | 1 | BRIDGE_STATUS_ACTIVE defines an active bridge status. | +| BRIDGE_STATUS_INACTIVE | 2 | BRIDGE_STATUS_INACTIVE defines an inactive bridge status. | + + + + + +### Role +Role defines the role of the operator, guardian, and judge. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| UNSPECIFIED | 0 | | +| GUARDIAN | 1 | | +| OPERATOR | 2 | | +| JUDGE | 3 | | + + + + + +### VoteOption +VoteOption enumerates the valid vote options for a given role proposal. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| VOTE_OPTION_UNSPECIFIED | 0 | VOTE_OPTION_UNSPECIFIED defines a no-op vote option. | +| VOTE_OPTION_YES | 1 | VOTE_OPTION_YES defines a yes vote option. | +| VOTE_OPTION_NO | 2 | VOTE_OPTION_NO defines a no vote option. | + + @@ -11471,119 +11609,116 @@ Msg defines the collection Msg service. - + -## lbm/fbridge/v1/fbridge.proto +## lbm/fbridge/v1/event.proto - + + +### EventAddVoteForRole -### Fraction -Fraction defines the protobuf message type for tmmath.Fraction that only -supports positive values. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `numerator` | [uint64](#uint64) | | | -| `denominator` | [uint64](#uint64) | | | +| `voter` | [string](#string) | | the voter address | +| `proposal_id` | [uint64](#uint64) | | the role proposal id | +| `option` | [VoteOption](#lbm.fbridge.v1.VoteOption) | | the vote option | - + -### Params +### EventClaim | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `operator_trust_level` | [Fraction](#lbm.fbridge.v1.Fraction) | | ratio of how many operators' confirmations are needed to be valid. | -| `guardian_trust_level` | [Fraction](#lbm.fbridge.v1.Fraction) | | ratio of how many guardians' confirmations are needed to be valid. | -| `judge_trust_level` | [Fraction](#lbm.fbridge.v1.Fraction) | | ratio of how many judges' confirmations are needed to be valid. | -| `timelock_period` | [uint64](#uint64) | | default timelock period for each provision (unix timestamp) | -| `proposal_period` | [uint64](#uint64) | | default period of the proposal to update the role | +| `seq` | [uint64](#uint64) | | the sequence number of the bridge request | +| `sender` | [string](#string) | | the sender address on the source chain | +| `receiver` | [string](#string) | | the recipient address on the destination chain | +| `amount` | [string](#string) | | the amount of token to be claimed | - + + +### EventConfirmProvision -### ProvisionData -Provision is a struct that represents a provision internally. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | `seq` | [uint64](#uint64) | | the sequence number of the bridge request | -| `amount` | [string](#string) | | the amount of token to be claimed | -| `sender` | [string](#string) | | the sender address on the source chain | -| `receiver` | [string](#string) | | the recipient address on the destination chain | - + + +### EventProvision -### ProvisionStatus -ProvisionStatus is a struct that represents the status of a provision. -To optimize computational cost, we have collected frequently changing values from provision. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `timelock_end` | [uint64](#uint64) | | the unix timestamp the provision will be able to be claimed (unix timestamp) | -| `confirm_counts` | [int32](#int32) | | a value that tells how many operators have submitted this provision | -| `is_claimed` | [bool](#bool) | | whether the provision has been claimed | +| `seq` | [uint64](#uint64) | | the sequence number of the bridge request | +| `sender` | [string](#string) | | the sender address on the source chain | +| `receiver` | [string](#string) | | the recipient address on the destination chain | +| `amount` | [string](#string) | | the amount of token to be claimed | +| `operator` | [string](#string) | | the address of the operator | - + -### RoleProposal +### EventSuggestRole | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `id` | [uint64](#uint64) | | | -| `proposer` | [string](#string) | | the proposer address | -| `target` | [string](#string) | | the address to update the role | -| `role` | [Role](#lbm.fbridge.v1.Role) | | the role to be updated - unspecified : 0, used to remove the address from a group - guardian : 1 - operator : 2 - judge : 3 | -| `expired_at` | [uint64](#uint64) | | the unix timestamp the proposal will be expired (unix timestamp) | +| `proposal` | [RoleProposal](#lbm.fbridge.v1.RoleProposal) | | | - + - +### EventTransfer + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `seq` | [uint64](#uint64) | | the sequence number of the bridge request | +| `sender` | [string](#string) | | the sender address on the source chain | +| `receiver` | [string](#string) | | the recipient address on the destination chain | +| `amount` | [string](#string) | | the amount of token to be transferred | -### Role -Role defines the role of the operator, guardian, and judge. -| Name | Number | Description | -| ---- | ------ | ----------- | -| UNSPECIFIED | 0 | | -| GUARDIAN | 1 | | -| OPERATOR | 2 | | -| JUDGE | 3 | | + + + @@ -11615,6 +11750,22 @@ Role defines the role of the operator, guardian, and judge. + + +### BridgeSwitch + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `guardian` | [string](#string) | | the guardian address | +| `status` | [BridgeStatus](#lbm.fbridge.v1.BridgeStatus) | | | + + + + + + ### Commitment @@ -11659,6 +11810,11 @@ GenesisState defines the fbridge module's genesis state. | `params` | [Params](#lbm.fbridge.v1.Params) | | params defines all the parameters of the module. | | `sending_state` | [SendingState](#lbm.fbridge.v1.SendingState) | | sending_state defines status saved when sending tokens to a counterpart chain | | `receiving_state` | [ReceivingState](#lbm.fbridge.v1.ReceivingState) | | receiving_state defines status saved when receiving tokens from a counterpart chain | +| `next_role_proposal_id` | [uint64](#uint64) | | next_role_proposal_id is the next role proposal ID to be used. | +| `role_proposals` | [RoleProposal](#lbm.fbridge.v1.RoleProposal) | repeated | role_proposals defines all the role proposals present at genesis. | +| `votes` | [Vote](#lbm.fbridge.v1.Vote) | repeated | votes defines all the votes present for role proposals at genesis. | +| `roles` | [RolePair](#lbm.fbridge.v1.RolePair) | repeated | roles defines all addresses assigned roles at genesis. | +| `bridge_switches` | [BridgeSwitch](#lbm.fbridge.v1.BridgeSwitch) | repeated | bridge_switches defines the status of whether each guardian has allowed the bridge to operate. | @@ -11751,6 +11907,32 @@ GenesisState defines the fbridge module's genesis state. + + +### QueryBridgeStatusRequest + + + + + + + + + +### QueryBridgeStatusResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `status` | [BridgeStatus](#lbm.fbridge.v1.BridgeStatus) | | | +| `metadata` | [BridgeStatusMetadata](#lbm.fbridge.v1.BridgeStatusMetadata) | | | + + + + + + ### QueryCommitmentsRequest @@ -11867,50 +12049,60 @@ GenesisState defines the fbridge module's genesis state. - + + +### QueryMemberRequest -### QueryGuardiansRequest +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `address` | [string](#string) | | | - -### QueryGuardiansResponse + + +### QueryMemberResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `guardians` | [string](#string) | repeated | | +| `role` | [string](#string) | | | + + - +### QueryMembersRequest -### QueryJudgesRequest +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `role` | [string](#string) | | the role name (guardian, operator, judge) | - -### QueryJudgesResponse + + +### QueryMembersResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `judges` | [string](#string) | repeated | | +| `members` | [string](#string) | repeated | | @@ -11973,31 +12165,6 @@ GenesisState defines the fbridge module's genesis state. - - -### QueryOperatorsRequest - - - - - - - - - -### QueryOperatorsResponse - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `operators` | [string](#string) | repeated | | - - - - - - ### QueryParamsRequest @@ -12031,7 +12198,7 @@ GenesisState defines the fbridge module's genesis state. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `proposal_id` | [string](#string) | | the proposal id | +| `proposal_id` | [uint64](#uint64) | | the proposal id | @@ -12077,6 +12244,7 @@ GenesisState defines the fbridge module's genesis state. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | `proposals` | [RoleProposal](#lbm.fbridge.v1.RoleProposal) | repeated | | +| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines an pagination for the response. | @@ -12144,6 +12312,67 @@ GenesisState defines the fbridge module's genesis state. + + + +### QueryVoteRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `proposal_id` | [uint64](#uint64) | | proposal_id defines the unique id of the proposal. | +| `voter` | [string](#string) | | voter defines the oter address for the proposals. | + + + + + + + + +### QueryVoteResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `vote` | [Vote](#lbm.fbridge.v1.Vote) | | vote defined the queried vote. | + + + + + + + + +### QueryVotesRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `proposal_id` | [uint64](#uint64) | | proposal_id defines the unique id of the proposal. | + + + + + + + + +### QueryVotesResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `votes` | [Vote](#lbm.fbridge.v1.Vote) | repeated | votes defined the queried votes. | + + + + + @@ -12167,11 +12396,13 @@ GenesisState defines the fbridge module's genesis state. | `ConfirmedProvision` | [QueryConfirmedProvisionRequest](#lbm.fbridge.v1.QueryConfirmedProvisionRequest) | [QueryConfirmedProvisionResponse](#lbm.fbridge.v1.QueryConfirmedProvisionResponse) | ConfirmedProvision queries a particular sequence of confirmed provisions | GET|/lbm/fbridge/v1/receiving/provision/{seq}| | `NeededSubmissionSeqs` | [QueryNeededSubmissionSeqsRequest](#lbm.fbridge.v1.QueryNeededSubmissionSeqsRequest) | [QueryNeededSubmissionSeqsResponse](#lbm.fbridge.v1.QueryNeededSubmissionSeqsResponse) | NeededSubmissionSeqs queries a list of sequence numbers that need to be submitted by a particular operator The search scope is [greatest_consecutive_seq_by_operator, min(greatest_consecutive_seq_by_operator + range, greatest_seq_by_operator)] greatest_consecutive_seq_by_operator can be replaced with greatest_consecutive_seq if the operator is newly added | GET|/lbm/fbridge/v1/receiving/operators/{operator}/needed_submission_seqs| | `Commitments` | [QueryCommitmentsRequest](#lbm.fbridge.v1.QueryCommitmentsRequest) | [QueryCommitmentsResponse](#lbm.fbridge.v1.QueryCommitmentsResponse) | Commitments queries commitments of a specific sequence number | GET|/lbm/fbridge/v1/receiving/commitments/{seq}| -| `Guardians` | [QueryGuardiansRequest](#lbm.fbridge.v1.QueryGuardiansRequest) | [QueryGuardiansResponse](#lbm.fbridge.v1.QueryGuardiansResponse) | Guardians queries a list of Guardians registered on the bridge | GET|/lbm/fbridge/v1/guardians| -| `Operators` | [QueryOperatorsRequest](#lbm.fbridge.v1.QueryOperatorsRequest) | [QueryOperatorsResponse](#lbm.fbridge.v1.QueryOperatorsResponse) | Operators queries a list of Operators registered on the bridge | GET|/lbm/fbridge/v1/operators| -| `Judges` | [QueryJudgesRequest](#lbm.fbridge.v1.QueryJudgesRequest) | [QueryJudgesResponse](#lbm.fbridge.v1.QueryJudgesResponse) | Judges queries a list of Judges registered on the bridge | GET|/lbm/fbridge/v1/judges| -| `Proposals` | [QueryProposalsRequest](#lbm.fbridge.v1.QueryProposalsRequest) | [QueryProposalsResponse](#lbm.fbridge.v1.QueryProposalsResponse) | Proposals queries a list of SuggestRole Proposals | GET|/lbm/fbridge/v1/role/proposals| -| `Proposal` | [QueryProposalRequest](#lbm.fbridge.v1.QueryProposalRequest) | [QueryProposalResponse](#lbm.fbridge.v1.QueryProposalResponse) | Proposal queries a SuggestRole Proposal | GET|/lbm/fbridge/v1/role/proposals/{proposal_id}| +| `Members` | [QueryMembersRequest](#lbm.fbridge.v1.QueryMembersRequest) | [QueryMembersResponse](#lbm.fbridge.v1.QueryMembersResponse) | Members queries the members of spcific group registered on the bridge | GET|/lbm/fbridge/v1/members| +| `Member` | [QueryMemberRequest](#lbm.fbridge.v1.QueryMemberRequest) | [QueryMemberResponse](#lbm.fbridge.v1.QueryMemberResponse) | Member queries the role of a specific member | GET|/lbm/fbridge/v1/members/{address}| +| `Proposals` | [QueryProposalsRequest](#lbm.fbridge.v1.QueryProposalsRequest) | [QueryProposalsResponse](#lbm.fbridge.v1.QueryProposalsResponse) | Proposals queries a list of SuggestRole Proposals | GET|/lbm/fbridge/v1/proposals| +| `Proposal` | [QueryProposalRequest](#lbm.fbridge.v1.QueryProposalRequest) | [QueryProposalResponse](#lbm.fbridge.v1.QueryProposalResponse) | Proposal queries a SuggestRole Proposal | GET|/lbm/fbridge/v1/proposals/{proposal_id}| +| `Vote` | [QueryVoteRequest](#lbm.fbridge.v1.QueryVoteRequest) | [QueryVoteResponse](#lbm.fbridge.v1.QueryVoteResponse) | Vote queries voted information based on proposalID, voterAddr. | GET|/lbm/fbridge/v1/proposals/{proposal_id}/votes/{voter}| +| `Votes` | [QueryVotesRequest](#lbm.fbridge.v1.QueryVotesRequest) | [QueryVotesResponse](#lbm.fbridge.v1.QueryVotesResponse) | Votes queries votes of a given proposal. | GET|/lbm/fbridge/v1/proposals/{proposal_id}/votes| +| `BridgeStatus` | [QueryBridgeStatusRequest](#lbm.fbridge.v1.QueryBridgeStatusRequest) | [QueryBridgeStatusResponse](#lbm.fbridge.v1.QueryBridgeStatusResponse) | BridgeStatus queries the status of the bridge | GET|/lbm/fbridge/v1/status| @@ -12194,7 +12425,7 @@ GenesisState defines the fbridge module's genesis state. | ----- | ---- | ----- | ----------- | | `from` | [string](#string) | | the guardian address | | `proposal_id` | [uint64](#uint64) | | the proposal ID | -| `option` | [bool](#bool) | | the vote option - yes : true - no : false | +| `option` | [VoteOption](#lbm.fbridge.v1.VoteOption) | | the vote option | @@ -12263,31 +12494,6 @@ MsgClaimBatch is input values required for claiming multiple claimable provision - - -### MsgHalt -MsgHalt is input values required for halting the bridge module - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `guardian` | [string](#string) | | the guardian address | - - - - - - - - -### MsgHaltResponse - - - - - - - ### MsgHoldTransfer @@ -12395,24 +12601,25 @@ MsgRemoveProvision is input values required for removing a specific confirmed pr - + -### MsgResume -MsgResume is input values required for resuming the bridge module +### MsgSetBridgeStatus +MsgSetBridgeStatus is input values required for setting the status of the bridge module | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `from` | [string](#string) | | the guardian address | +| `guardian` | [string](#string) | | the guardian address | +| `status` | [BridgeStatus](#lbm.fbridge.v1.BridgeStatus) | | | - + -### MsgResumeResponse +### MsgSetBridgeStatusResponse @@ -12496,8 +12703,7 @@ MsgTransfer is input values required for bridge transfer | `Claim` | [MsgClaim](#lbm.fbridge.v1.MsgClaim) | [MsgClaimResponse](#lbm.fbridge.v1.MsgClaimResponse) | Claim processes the claiming of a provision with a specific sequence number | | | `SuggestRole` | [MsgSuggestRole](#lbm.fbridge.v1.MsgSuggestRole) | [MsgSuggestRoleResponse](#lbm.fbridge.v1.MsgSuggestRoleResponse) | SuggestRole suggests updating the role of an address in the bridge module. The role can be one of the following: guardian, operator, judge. The proposal will be passed only with the consent of +2/3 Guardian members. | | | `AddVoteForRole` | [MsgAddVoteForRole](#lbm.fbridge.v1.MsgAddVoteForRole) | [MsgAddVoteForRoleResponse](#lbm.fbridge.v1.MsgAddVoteForRoleResponse) | AddVoteForRole adds a vote for a role change proposal. | | -| `Halt` | [MsgHalt](#lbm.fbridge.v1.MsgHalt) | [MsgHaltResponse](#lbm.fbridge.v1.MsgHaltResponse) | Halt the bridge module. | | -| `Resume` | [MsgResume](#lbm.fbridge.v1.MsgResume) | [MsgResumeResponse](#lbm.fbridge.v1.MsgResumeResponse) | Resume the bridge module. | | +| `SetBridgeStatus` | [MsgSetBridgeStatus](#lbm.fbridge.v1.MsgSetBridgeStatus) | [MsgSetBridgeStatusResponse](#lbm.fbridge.v1.MsgSetBridgeStatusResponse) | SetBridgeStatus operates a switch to halt/resume the bridge module. If the ratio of inactive bridge switches exceed TrustLevel, the bridge module halts. | | diff --git a/proto/lbm/fbridge/v1/event.proto b/proto/lbm/fbridge/v1/event.proto index e7594d4dc8..324a2db2a2 100644 --- a/proto/lbm/fbridge/v1/event.proto +++ b/proto/lbm/fbridge/v1/event.proto @@ -3,6 +3,9 @@ package lbm.fbridge.v1; option go_package = "github.com/Finschia/finschia-sdk/x/fbridge/types"; +import "gogoproto/gogo.proto"; +import "lbm/fbridge/v1/fbridge.proto"; + message EventTransfer { // the sequence number of the bridge request uint64 seq = 1; @@ -14,6 +17,19 @@ message EventTransfer { string amount = 4; } +message EventSuggestRole { + RoleProposal proposal = 1 [(gogoproto.nullable) = false]; +} + +message EventAddVoteForRole { + // the voter address + string voter = 1; + // the role proposal id + uint64 proposal_id = 2; + // the vote option + VoteOption option = 3; +} + message EventProvision { // the sequence number of the bridge request uint64 seq = 1; diff --git a/proto/lbm/fbridge/v1/fbridge.proto b/proto/lbm/fbridge/v1/fbridge.proto index fccbf79a22..c3c4d5b6c7 100644 --- a/proto/lbm/fbridge/v1/fbridge.proto +++ b/proto/lbm/fbridge/v1/fbridge.proto @@ -3,6 +3,7 @@ package lbm.fbridge.v1; option go_package = "github.com/Finschia/finschia-sdk/x/fbridge/types"; +import "google/protobuf/timestamp.proto"; import "gogoproto/gogo.proto"; message Params { @@ -51,10 +52,17 @@ message Fraction { // Role defines the role of the operator, guardian, and judge. enum Role { - UNSPECIFIED = 0; - GUARDIAN = 1; - OPERATOR = 2; - JUDGE = 3; + option (gogoproto.goproto_enum_prefix) = false; + + UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "RoleEmpty"]; + GUARDIAN = 1 [(gogoproto.enumvalue_customname) = "RoleGuardian"]; + OPERATOR = 2 [(gogoproto.enumvalue_customname) = "RoleOperator"]; + JUDGE = 3 [(gogoproto.enumvalue_customname) = "RoleJudge"]; +} + +message RolePair { + string address = 1; + Role role = 2; } message RoleProposal { @@ -71,5 +79,56 @@ message RoleProposal { Role role = 4; // the unix timestamp the proposal will be expired (unix timestamp) - uint64 expired_at = 5; + google.protobuf.Timestamp expired_at = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; +} + +// VoteOption enumerates the valid vote options for a given role proposal. +enum VoteOption { + option (gogoproto.goproto_enum_prefix) = false; + + // VOTE_OPTION_UNSPECIFIED defines a no-op vote option. + VOTE_OPTION_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "OptionEmpty"]; + // VOTE_OPTION_YES defines a yes vote option. + VOTE_OPTION_YES = 1 [(gogoproto.enumvalue_customname) = "OptionYes"]; + // VOTE_OPTION_NO defines a no vote option. + VOTE_OPTION_NO = 2 [(gogoproto.enumvalue_customname) = "OptionNo"]; +} + +// Vote defines a vote on a role proposal. +message Vote { + option (gogoproto.equal) = false; + + uint64 proposal_id = 1; + string voter = 2; + VoteOption option = 3; +} + +// RoleMetadata defines the metadata of the role. +message RoleMetadata { + // the number of registered guardians + uint64 guardian = 1; + // the number of the operators + uint64 operator = 2; + // the number of the judges + uint64 judge = 3; +} + +enum BridgeStatus { + option (gogoproto.goproto_enum_prefix) = false; + + // BRIDGE_STATUS_UNSPECIFIED defines an unspecified bridge status. + BRIDGE_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "StatusEmpty"]; + + // BRIDGE_STATUS_ACTIVE defines an active bridge status. + BRIDGE_STATUS_ACTIVE = 1 [(gogoproto.enumvalue_customname) = "StatusActive"]; + // BRIDGE_STATUS_INACTIVE defines an inactive bridge status. + BRIDGE_STATUS_INACTIVE = 2 [(gogoproto.enumvalue_customname) = "StatusInactive"]; +} + +// BridgeStatusMetadata defines the metadata of the bridge status. +message BridgeStatusMetadata { + // the number of inactived bridge switch + uint64 inactive = 1; + // the number of activated bridge switch + uint64 active = 2; } diff --git a/proto/lbm/fbridge/v1/genesis.proto b/proto/lbm/fbridge/v1/genesis.proto index 35775047b2..57d5260328 100644 --- a/proto/lbm/fbridge/v1/genesis.proto +++ b/proto/lbm/fbridge/v1/genesis.proto @@ -14,6 +14,16 @@ message GenesisState { SendingState sending_state = 2 [(gogoproto.nullable) = false]; // receiving_state defines status saved when receiving tokens from a counterpart chain ReceivingState receiving_state = 3 [(gogoproto.nullable) = false]; + // next_role_proposal_id is the next role proposal ID to be used. + uint64 next_role_proposal_id = 4; + // role_proposals defines all the role proposals present at genesis. + repeated RoleProposal role_proposals = 5 [(gogoproto.nullable) = false]; + // votes defines all the votes present for role proposals at genesis. + repeated Vote votes = 6 [(gogoproto.nullable) = false]; + // roles defines all addresses assigned roles at genesis. + repeated RolePair roles = 7 [(gogoproto.nullable) = false]; + // bridge_switches defines the status of whether each guardian has allowed the bridge to operate. + repeated BridgeSwitch bridge_switches = 8 [(gogoproto.nullable) = false]; } message SendingState { @@ -79,3 +89,9 @@ message ConfirmedProvision { // commitment is the hash value of a provision string commitment = 2; } + +message BridgeSwitch { + // the guardian address + string guardian = 1; + BridgeStatus status = 2; +} diff --git a/proto/lbm/fbridge/v1/query.proto b/proto/lbm/fbridge/v1/query.proto index 120039df88..b59d513956 100644 --- a/proto/lbm/fbridge/v1/query.proto +++ b/proto/lbm/fbridge/v1/query.proto @@ -58,29 +58,39 @@ service Query { option (google.api.http).get = "/lbm/fbridge/v1/receiving/commitments/{seq}"; } - // Guardians queries a list of Guardians registered on the bridge - rpc Guardians(QueryGuardiansRequest) returns (QueryGuardiansResponse) { - option (google.api.http).get = "/lbm/fbridge/v1/guardians"; + // Members queries the members of spcific group registered on the bridge + rpc Members(QueryMembersRequest) returns (QueryMembersResponse) { + option (google.api.http).get = "/lbm/fbridge/v1/members"; } - // Operators queries a list of Operators registered on the bridge - rpc Operators(QueryOperatorsRequest) returns (QueryOperatorsResponse) { - option (google.api.http).get = "/lbm/fbridge/v1/operators"; - } - - // Judges queries a list of Judges registered on the bridge - rpc Judges(QueryJudgesRequest) returns (QueryJudgesResponse) { - option (google.api.http).get = "/lbm/fbridge/v1/judges"; + // Member queries the role of a specific member + rpc Member(QueryMemberRequest) returns (QueryMemberResponse) { + option (google.api.http).get = "/lbm/fbridge/v1/members/{address}"; } // Proposals queries a list of SuggestRole Proposals rpc Proposals(QueryProposalsRequest) returns (QueryProposalsResponse) { - option (google.api.http).get = "/lbm/fbridge/v1/role/proposals"; + option (google.api.http).get = "/lbm/fbridge/v1/proposals"; } // Proposal queries a SuggestRole Proposal rpc Proposal(QueryProposalRequest) returns (QueryProposalResponse) { - option (google.api.http).get = "/lbm/fbridge/v1/role/proposals/{proposal_id}"; + option (google.api.http).get = "/lbm/fbridge/v1/proposals/{proposal_id}"; + } + + // Vote queries voted information based on proposalID, voterAddr. + rpc Vote(QueryVoteRequest) returns (QueryVoteResponse) { + option (google.api.http).get = "/lbm/fbridge/v1/proposals/{proposal_id}/votes/{voter}"; + } + + // Votes queries votes of a given proposal. + rpc Votes(QueryVotesRequest) returns (QueryVotesResponse) { + option (google.api.http).get = "/lbm/fbridge/v1/proposals/{proposal_id}/votes"; + } + + // BridgeStatus queries the status of the bridge + rpc BridgeStatus(QueryBridgeStatusRequest) returns (QueryBridgeStatusResponse) { + option (google.api.http).get = "/lbm/fbridge/v1/status"; } } @@ -162,22 +172,21 @@ message QueryCommitmentsResponse { repeated string commitments = 1; } -message QueryGuardiansRequest {} - -message QueryGuardiansResponse { - repeated string guardians = 1; +message QueryMembersRequest { + // the role name (guardian, operator, judge) + string role = 1; } -message QueryOperatorsRequest {} - -message QueryOperatorsResponse { - repeated string operators = 1; +message QueryMembersResponse { + repeated string members = 1; } -message QueryJudgesRequest {} +message QueryMemberRequest { + string address = 1; +} -message QueryJudgesResponse { - repeated string judges = 1; +message QueryMemberResponse { + string role = 1; } message QueryProposalsRequest { @@ -186,14 +195,47 @@ message QueryProposalsRequest { } message QueryProposalsResponse { - repeated RoleProposal proposals = 1; + repeated RoleProposal proposals = 1 [(gogoproto.nullable) = false]; + + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; } message QueryProposalRequest { // the proposal id - string proposal_id = 1; + uint64 proposal_id = 1; } message QueryProposalResponse { - RoleProposal proposal = 1; + RoleProposal proposal = 1 [(gogoproto.nullable) = false]; +} + +message QueryVoteRequest { + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; + + // voter defines the oter address for the proposals. + string voter = 2; +} + +message QueryVoteResponse { + // vote defined the queried vote. + Vote vote = 1 [(gogoproto.nullable) = false]; +} + +message QueryVotesRequest { + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; +} + +message QueryVotesResponse { + // votes defined the queried votes. + repeated Vote votes = 1 [(gogoproto.nullable) = false]; +} + +message QueryBridgeStatusRequest {} + +message QueryBridgeStatusResponse { + BridgeStatus status = 1; + BridgeStatusMetadata metadata = 2 [(gogoproto.nullable) = false]; } diff --git a/proto/lbm/fbridge/v1/tx.proto b/proto/lbm/fbridge/v1/tx.proto index 8b114a8645..e1186ec588 100644 --- a/proto/lbm/fbridge/v1/tx.proto +++ b/proto/lbm/fbridge/v1/tx.proto @@ -36,11 +36,9 @@ service Msg { // AddVoteForRole adds a vote for a role change proposal. rpc AddVoteForRole(MsgAddVoteForRole) returns (MsgAddVoteForRoleResponse); - // Halt the bridge module. - rpc Halt(MsgHalt) returns (MsgHaltResponse); - - // Resume the bridge module. - rpc Resume(MsgResume) returns (MsgResumeResponse); + // SetBridgeStatus operates a switch to halt/resume the bridge module. + // If the ratio of inactive bridge switches exceed TrustLevel, the bridge module halts. + rpc SetBridgeStatus(MsgSetBridgeStatus) returns (MsgSetBridgeStatusResponse); } // MsgTransfer is input values required for bridge transfer @@ -145,25 +143,17 @@ message MsgAddVoteForRole { // the proposal ID uint64 proposal_id = 2; // the vote option - // - yes : true - // - no : false - bool option = 3; + VoteOption option = 3; } message MsgAddVoteForRoleResponse {} -// MsgHalt is input values required for halting the bridge module -message MsgHalt { +// MsgSetBridgeStatus is input values required for setting the status of the bridge module +message MsgSetBridgeStatus { // the guardian address string guardian = 1; -} - -message MsgHaltResponse {} -// MsgResume is input values required for resuming the bridge module -message MsgResume { - // the guardian address - string from = 1; + BridgeStatus status = 2; } -message MsgResumeResponse {} +message MsgSetBridgeStatusResponse {} diff --git a/simapp/app.go b/simapp/app.go index 7bb68f2e01..9b064b19b2 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -271,7 +271,7 @@ func NewSimApp( tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) // NOTE: The testingkey is just mounted for testing purposes. Actual applications should // not include this key. - memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey, "testingkey") + memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey, fbridgetypes.MemStoreKey, "testingkey") // configure state listening capabilities using AppOptions // we are doing nothing with the returned streamingServices and waitGroup in this case @@ -373,7 +373,7 @@ func NewSimApp( // If evidence needs to be handled for the app, set routes in router here and seal app.EvidenceKeeper = *evidenceKeeper - app.FbridgeKeeper = fbridgekeeper.NewKeeper(appCodec, keys[fbridgetypes.StoreKey], app.AccountKeeper, app.BankKeeper, "stake", authtypes.NewModuleAddress(govtypes.ModuleName).String()) + app.FbridgeKeeper = fbridgekeeper.NewKeeper(appCodec, keys[fbridgetypes.StoreKey], memKeys[fbridgetypes.MemStoreKey], app.AccountKeeper, app.BankKeeper, "stake", fbridgetypes.DefaultAuthority().String()) /**** Module Options ****/ @@ -471,6 +471,7 @@ func NewSimApp( capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, + fbridgetypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, @@ -488,7 +489,6 @@ func NewSimApp( token.ModuleName, collection.ModuleName, fswaptypes.ModuleName, - fbridgetypes.ModuleName, ) // Uncomment if you want to set a custom migration order here. diff --git a/x/ERRORS.md b/x/ERRORS.md index dcf56afb65..d8dc1ea25e 100644 --- a/x/ERRORS.md +++ b/x/ERRORS.md @@ -7,6 +7,7 @@ * [Crisis](#crisis) * [Distribution](#distribution) * [Evidence](#evidence) + * [Fbridge](#fbridge) * [Feegrant](#feegrant) * [Foundation](#foundation) * [Fswap](#fswap) @@ -151,6 +152,17 @@ >You can also find detailed information in the following Errors.go files: * [evidence/types/errors.go](evidence/types/errors.go) +## Fbridge + +|Error Name|Codespace|Code|Description| +|:-|:-|:-|:-| +|ErrUnknownProposal|fbridge|2|unknown proposal| +|ErrUnknownVote|fbridge|3|unknown vote| +|ErrInactiveBridge|fbridge|4|the bridge has halted| + +>You can also find detailed information in the following Errors.go files: + * [fbridge/types/errors.go](fbridge/types/errors.go) + ## Feegrant |Error Name|Codespace|Code|Description| diff --git a/x/fbridge/client/cli/query.go b/x/fbridge/client/cli/query.go index 4878af22e7..19708afb6e 100644 --- a/x/fbridge/client/cli/query.go +++ b/x/fbridge/client/cli/query.go @@ -2,6 +2,7 @@ package cli import ( "fmt" + "strconv" "github.com/spf13/cobra" @@ -23,13 +24,45 @@ func NewQueryCmd() *cobra.Command { } cmd.AddCommand( + NewQueryParamsCmd(), NewQueryNextSeqSendCmd(), NewQuerySeqToBlocknumsCmd(), + NewQueryMembersCmd(), + NewQueryMemberCmd(), + NewQueryProposalsCmd(), + NewQueryProposalCmd(), + NewQueryVotesCmd(), + NewQueryVoteCmd(), + NewQueryBridgeStatusCmd(), ) return cmd } +func NewQueryParamsCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Short: "Query the current fbridge module parameters", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + qc := types.NewQueryClient(clientCtx) + res, err := qc.Params(cmd.Context(), &types.QueryParamsRequest{}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + func NewQueryNextSeqSendCmd() *cobra.Command { cmd := &cobra.Command{ Use: "sending-next-seq", @@ -59,7 +92,7 @@ func NewQuerySeqToBlocknumsCmd() *cobra.Command { Use: "seq-to-blocknums", Short: "Query the block number for given sequence numbers", Args: cobra.NoArgs, - Example: fmt.Sprintf("%s query %s sending seq-to-blocknums --sequences=1,2,3", version.AppName, types.ModuleName), + Example: fmt.Sprintf("%s query %s seq-to-blocknums --sequences=1,2,3", version.AppName, types.ModuleName), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { @@ -90,3 +123,202 @@ func NewQuerySeqToBlocknumsCmd() *cobra.Command { flags.AddQueryFlagsToCmd(cmd) return cmd } + +func NewQueryMembersCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "members [role]", + Short: "Query the members of spcific group registered on the bridge (guardian|operator|judge)", + Args: cobra.ExactArgs(1), + Example: fmt.Sprintf("%s query %s members guardian", version.AppName, types.ModuleName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + qc := types.NewQueryClient(clientCtx) + + res, err := qc.Members(cmd.Context(), &types.QueryMembersRequest{Role: args[0]}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +func NewQueryMemberCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "member [address]", + Short: "Query the roles of a specific member registered on the bridge", + Args: cobra.ExactArgs(1), + Example: fmt.Sprintf("%s query %s member link1...", version.AppName, types.ModuleName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + qc := types.NewQueryClient(clientCtx) + + res, err := qc.Member(cmd.Context(), &types.QueryMemberRequest{Address: args[0]}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +func NewQueryProposalsCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "proposals", + Short: "Query all role proposals", + Args: cobra.NoArgs, + Example: fmt.Sprintf("%s query %s proposals", version.AppName, types.ModuleName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + qc := types.NewQueryClient(clientCtx) + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + res, err := qc.Proposals(cmd.Context(), &types.QueryProposalsRequest{Pagination: pageReq}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + flags.AddPaginationFlagsToCmd(cmd, "all proposals") + return cmd +} + +func NewQueryProposalCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "proposal [proposal_id]", + Short: "Query a specific role proposal", + Args: cobra.ExactArgs(1), + Example: fmt.Sprintf("%s query %s proposal 1", version.AppName, types.ModuleName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + qc := types.NewQueryClient(clientCtx) + + id, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return err + } + + res, err := qc.Proposal(cmd.Context(), &types.QueryProposalRequest{ProposalId: id}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +func NewQueryVotesCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "votes [proposal_id]", + Short: "Query all votes for a specific role proposal", + Args: cobra.ExactArgs(1), + Example: fmt.Sprintf("%s query %s votes 1", version.AppName, types.ModuleName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + qc := types.NewQueryClient(clientCtx) + + id, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return err + } + + res, err := qc.Votes(cmd.Context(), &types.QueryVotesRequest{ProposalId: id}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +func NewQueryVoteCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "vote [proposal_id] [voter]", + Short: "Query a specific vote for a role proposal", + Args: cobra.ExactArgs(2), + Example: fmt.Sprintf("%s query %s vote 1 link1...", version.AppName, types.ModuleName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + qc := types.NewQueryClient(clientCtx) + + id, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return err + } + + res, err := qc.Vote(cmd.Context(), &types.QueryVoteRequest{ProposalId: id, Voter: args[1]}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +func NewQueryBridgeStatusCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "status", + Short: "Query the current status of the bridge", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + qc := types.NewQueryClient(clientCtx) + res, err := qc.BridgeStatus(cmd.Context(), &types.QueryBridgeStatusRequest{}) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} diff --git a/x/fbridge/client/cli/tx.go b/x/fbridge/client/cli/tx.go index 8aa3b892bb..887e5bf586 100644 --- a/x/fbridge/client/cli/tx.go +++ b/x/fbridge/client/cli/tx.go @@ -1,6 +1,9 @@ package cli import ( + "fmt" + "strconv" + "github.com/spf13/cobra" "github.com/Finschia/finschia-sdk/client" @@ -8,6 +11,7 @@ import ( "github.com/Finschia/finschia-sdk/client/tx" sdk "github.com/Finschia/finschia-sdk/types" sdkerrors "github.com/Finschia/finschia-sdk/types/errors" + "github.com/Finschia/finschia-sdk/version" "github.com/Finschia/finschia-sdk/x/fbridge/types" ) @@ -23,6 +27,9 @@ func NewTxCmd() *cobra.Command { TxCmd.AddCommand( NewTransferTxCmd(), + NewSuggestRoleTxCmd(), + NewAddVoteForRoleTxCmd(), + NewSetBridgeStatusTxCmd(), ) return TxCmd @@ -30,9 +37,10 @@ func NewTxCmd() *cobra.Command { func NewTransferTxCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "transfer [to_address] [amount]", - Short: `Transfer token from current chain to counterparty chain`, - Args: cobra.ExactArgs(2), + Use: "transfer [to_address] [amount]", + Short: `Transfer token from current chain to counterparty chain`, + Example: fmt.Sprintf("%s tx %s transfer link1... 1000cony --from mykey", version.AppName, types.ModuleName), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientTxContext(cmd) if err != nil { @@ -65,3 +73,119 @@ func NewTransferTxCmd() *cobra.Command { return cmd } + +func NewSuggestRoleTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "suggest-role [target_address] [role]", + Short: `Suggest a role to a specific address (unspecified|guardian|operator|judge)`, + Args: cobra.ExactArgs(2), + Example: fmt.Sprintf("%s tx %s suggest-role link1... guardian --from guardiankey", version.AppName, types.ModuleName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + from := clientCtx.GetFromAddress().String() + if _, err := sdk.AccAddressFromBech32(from); err != nil { + return sdkerrors.ErrInvalidAddress.Wrapf("invalid address: %s", from) + } + target := args[0] + role, found := types.QueryParamToRole[args[1]] + if !found { + return sdkerrors.ErrInvalidRequest.Wrapf("invalid role: %s", args[1]) + } + + msg := types.MsgSuggestRole{ + From: from, + Target: target, + Role: role, + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +func NewAddVoteForRoleTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "add-vote-for-role [proposal_id] [option]", + Short: `Vote for a role proposal (yes|no)`, + Args: cobra.ExactArgs(2), + Example: fmt.Sprintf("%s tx %s add-vote-for-role 1 yes --from guardiankey", version.AppName, types.ModuleName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + from := clientCtx.GetFromAddress().String() + if _, err := sdk.AccAddressFromBech32(from); err != nil { + return sdkerrors.ErrInvalidAddress.Wrapf("invalid address: %s", from) + } + proposalID, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return sdkerrors.ErrInvalidRequest.Wrapf("invalid proposal ID: %s", args[0]) + } + + voteOpts := map[string]types.VoteOption{ + "yes": types.OptionYes, + "no": types.OptionNo, + } + option, found := voteOpts[args[1]] + if !found { + return sdkerrors.ErrInvalidRequest.Wrapf("invalid vote option: %s", args[1]) + } + + msg := types.MsgAddVoteForRole{ + From: from, + ProposalId: proposalID, + Option: option, + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +func NewSetBridgeStatusTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "set-bridge-status [status]", + Short: `Set sender's bridge switch for halting/resuming the bridge module. Each guardian has their own switch. (halt|resume)`, + Args: cobra.ExactArgs(1), + Example: fmt.Sprintf("%s tx %s set-bridge-status halt --from guardiankey\n"+ + "%s tx %s set-bridge-status resume --from guardiankey\n", version.AppName, types.ModuleName, version.AppName, types.ModuleName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + from := clientCtx.GetFromAddress().String() + if _, err := sdk.AccAddressFromBech32(from); err != nil { + return sdkerrors.ErrInvalidAddress.Wrapf("invalid address: %s", from) + } + + conv := map[string]types.BridgeStatus{ + "halt": types.StatusInactive, + "resume": types.StatusActive, + } + + msg := types.MsgSetBridgeStatus{ + Guardian: from, + Status: conv[args[0]], + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/fbridge/keeper/abci.go b/x/fbridge/keeper/abci.go new file mode 100644 index 0000000000..28b5333b1f --- /dev/null +++ b/x/fbridge/keeper/abci.go @@ -0,0 +1,65 @@ +package keeper + +import ( + "fmt" + + sdk "github.com/Finschia/finschia-sdk/types" + "github.com/Finschia/finschia-sdk/x/fbridge/types" +) + +func (k Keeper) BeginBlocker(ctx sdk.Context) { + k.InitMemStore(ctx) + + proposals := k.GetRoleProposals(ctx) + for _, proposal := range proposals { + if ctx.BlockTime().After(proposal.ExpiredAt) { + k.deleteRoleProposal(ctx, proposal.Id) + } + } +} + +func (k Keeper) EndBlocker(ctx sdk.Context) { + guardianTrustLevel := k.GetParams(ctx).GuardianTrustLevel + proposals := k.GetRoleProposals(ctx) + for _, proposal := range proposals { + votes := k.GetProposalVotes(ctx, proposal.Id) + + var voteYes uint64 = 0 + for _, vote := range votes { + if vote.Option == types.OptionYes { + voteYes++ + } + } + + if types.CheckTrustLevelThreshold(k.GetRoleMetadata(ctx).Guardian, voteYes, guardianTrustLevel) || proposal.Proposer == k.GetAuthority() { + if err := k.updateRole(ctx, proposal.Role, sdk.MustAccAddressFromBech32(proposal.Target)); err != nil { + panic(err) + } + + k.deleteRoleProposal(ctx, proposal.Id) + } + } +} + +// RegisterInvariants registers the fbridge module invariants +func RegisterInvariants(ir sdk.InvariantRegistry, k Keeper) { + ir.RegisterRoute(types.ModuleName, "guardian-invariant", GuardianInvariant(k)) +} + +func GuardianInvariant(k Keeper) sdk.Invariant { + return func(ctx sdk.Context) (string, bool) { + numGuardian := 0 + for _, p := range k.GetRolePairs(ctx) { + if p.Role == types.RoleGuardian { + numGuardian++ + } + } + + numBridgeSw := len(k.GetBridgeSwitches(ctx)) + broken := numGuardian != numBridgeSw + return sdk.FormatInvariant( + types.ModuleName, "guardian-invariant", + fmt.Sprintf("number of guardians(%d) != number of bridge switches(%d)", numGuardian, numBridgeSw), + ), broken + } +} diff --git a/x/fbridge/keeper/auth.go b/x/fbridge/keeper/auth.go new file mode 100644 index 0000000000..86070efe83 --- /dev/null +++ b/x/fbridge/keeper/auth.go @@ -0,0 +1,331 @@ +package keeper + +import ( + "encoding/binary" + "fmt" + "time" + + sdk "github.com/Finschia/finschia-sdk/types" + sdkerrors "github.com/Finschia/finschia-sdk/types/errors" + "github.com/Finschia/finschia-sdk/x/fbridge/types" +) + +func (k Keeper) RegisterRoleProposal(ctx sdk.Context, proposer, target sdk.AccAddress, role types.Role) (types.RoleProposal, error) { + if k.GetRoleMetadata(ctx).Guardian > 0 { + if k.GetRole(ctx, proposer) != types.RoleGuardian { + return types.RoleProposal{}, sdkerrors.ErrUnauthorized.Wrapf("only guardian can execute this action") + } + } else { + if proposer.String() != k.authority { + return types.RoleProposal{}, sdkerrors.ErrUnauthorized.Wrapf("only %s can execute this action", k.authority) + } + } + + if k.GetRole(ctx, target) == role { + return types.RoleProposal{}, sdkerrors.ErrUnauthorized.Wrap("target already has same role") + } + + proposalID := k.GetNextProposalID(ctx) + proposal := types.RoleProposal{ + Id: proposalID, + Proposer: proposer.String(), + Target: target.String(), + Role: role, + ExpiredAt: ctx.BlockTime().Add(time.Duration(k.GetParams(ctx).ProposalPeriod)).UTC(), + } + + k.setRoleProposal(ctx, proposal) + k.setNextProposalID(ctx, proposalID+1) + + return proposal, nil +} + +func (k Keeper) addVote(ctx sdk.Context, proposalID uint64, voter sdk.AccAddress, option types.VoteOption) error { + if k.GetRole(ctx, voter) != types.RoleGuardian { + return sdkerrors.ErrUnauthorized.Wrap("only guardian can execute this action") + } + + _, found := k.GetRoleProposal(ctx, proposalID) + if !found { + return types.ErrUnknownProposal.Wrapf("#%d not found", proposalID) + } + + if err := types.IsValidVoteOption(option); err != nil { + return sdkerrors.ErrInvalidRequest.Wrap(err.Error()) + } + + k.setVote(ctx, proposalID, voter, option) + + return nil +} + +func (k Keeper) updateRole(ctx sdk.Context, role types.Role, addr sdk.AccAddress) error { + previousRole := k.GetRole(ctx, addr) + if previousRole == role { + return sdkerrors.ErrInvalidRequest.Wrap("target already has same role") + } + + roleMeta := k.GetRoleMetadata(ctx) + nInactive := k.GetBridgeInactiveCounter(ctx) + + switch previousRole { + case types.RoleGuardian: + roleMeta.Guardian-- + + bs, err := k.GetBridgeSwitch(ctx, addr) + if err != nil { + return err + } + + if bs.Status == types.StatusInactive { + nInactive-- + } + + k.deleteBridgeSwitch(ctx, addr) + + case types.RoleOperator: + roleMeta.Operator-- + case types.RoleJudge: + roleMeta.Judge-- + } + + if role == types.RoleEmpty { + k.deleteRole(ctx, addr) + return nil + } else { + if err := k.setRole(ctx, role, addr); err != nil { + return err + } + } + + switch role { + case types.RoleGuardian: + roleMeta.Guardian++ + if err := k.setBridgeSwitch(ctx, addr, types.StatusActive); err != nil { + panic(err) + } + case types.RoleOperator: + roleMeta.Operator++ + case types.RoleJudge: + roleMeta.Judge++ + } + + k.setRoleMetadata(ctx, roleMeta) + k.setBridgeInactiveCounter(ctx, nInactive) + + return nil +} + +func (k Keeper) updateBridgeSwitch(ctx sdk.Context, guardian sdk.AccAddress, status types.BridgeStatus) error { + if sw, err := k.GetBridgeSwitch(ctx, guardian); err == nil && sw.Status == status { + return sdkerrors.ErrInvalidRequest.Wrapf("%s already set %s", guardian, status) + } else if err != nil { + return err + } + + nInactive := k.GetBridgeInactiveCounter(ctx) + switch status { + case types.StatusActive: + nInactive-- + case types.StatusInactive: + nInactive++ + default: + return sdkerrors.ErrInvalidRequest.Wrapf("unknown bridge status: %d", status) + } + k.setBridgeInactiveCounter(ctx, nInactive) + + if err := k.setBridgeSwitch(ctx, guardian, status); err != nil { + return err + } + + return nil +} + +func (k Keeper) setNextProposalID(ctx sdk.Context, seq uint64) { + store := ctx.KVStore(k.storeKey) + bz := make([]byte, 8) + binary.BigEndian.PutUint64(bz, seq) + store.Set(types.KeyNextProposalID, bz) +} + +func (k Keeper) GetNextProposalID(ctx sdk.Context) uint64 { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.KeyNextProposalID) + if bz == nil { + panic("next role proposal ID must be set at genesis") + } + + return binary.BigEndian.Uint64(bz) +} + +func (k Keeper) setRoleProposal(ctx sdk.Context, proposal types.RoleProposal) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(&proposal) + store.Set(types.ProposalKey(proposal.Id), bz) +} + +func (k Keeper) GetRoleProposal(ctx sdk.Context, id uint64) (proposal types.RoleProposal, found bool) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.ProposalKey(id)) + if bz == nil { + return proposal, false + } + + k.cdc.MustUnmarshal(bz, &proposal) + return proposal, true +} + +func (k Keeper) deleteRoleProposal(ctx sdk.Context, id uint64) { + store := ctx.KVStore(k.storeKey) + if _, found := k.GetRoleProposal(ctx, id); !found { + panic(fmt.Sprintf("role proposal #%d not found", id)) + } + store.Delete(types.ProposalKey(id)) +} + +// IterateProposals iterates over the all the role proposals and performs a callback function +func (k Keeper) IterateProposals(ctx sdk.Context, cb func(proposal types.RoleProposal) (stop bool)) { + store := ctx.KVStore(k.storeKey) + + iterator := sdk.KVStorePrefixIterator(store, types.KeyProposalPrefix) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var proposal types.RoleProposal + k.cdc.MustUnmarshal(iterator.Value(), &proposal) + if cb(proposal) { + break + } + } +} + +// GetRoleProposals returns all the role proposals from store +func (k Keeper) GetRoleProposals(ctx sdk.Context) (proposals []types.RoleProposal) { + k.IterateProposals(ctx, func(proposal types.RoleProposal) bool { + proposals = append(proposals, proposal) + return false + }) + return +} + +func (k Keeper) setVote(ctx sdk.Context, proposalID uint64, voter sdk.AccAddress, option types.VoteOption) { + store := ctx.KVStore(k.storeKey) + bz := make([]byte, 4) + binary.BigEndian.PutUint32(bz, uint32(option)) + store.Set(types.VoterVoteKey(proposalID, voter), bz) +} + +func (k Keeper) GetVote(ctx sdk.Context, proposalID uint64, voter sdk.AccAddress) (types.VoteOption, error) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.VoterVoteKey(proposalID, voter)) + if bz == nil { + return types.OptionEmpty, types.ErrUnknownVote + } + + return types.VoteOption(binary.BigEndian.Uint32(bz)), nil +} + +func (k Keeper) GetProposalVotes(ctx sdk.Context, proposalID uint64) []types.Vote { + store := ctx.KVStore(k.storeKey) + + votes := make([]types.Vote, 0) + iterator := sdk.KVStorePrefixIterator(store, types.VotesKey(proposalID)) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + _, voter := types.SplitVoterVoteKey(iterator.Key()) + v := types.Vote{ + ProposalId: proposalID, + Voter: voter.String(), + Option: types.VoteOption(binary.BigEndian.Uint32(iterator.Value())), + } + votes = append(votes, v) + } + + return votes +} + +func (k Keeper) setRole(ctx sdk.Context, role types.Role, addr sdk.AccAddress) error { + if err := types.IsValidRole(role); err != nil { + return sdkerrors.ErrInvalidRequest.Wrap(err.Error()) + } + + store := ctx.KVStore(k.storeKey) + bz := make([]byte, 4) + binary.BigEndian.PutUint32(bz, uint32(role)) + store.Set(types.RoleKey(addr), bz) + + return nil +} + +func (k Keeper) GetRole(ctx sdk.Context, addr sdk.AccAddress) types.Role { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.RoleKey(addr)) + if bz == nil { + return types.RoleEmpty + } + + return types.Role(binary.BigEndian.Uint32(bz)) +} + +func (k Keeper) GetRolePairs(ctx sdk.Context) []types.RolePair { + store := ctx.KVStore(k.storeKey) + pairs := make([]types.RolePair, 0) + iterator := sdk.KVStorePrefixIterator(store, types.KeyRolePrefix) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + assignee := types.SplitRoleKey(iterator.Key()) + pairs = append(pairs, types.RolePair{Address: assignee.String(), Role: types.Role(binary.BigEndian.Uint32(iterator.Value()))}) + } + + return pairs +} + +func (k Keeper) deleteRole(ctx sdk.Context, addr sdk.AccAddress) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.RoleKey(addr)) +} + +func (k Keeper) setBridgeSwitch(ctx sdk.Context, guardian sdk.AccAddress, status types.BridgeStatus) error { + if err := types.IsValidBridgeStatus(status); err != nil { + return sdkerrors.ErrInvalidRequest.Wrap(err.Error()) + } + + store := ctx.KVStore(k.storeKey) + bz := make([]byte, 4) + binary.BigEndian.PutUint32(bz, uint32(status)) + store.Set(types.BridgeSwitchKey(guardian), bz) + return nil +} + +func (k Keeper) deleteBridgeSwitch(ctx sdk.Context, guardian sdk.AccAddress) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.BridgeSwitchKey(guardian)) +} + +func (k Keeper) GetBridgeSwitch(ctx sdk.Context, guardian sdk.AccAddress) (types.BridgeSwitch, error) { + if k.GetRole(ctx, guardian) != types.RoleGuardian { + return types.BridgeSwitch{}, sdkerrors.ErrUnauthorized.Wrap("only guardian has bridge switch") + } + + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.BridgeSwitchKey(guardian)) + if bz == nil { + panic("bridge switch must be set at genesis") + } + + return types.BridgeSwitch{Guardian: guardian.String(), Status: types.BridgeStatus(binary.BigEndian.Uint32(bz))}, nil +} + +func (k Keeper) GetBridgeSwitches(ctx sdk.Context) []types.BridgeSwitch { + store := ctx.KVStore(k.storeKey) + + bws := make([]types.BridgeSwitch, 0) + iterator := sdk.KVStorePrefixIterator(store, types.KeyBridgeSwitchPrefix) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + addr := types.SplitBridgeSwitchKey(iterator.Key()) + bws = append(bws, types.BridgeSwitch{Guardian: addr.String(), Status: types.BridgeStatus(binary.BigEndian.Uint32(iterator.Value()))}) + } + + return bws +} diff --git a/x/fbridge/keeper/auth_test.go b/x/fbridge/keeper/auth_test.go new file mode 100644 index 0000000000..fb773014e3 --- /dev/null +++ b/x/fbridge/keeper/auth_test.go @@ -0,0 +1,89 @@ +package keeper + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/Finschia/finschia-sdk/x/fbridge/testutil" + "github.com/Finschia/finschia-sdk/x/fbridge/types" +) + +func TestAssignRole(t *testing.T) { + key, memKey, ctx, encCfg, authKeeper, bankKeeper, addrs := testutil.PrepareFbridgeTest(t, 3) + auth := types.DefaultAuthority() + k := NewKeeper(encCfg.Codec, key, memKey, authKeeper, bankKeeper, "stake", auth.String()) + err := k.InitGenesis(ctx, types.DefaultGenesisState()) + require.NoError(t, err) + + // 1. Bridge authority assigns an address to a guardian role + p, err := k.RegisterRoleProposal(ctx, addrs[0], addrs[1], types.RoleGuardian) + require.Error(t, err, "role proposal must not be passed without authority") + require.Equal(t, types.RoleProposal{}, p) + p, err = k.RegisterRoleProposal(ctx, auth, addrs[0], types.RoleGuardian) + require.NoError(t, err) + require.EqualValues(t, 1, p.Id) + err = k.updateRole(ctx, types.RoleGuardian, addrs[0]) + require.NoError(t, err) + require.Equal(t, types.RoleGuardian, k.GetRole(ctx, addrs[0])) + require.Equal(t, types.RoleMetadata{Guardian: 1, Operator: 0, Judge: 0}, k.GetRoleMetadata(ctx)) + + // 2. Guardian assigns an address to a guardian role + _, err = k.RegisterRoleProposal(ctx, auth, addrs[1], types.RoleGuardian) + require.Error(t, err, "role proposal must be passed with guardian role after guardian group is formed") + p, err = k.RegisterRoleProposal(ctx, addrs[0], addrs[1], types.RoleGuardian) + require.NoError(t, err, "role proposal must be passed with guardian role") + require.EqualValues(t, 2, p.Id) + err = k.addVote(ctx, p.Id, addrs[0], types.OptionYes) + require.NoError(t, err) + opt, err := k.GetVote(ctx, p.Id, addrs[0]) + require.NoError(t, err) + require.Equal(t, types.OptionYes, opt) + err = k.updateRole(ctx, types.RoleGuardian, addrs[1]) + require.NoError(t, err) + require.Equal(t, types.RoleMetadata{Guardian: 2, Operator: 0, Judge: 0}, k.GetRoleMetadata(ctx)) + sws := k.GetBridgeSwitches(ctx) + require.Len(t, sws, 2) + for _, sw := range sws { + require.Equal(t, types.StatusActive, sw.Status) + } + + // 3. Guardian assigns an address to an operator role + err = k.updateRole(ctx, types.RoleOperator, addrs[1]) + require.NoError(t, err) + require.Equal(t, types.RoleMetadata{Guardian: 1, Operator: 1, Judge: 0}, k.GetRoleMetadata(ctx)) + + // 4. Guardian assigns an address to a same role + err = k.updateRole(ctx, types.RoleOperator, addrs[1]) + require.Error(t, err, "role must not be updated to the same role") +} + +func TestBridgeHaltAndResume(t *testing.T) { + key, memKey, ctx, encCfg, authKeeper, bankKeeper, addrs := testutil.PrepareFbridgeTest(t, 3) + auth := types.DefaultAuthority() + k := NewKeeper(encCfg.Codec, key, memKey, authKeeper, bankKeeper, "stake", auth.String()) + err := k.InitGenesis(ctx, types.DefaultGenesisState()) + require.NoError(t, err) + for _, addr := range addrs { + err = k.updateRole(ctx, types.RoleGuardian, addr) + require.NoError(t, err) + } + + require.Equal(t, types.StatusActive, k.GetBridgeStatus(ctx), "bridge status must be active (3/3)") + require.Equal(t, types.BridgeStatusMetadata{Active: 3, Inactive: 0}, k.GetBridgeStatusMetadata(ctx)) + + err = k.updateBridgeSwitch(ctx, addrs[0], types.StatusInactive) + require.NoError(t, err) + require.Equal(t, types.StatusActive, k.GetBridgeStatus(ctx), "bridge status must be active (2/3)") + require.Equal(t, types.BridgeStatusMetadata{Active: 2, Inactive: 1}, k.GetBridgeStatusMetadata(ctx)) + + err = k.updateBridgeSwitch(ctx, addrs[1], types.StatusInactive) + require.NoError(t, err) + require.Equal(t, types.StatusInactive, k.GetBridgeStatus(ctx), "bridge status must be inactive (1/3)") + require.Equal(t, types.BridgeStatusMetadata{Active: 1, Inactive: 2}, k.GetBridgeStatusMetadata(ctx)) + + err = k.updateBridgeSwitch(ctx, addrs[0], types.StatusActive) + require.NoError(t, err) + require.Equal(t, types.StatusActive, k.GetBridgeStatus(ctx), "bridge status must be active (2/3)") + require.Equal(t, types.BridgeStatusMetadata{Active: 2, Inactive: 1}, k.GetBridgeStatusMetadata(ctx)) +} diff --git a/x/fbridge/keeper/genesis.go b/x/fbridge/keeper/genesis.go index 9312e18a97..486f35ea68 100644 --- a/x/fbridge/keeper/genesis.go +++ b/x/fbridge/keeper/genesis.go @@ -8,20 +8,53 @@ import ( ) func (k Keeper) InitGenesis(ctx sdk.Context, gs *types.GenesisState) error { + k.SetParams(ctx, gs.Params) k.setNextSequence(ctx, gs.SendingState.NextSeq) for _, info := range gs.SendingState.SeqToBlocknum { k.setSeqToBlocknum(ctx, info.Seq, info.Blocknum) } + for _, pair := range gs.Roles { + if err := k.setRole(ctx, pair.Role, sdk.MustAccAddressFromBech32(pair.Address)); err != nil { + panic(err) + } + } + + for _, sw := range gs.BridgeSwitches { + if err := k.setBridgeSwitch(ctx, sdk.MustAccAddressFromBech32(sw.Guardian), sw.Status); err != nil { + panic(err) + } + } + + k.setNextProposalID(ctx, gs.NextRoleProposalId) + for _, proposal := range gs.RoleProposals { + k.setRoleProposal(ctx, proposal) + } + + for _, vote := range gs.Votes { + k.setVote(ctx, vote.ProposalId, sdk.MustAccAddressFromBech32(vote.Voter), vote.Option) + } + + // TODO: we initialize the appropriate genesis parameters whenever the feature is added + + k.InitMemStore(ctx) + return nil } func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { return &types.GenesisState{ + Params: k.GetParams(ctx), SendingState: types.SendingState{ NextSeq: k.GetNextSequence(ctx), SeqToBlocknum: k.getAllSeqToBlocknums(ctx), }, + ReceivingState: types.ReceivingState{}, + NextRoleProposalId: k.GetNextProposalID(ctx), + RoleProposals: k.GetRoleProposals(ctx), + Votes: k.GetAllVotes(ctx), + Roles: k.GetRolePairs(ctx), + BridgeSwitches: k.GetBridgeSwitches(ctx), } } @@ -40,3 +73,28 @@ func (k Keeper) getAllSeqToBlocknums(ctx sdk.Context) []types.BlockSeqInfo { return infos } + +// IterateVotes iterates over the all the votes for role proposals and performs a callback function +func (k Keeper) IterateVotes(ctx sdk.Context, cb func(proposal types.Vote) (stop bool)) { + store := ctx.KVStore(k.storeKey) + + iterator := sdk.KVStorePrefixIterator(store, types.KeyProposalVotePrefix) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + id, voter := types.SplitVoterVoteKey(iterator.Key()) + opt := types.VoteOption(binary.BigEndian.Uint32(iterator.Value())) + v := types.Vote{ProposalId: id, Voter: voter.String(), Option: opt} + if cb(v) { + break + } + } +} + +// GetAllVotes returns all the votes from the store +func (k Keeper) GetAllVotes(ctx sdk.Context) (votes []types.Vote) { + k.IterateVotes(ctx, func(vote types.Vote) bool { + votes = append(votes, vote) + return false + }) + return +} diff --git a/x/fbridge/keeper/grpc_query.go b/x/fbridge/keeper/grpc_query.go index e2460064c2..7c7046a535 100644 --- a/x/fbridge/keeper/grpc_query.go +++ b/x/fbridge/keeper/grpc_query.go @@ -7,14 +7,24 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "github.com/Finschia/finschia-sdk/store/prefix" sdk "github.com/Finschia/finschia-sdk/types" + sdkerrors "github.com/Finschia/finschia-sdk/types/errors" + "github.com/Finschia/finschia-sdk/types/query" "github.com/Finschia/finschia-sdk/x/fbridge/types" ) var _ types.QueryServer = Keeper{} -func (k Keeper) Params(ctx context.Context, request *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { - panic("implement me") +func (k Keeper) Params(goCtx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + params := k.GetParams(ctx) + + return &types.QueryParamsResponse{Params: params}, nil } func (k Keeper) NextSeqSend(goCtx context.Context, req *types.QueryNextSeqSendRequest) (*types.QueryNextSeqSendResponse, error) { @@ -53,45 +63,136 @@ func (k Keeper) SeqToBlocknums(goCtx context.Context, req *types.QuerySeqToBlock } func (k Keeper) GreatestSeqByOperator(ctx context.Context, request *types.QueryGreatestSeqByOperatorRequest) (*types.QueryGreatestSeqByOperatorResponse, error) { - panic("implement me") + panic(sdkerrors.ErrNotSupported) } func (k Keeper) GreatestConsecutiveConfirmedSeq(ctx context.Context, request *types.QueryGreatestConsecutiveConfirmedSeqRequest) (*types.QueryGreatestConsecutiveConfirmedSeqResponse, error) { - panic("implement me") + panic(sdkerrors.ErrNotSupported) } func (k Keeper) SubmittedProvision(ctx context.Context, request *types.QuerySubmittedProvisionRequest) (*types.QuerySubmittedProvisionResponse, error) { - panic("implement me") + panic(sdkerrors.ErrNotSupported) } func (k Keeper) ConfirmedProvision(ctx context.Context, request *types.QueryConfirmedProvisionRequest) (*types.QueryConfirmedProvisionResponse, error) { - panic("implement me") + panic(sdkerrors.ErrNotSupported) } func (k Keeper) NeededSubmissionSeqs(ctx context.Context, request *types.QueryNeededSubmissionSeqsRequest) (*types.QueryNeededSubmissionSeqsResponse, error) { - panic("implement me") + panic(sdkerrors.ErrNotSupported) } func (k Keeper) Commitments(ctx context.Context, request *types.QueryCommitmentsRequest) (*types.QueryCommitmentsResponse, error) { - panic("implement me") + panic(sdkerrors.ErrNotSupported) +} + +func (k Keeper) Members(goCtx context.Context, req *types.QueryMembersRequest) (*types.QueryMembersResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + roles := k.GetRolePairs(ctx) + members := make([]string, 0) + + if req.Role == "" { + for _, pair := range roles { + members = append(members, pair.Address) + } + } else { + role, found := types.QueryParamToRole[req.Role] + if !found { + return nil, status.Error(codes.InvalidArgument, "invalid role") + } + + for _, pair := range roles { + if pair.Role == role { + members = append(members, pair.Address) + } + } + } + + return &types.QueryMembersResponse{Members: members}, nil } -func (k Keeper) Guardians(ctx context.Context, request *types.QueryGuardiansRequest) (*types.QueryGuardiansResponse, error) { - panic("implement me") +func (k Keeper) Member(goCtx context.Context, req *types.QueryMemberRequest) (*types.QueryMemberResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + r := k.GetRole(ctx, sdk.MustAccAddressFromBech32(req.Address)) + if r == types.RoleEmpty { + return nil, status.Error(codes.NotFound, "role not found") + } + + return &types.QueryMemberResponse{Role: types.Role_name[int32(r)]}, nil +} + +func (k Keeper) Proposals(goCtx context.Context, req *types.QueryProposalsRequest) (*types.QueryProposalsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyProposalPrefix) + proposals := make([]types.RoleProposal, 0) + pageRes, err := query.Paginate(store, req.Pagination, func(_, value []byte) error { + var proposal types.RoleProposal + k.cdc.MustUnmarshal(value, &proposal) + proposals = append(proposals, proposal) + return nil + }) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &types.QueryProposalsResponse{Proposals: proposals, Pagination: pageRes}, nil } -func (k Keeper) Operators(ctx context.Context, request *types.QueryOperatorsRequest) (*types.QueryOperatorsResponse, error) { - panic("implement me") +func (k Keeper) Proposal(goCtx context.Context, req *types.QueryProposalRequest) (*types.QueryProposalResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + proposal, found := k.GetRoleProposal(ctx, req.ProposalId) + if !found { + return nil, status.Error(codes.NotFound, fmt.Sprintf("role proposal %d", req.ProposalId)) + } + + return &types.QueryProposalResponse{Proposal: proposal}, nil } -func (k Keeper) Judges(ctx context.Context, request *types.QueryJudgesRequest) (*types.QueryJudgesResponse, error) { - panic("implement me") +func (k Keeper) Votes(goCtx context.Context, req *types.QueryVotesRequest) (*types.QueryVotesResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + votes := k.GetProposalVotes(ctx, req.ProposalId) + return &types.QueryVotesResponse{Votes: votes}, nil } -func (k Keeper) Proposals(ctx context.Context, request *types.QueryProposalsRequest) (*types.QueryProposalsResponse, error) { - panic("implement me") +func (k Keeper) Vote(goCtx context.Context, req *types.QueryVoteRequest) (*types.QueryVoteResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + opt, err := k.GetVote(ctx, req.ProposalId, sdk.MustAccAddressFromBech32(req.Voter)) + if err != nil { + return nil, status.Error(codes.NotFound, err.Error()) + } + + return &types.QueryVoteResponse{Vote: types.Vote{ProposalId: req.ProposalId, Voter: req.Voter, Option: opt}}, nil } -func (k Keeper) Proposal(ctx context.Context, request *types.QueryProposalRequest) (*types.QueryProposalResponse, error) { - panic("implement me") +func (k Keeper) BridgeStatus(goCtx context.Context, req *types.QueryBridgeStatusRequest) (*types.QueryBridgeStatusResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + return &types.QueryBridgeStatusResponse{Status: k.GetBridgeStatus(ctx), Metadata: k.GetBridgeStatusMetadata(ctx)}, nil } diff --git a/x/fbridge/keeper/keeper.go b/x/fbridge/keeper/keeper.go index 6059da88bc..18cc8e0ef9 100644 --- a/x/fbridge/keeper/keeper.go +++ b/x/fbridge/keeper/keeper.go @@ -1,7 +1,9 @@ package keeper import ( + "encoding/binary" "errors" + "fmt" "github.com/tendermint/tendermint/libs/log" @@ -12,6 +14,7 @@ import ( type Keeper struct { storeKey sdk.StoreKey + memKey sdk.StoreKey cdc codec.BinaryCodec authKeeper types.AccountKeeper bankKeeper types.BankKeeper @@ -19,30 +22,31 @@ type Keeper struct { // the target denom for the bridge targetDenom string - // the authority address that can execute privileged operations only if the guardian group is not set - // - UpdateParams - // - SuggestRole + // authority can give a role to a specific address like guardian authority string } func NewKeeper( cdc codec.BinaryCodec, - key sdk.StoreKey, + key, memKey sdk.StoreKey, authKeeper types.AccountKeeper, bankKeeper types.BankKeeper, - targetDenom string, - authority string, + targetDenom, authority string, ) Keeper { if addr := authKeeper.GetModuleAddress(types.ModuleName); addr == nil { panic(errors.New("fbridge module account has not been set")) } - if authority != types.DefaultAuthority().String() { - panic(errors.New("authority must be gov module")) + for _, addr := range types.AuthorityCandiates() { + if authority == addr.String() { + break + } + panic("x/bridge authority must be the gov or foundation module account") } return Keeper{ storeKey: key, + memKey: memKey, cdc: cdc, authKeeper: authKeeper, bankKeeper: bankKeeper, @@ -55,6 +59,108 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", "x/"+types.ModuleName) } +func (k Keeper) InitMemStore(ctx sdk.Context) { + memStore := ctx.KVStore(k.memKey) + memStoreType := memStore.GetStoreType() + if memStoreType != sdk.StoreTypeMemory { + panic(fmt.Sprintf("invalid memory store type; got %s, expected: %s", memStoreType, sdk.StoreTypeMemory)) + } + + // create context with no block gas meter to ensure we do not consume gas during local initialization logic. + noGasCtx := ctx.WithBlockGasMeter(sdk.NewInfiniteGasMeter()) + + roleMetadata := types.RoleMetadata{} + if !k.IsInitialized(noGasCtx) { + for _, pair := range k.GetRolePairs(noGasCtx) { + switch pair.Role { + case types.RoleGuardian: + roleMetadata.Guardian++ + case types.RoleOperator: + roleMetadata.Operator++ + case types.RoleJudge: + roleMetadata.Judge++ + } + } + k.setRoleMetadata(noGasCtx, roleMetadata) + + nInactive := uint64(0) + for _, bs := range k.GetBridgeSwitches(ctx) { + if bs.Status == types.StatusInactive { + nInactive++ + } + } + k.setBridgeInactiveCounter(noGasCtx, nInactive) + + memStore := noGasCtx.KVStore(k.memKey) + memStore.Set(types.KeyMemInitialized, []byte{1}) + } +} + +// IsInitialized returns true if the keeper is properly initialized, and false otherwise. +func (k Keeper) IsInitialized(ctx sdk.Context) bool { + memStore := ctx.KVStore(k.memKey) + return memStore.Get(types.KeyMemInitialized) != nil +} + func (k Keeper) GetAuthority() string { return k.authority } + +func (k Keeper) IsBridgeHalted(ctx sdk.Context) bool { + return k.GetBridgeStatus(ctx) == types.StatusInactive +} + +func (k Keeper) setRoleMetadata(ctx sdk.Context, data types.RoleMetadata) { + memStore := ctx.KVStore(k.memKey) + bz := k.cdc.MustMarshal(&data) + memStore.Set(types.KeyMemRoleMetadata, bz) +} + +func (k Keeper) GetRoleMetadata(ctx sdk.Context) types.RoleMetadata { + memStore := ctx.KVStore(k.memKey) + data := types.RoleMetadata{} + bz := memStore.Get(types.KeyMemRoleMetadata) + if bz == nil { + return types.RoleMetadata{} + } + k.cdc.MustUnmarshal(bz, &data) + return data +} + +func (k Keeper) GetBridgeStatus(ctx sdk.Context) types.BridgeStatus { + roleMeta := k.GetRoleMetadata(ctx) + if roleMeta.Guardian != 0 { + bsMeta := k.GetBridgeStatusMetadata(ctx) + if types.CheckTrustLevelThreshold(roleMeta.Guardian, bsMeta.Inactive, k.GetParams(ctx).GuardianTrustLevel) { + return types.StatusInactive + } + + return types.StatusActive + } + + return types.StatusInactive +} + +func (k Keeper) setBridgeInactiveCounter(ctx sdk.Context, nInactive uint64) { + memStore := ctx.KVStore(k.memKey) + bz := make([]byte, 8) + binary.BigEndian.PutUint64(bz, nInactive) + memStore.Set(types.KeyMemBridgeInactiveCounter, bz) +} + +func (k Keeper) GetBridgeInactiveCounter(ctx sdk.Context) uint64 { + memStore := ctx.KVStore(k.memKey) + bz := memStore.Get(types.KeyMemBridgeInactiveCounter) + if bz == nil { + panic("bridge inactive counter must be set at initialization") + } + + return binary.BigEndian.Uint64(bz) +} + +func (k Keeper) GetBridgeStatusMetadata(ctx sdk.Context) types.BridgeStatusMetadata { + bsMeta := types.BridgeStatusMetadata{} + bsMeta.Inactive = k.GetBridgeInactiveCounter(ctx) + bsMeta.Active = k.GetRoleMetadata(ctx).Guardian - bsMeta.Inactive + return bsMeta +} diff --git a/x/fbridge/keeper/msg_server.go b/x/fbridge/keeper/msg_server.go index 491f57c632..5f6775f4bc 100644 --- a/x/fbridge/keeper/msg_server.go +++ b/x/fbridge/keeper/msg_server.go @@ -21,6 +21,10 @@ func NewMsgServer(k Keeper) types.MsgServer { func (m msgServer) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types.MsgTransferResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) + if m.IsBridgeHalted(ctx) { + return nil, types.ErrInactiveBridge + } + from, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid sender address (%s)", err) @@ -48,41 +52,94 @@ func (m msgServer) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*typ } func (m msgServer) Provision(ctx context.Context, msg *types.MsgProvision) (*types.MsgProvisionResponse, error) { - panic("implement me") + panic(sdkerrors.ErrNotSupported) } func (m msgServer) HoldTransfer(ctx context.Context, msg *types.MsgHoldTransfer) (*types.MsgHoldTransferResponse, error) { - panic("implement me") + panic(sdkerrors.ErrNotSupported) } func (m msgServer) ReleaseTransfer(ctx context.Context, msg *types.MsgReleaseTransfer) (*types.MsgReleaseTransferResponse, error) { - panic("implement me") + panic(sdkerrors.ErrNotSupported) } func (m msgServer) RemoveProvision(ctx context.Context, msg *types.MsgRemoveProvision) (*types.MsgRemoveProvisionResponse, error) { - panic("implement me") + panic(sdkerrors.ErrNotSupported) } func (m msgServer) ClaimBatch(ctx context.Context, msg *types.MsgClaimBatch) (*types.MsgClaimBatchResponse, error) { - panic("implement me") + panic(sdkerrors.ErrNotSupported) } func (m msgServer) Claim(ctx context.Context, msg *types.MsgClaim) (*types.MsgClaimResponse, error) { - panic("implement me") + panic(sdkerrors.ErrNotSupported) } -func (m msgServer) SuggestRole(ctx context.Context, msg *types.MsgSuggestRole) (*types.MsgSuggestRoleResponse, error) { - panic("implement me") -} +func (m msgServer) SuggestRole(goCtx context.Context, msg *types.MsgSuggestRole) (*types.MsgSuggestRoleResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + proposer, err := sdk.AccAddressFromBech32(msg.From) + if err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid proposer address (%s)", err) + } + + target, err := sdk.AccAddressFromBech32(msg.Target) + if err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid target address (%s)", err) + } + + if err := types.IsValidRole(msg.Role); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error()) + } + + proposal, err := m.RegisterRoleProposal(ctx, proposer, target, msg.Role) + if err != nil { + return nil, err + } + + if err := ctx.EventManager().EmitTypedEvent(&types.EventSuggestRole{ + Proposal: proposal, + }); err != nil { + panic(err) + } -func (m msgServer) AddVoteForRole(ctx context.Context, msg *types.MsgAddVoteForRole) (*types.MsgAddVoteForRoleResponse, error) { - panic("implement me") + return &types.MsgSuggestRoleResponse{}, nil } -func (m msgServer) Halt(ctx context.Context, msg *types.MsgHalt) (*types.MsgHaltResponse, error) { - panic("implement me") +func (m msgServer) AddVoteForRole(goCtx context.Context, msg *types.MsgAddVoteForRole) (*types.MsgAddVoteForRoleResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + voter, err := sdk.AccAddressFromBech32(msg.From) + if err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid proposer address (%s)", err) + } + + if err := m.addVote(ctx, msg.ProposalId, voter, msg.Option); err != nil { + return nil, err + } + + if err := ctx.EventManager().EmitTypedEvent(&types.EventAddVoteForRole{ + Voter: msg.From, + ProposalId: msg.ProposalId, + Option: msg.Option, + }); err != nil { + panic(err) + } + + return &types.MsgAddVoteForRoleResponse{}, nil } -func (m msgServer) Resume(ctx context.Context, resume *types.MsgResume) (*types.MsgResumeResponse, error) { - panic("implement me") +func (m msgServer) SetBridgeStatus(goCtx context.Context, msg *types.MsgSetBridgeStatus) (*types.MsgSetBridgeStatusResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + addr, err := sdk.AccAddressFromBech32(msg.Guardian) + if err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid guardian address (%s)", err) + } + + if err := m.updateBridgeSwitch(ctx, addr, msg.Status); err != nil { + return nil, err + } + + return &types.MsgSetBridgeStatusResponse{}, nil } diff --git a/x/fbridge/keeper/params.go b/x/fbridge/keeper/params.go new file mode 100644 index 0000000000..dcbfc093d7 --- /dev/null +++ b/x/fbridge/keeper/params.go @@ -0,0 +1,24 @@ +package keeper + +import ( + sdk "github.com/Finschia/finschia-sdk/types" + "github.com/Finschia/finschia-sdk/x/fbridge/types" +) + +func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(¶ms) + store.Set(types.KeyParams, bz) +} + +func (k Keeper) GetParams(ctx sdk.Context) types.Params { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.KeyParams) + if bz == nil { + return types.DefaultParams() + } + + var params types.Params + k.cdc.MustUnmarshal(bz, ¶ms) + return params +} diff --git a/x/fbridge/keeper/transfer_test.go b/x/fbridge/keeper/transfer_test.go index ac0743ad98..4466e3d06c 100644 --- a/x/fbridge/keeper/transfer_test.go +++ b/x/fbridge/keeper/transfer_test.go @@ -7,26 +7,23 @@ import ( "github.com/stretchr/testify/require" sdk "github.com/Finschia/finschia-sdk/types" - authtypes "github.com/Finschia/finschia-sdk/x/auth/types" "github.com/Finschia/finschia-sdk/x/fbridge/testutil" "github.com/Finschia/finschia-sdk/x/fbridge/types" ) func TestHandleBridgeTransfer(t *testing.T) { - key, ctx, encCfg, authKeeper, bankKeeper := testutil.PrepareFbridgeTest(t) + key, memKey, ctx, encCfg, authKeeper, bankKeeper, _ := testutil.PrepareFbridgeTest(t, 0) sender := sdk.AccAddress("test") amt := sdk.NewInt(1000000) denom := "stake" token := sdk.Coins{sdk.Coin{Denom: denom, Amount: amt}} - bridge := authtypes.NewEmptyModuleAccount("fbridge") - authKeeper.EXPECT().GetModuleAddress(types.ModuleName).Return(bridge.GetAddress()).AnyTimes() bankKeeper.EXPECT().IsSendEnabledCoins(ctx, token).Return(nil) bankKeeper.EXPECT().SendCoinsFromAccountToModule(ctx, sender, types.ModuleName, token).Return(nil) bankKeeper.EXPECT().BurnCoins(ctx, types.ModuleName, token).Return(nil) - k := NewKeeper(encCfg.Codec, key, authKeeper, bankKeeper, denom, authtypes.NewModuleAddress("gov").String()) + k := NewKeeper(encCfg.Codec, key, memKey, authKeeper, bankKeeper, denom, types.DefaultAuthority().String()) targetSeq := uint64(2) bz := make([]byte, 8) binary.BigEndian.PutUint64(bz, targetSeq) diff --git a/x/fbridge/module/module.go b/x/fbridge/module/module.go index e7f7cfc28c..72d43c88f3 100644 --- a/x/fbridge/module/module.go +++ b/x/fbridge/module/module.go @@ -24,9 +24,11 @@ const ( ) var ( - _ module.AppModuleBasic = AppModuleBasic{} - _ module.AppModuleGenesis = AppModule{} - _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} + _ module.AppModuleGenesis = AppModule{} + _ module.AppModule = AppModule{} + _ module.BeginBlockAppModule = AppModule{} + _ module.EndBlockAppModule = AppModule{} ) // AppModuleBasic defines the basic application module used by the fbridge module. @@ -87,7 +89,7 @@ type AppModule struct { } // NewAppModule creates a new AppModule object -func NewAppModule(cdc codec.Codec, keeper keeper.Keeper) AppModule { +func NewAppModule(_ codec.Codec, keeper keeper.Keeper) AppModule { return AppModule{ keeper: keeper, } @@ -121,9 +123,21 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw // ConsensusVersion implements AppModule/ConsensusVersion. func (AppModule) ConsensusVersion() uint64 { return consensusVersion } +// BeginBlock returns the begin blocker for the fbridge module. +func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { + am.keeper.BeginBlocker(ctx) +} + +// EndBlock returns the end blocker for the fbridge module. +// It returns no validator updates. +func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + am.keeper.EndBlocker(ctx) + return []abci.ValidatorUpdate{} +} + // RegisterInvariants does nothing, there are no invariants to enforce func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { - _ = ir + keeper.RegisterInvariants(ir, am.keeper) } // Deprecated: Route does nothing. diff --git a/x/fbridge/testutil/setup.go b/x/fbridge/testutil/setup.go index 029772fac0..a7258e9cf8 100644 --- a/x/fbridge/testutil/setup.go +++ b/x/fbridge/testutil/setup.go @@ -12,19 +12,22 @@ import ( "github.com/Finschia/finschia-sdk/client" "github.com/Finschia/finschia-sdk/codec" codectypes "github.com/Finschia/finschia-sdk/codec/types" + "github.com/Finschia/finschia-sdk/crypto/keys/secp256k1" "github.com/Finschia/finschia-sdk/std" "github.com/Finschia/finschia-sdk/store" storetypes "github.com/Finschia/finschia-sdk/store/types" sdk "github.com/Finschia/finschia-sdk/types" "github.com/Finschia/finschia-sdk/x/auth/tx" + authtypes "github.com/Finschia/finschia-sdk/x/auth/types" "github.com/Finschia/finschia-sdk/x/fbridge/types" ) -func DefaultContextWithDB(tb testing.TB, key, tkey storetypes.StoreKey) sdk.Context { +func DefaultContextWithDB(tb testing.TB, key, mkey, tkey storetypes.StoreKey) sdk.Context { tb.Helper() db := dbm.NewMemDB() cms := store.NewCommitMultiStore(db) cms.MountStoreWithDB(key, storetypes.StoreTypeIAVL, db) + cms.MountStoreWithDB(mkey, storetypes.StoreTypeMemory, db) cms.MountStoreWithDB(tkey, storetypes.StoreTypeTransient, db) err := cms.LoadLatestVersion() assert.NoError(tb, err) @@ -60,16 +63,23 @@ func MakeTestEncodingConfig() TestEncodingConfig { return encCfg } -func PrepareFbridgeTest(tb testing.TB) (*sdk.KVStoreKey, sdk.Context, TestEncodingConfig, *MockAccountKeeper, *MockBankKeeper) { +func PrepareFbridgeTest(tb testing.TB, n int) (*sdk.KVStoreKey, *sdk.MemoryStoreKey, sdk.Context, TestEncodingConfig, *MockAccountKeeper, *MockBankKeeper, []sdk.AccAddress) { tb.Helper() ctrl := gomock.NewController(tb) key := storetypes.NewKVStoreKey(types.StoreKey) - ctx := DefaultContextWithDB(tb, key, sdk.NewTransientStoreKey("transient_test")) + memKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + ctx := DefaultContextWithDB(tb, key, memKey, sdk.NewTransientStoreKey("transient_test")) encCfg := MakeTestEncodingConfig() authKeeper := NewMockAccountKeeper(ctrl) + authKeeper.EXPECT().GetModuleAddress(types.ModuleName).Return(authtypes.NewEmptyModuleAccount("fbridge").GetAddress()).AnyTimes() bankKeeper := NewMockBankKeeper(ctrl) - return key, ctx, encCfg, authKeeper, bankKeeper + addrs := make([]sdk.AccAddress, n) + for i := 0; i < n; i++ { + addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + } + + return key, memKey, ctx, encCfg, authKeeper, bankKeeper, addrs } diff --git a/x/fbridge/types/codec.go b/x/fbridge/types/codec.go index c2edd215be..745a212112 100644 --- a/x/fbridge/types/codec.go +++ b/x/fbridge/types/codec.go @@ -22,8 +22,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { legacy.RegisterAminoMsg(cdc, &MsgClaim{}, "lbm-sdk/MsgClaim") legacy.RegisterAminoMsg(cdc, &MsgSuggestRole{}, "lbm-sdk/MsgSuggestRole") legacy.RegisterAminoMsg(cdc, &MsgAddVoteForRole{}, "lbm-sdk/MsgAddVoteForRole") - legacy.RegisterAminoMsg(cdc, &MsgHalt{}, "lbm-sdk/MsgHalt") - legacy.RegisterAminoMsg(cdc, &MsgResume{}, "lbm-sdk/MsgResume") + legacy.RegisterAminoMsg(cdc, &MsgSetBridgeStatus{}, "lbm-sdk/MsgSetBridgeStatus") } func RegisterInterfaces(registrar types.InterfaceRegistry) { @@ -38,8 +37,7 @@ func RegisterInterfaces(registrar types.InterfaceRegistry) { &MsgClaim{}, &MsgSuggestRole{}, &MsgAddVoteForRole{}, - &MsgHalt{}, - &MsgResume{}, + &MsgSetBridgeStatus{}, ) msgservice.RegisterMsgServiceDesc(registrar, &_Msg_serviceDesc) diff --git a/x/fbridge/types/errors.go b/x/fbridge/types/errors.go new file mode 100644 index 0000000000..9a8b1e2db0 --- /dev/null +++ b/x/fbridge/types/errors.go @@ -0,0 +1,9 @@ +package types + +import sdkerrors "github.com/Finschia/finschia-sdk/types/errors" + +var ( + ErrUnknownProposal = sdkerrors.Register(ModuleName, 2, "unknown proposal") + ErrUnknownVote = sdkerrors.Register(ModuleName, 3, "unknown vote") + ErrInactiveBridge = sdkerrors.Register(ModuleName, 4, "the bridge has halted") +) diff --git a/x/fbridge/types/event.pb.go b/x/fbridge/types/event.pb.go index 0749710deb..e82390f62a 100644 --- a/x/fbridge/types/event.pb.go +++ b/x/fbridge/types/event.pb.go @@ -5,6 +5,7 @@ package types import ( fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" io "io" math "math" @@ -94,6 +95,113 @@ func (m *EventTransfer) GetAmount() string { return "" } +type EventSuggestRole struct { + Proposal RoleProposal `protobuf:"bytes,1,opt,name=proposal,proto3" json:"proposal"` +} + +func (m *EventSuggestRole) Reset() { *m = EventSuggestRole{} } +func (m *EventSuggestRole) String() string { return proto.CompactTextString(m) } +func (*EventSuggestRole) ProtoMessage() {} +func (*EventSuggestRole) Descriptor() ([]byte, []int) { + return fileDescriptor_a36aa6e56f2275b8, []int{1} +} +func (m *EventSuggestRole) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventSuggestRole) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventSuggestRole.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 *EventSuggestRole) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventSuggestRole.Merge(m, src) +} +func (m *EventSuggestRole) XXX_Size() int { + return m.Size() +} +func (m *EventSuggestRole) XXX_DiscardUnknown() { + xxx_messageInfo_EventSuggestRole.DiscardUnknown(m) +} + +var xxx_messageInfo_EventSuggestRole proto.InternalMessageInfo + +func (m *EventSuggestRole) GetProposal() RoleProposal { + if m != nil { + return m.Proposal + } + return RoleProposal{} +} + +type EventAddVoteForRole struct { + // the voter address + Voter string `protobuf:"bytes,1,opt,name=voter,proto3" json:"voter,omitempty"` + // the role proposal id + ProposalId uint64 `protobuf:"varint,2,opt,name=proposal_id,json=proposalId,proto3" json:"proposal_id,omitempty"` + // the vote option + Option VoteOption `protobuf:"varint,3,opt,name=option,proto3,enum=lbm.fbridge.v1.VoteOption" json:"option,omitempty"` +} + +func (m *EventAddVoteForRole) Reset() { *m = EventAddVoteForRole{} } +func (m *EventAddVoteForRole) String() string { return proto.CompactTextString(m) } +func (*EventAddVoteForRole) ProtoMessage() {} +func (*EventAddVoteForRole) Descriptor() ([]byte, []int) { + return fileDescriptor_a36aa6e56f2275b8, []int{2} +} +func (m *EventAddVoteForRole) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventAddVoteForRole) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventAddVoteForRole.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 *EventAddVoteForRole) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventAddVoteForRole.Merge(m, src) +} +func (m *EventAddVoteForRole) XXX_Size() int { + return m.Size() +} +func (m *EventAddVoteForRole) XXX_DiscardUnknown() { + xxx_messageInfo_EventAddVoteForRole.DiscardUnknown(m) +} + +var xxx_messageInfo_EventAddVoteForRole proto.InternalMessageInfo + +func (m *EventAddVoteForRole) GetVoter() string { + if m != nil { + return m.Voter + } + return "" +} + +func (m *EventAddVoteForRole) GetProposalId() uint64 { + if m != nil { + return m.ProposalId + } + return 0 +} + +func (m *EventAddVoteForRole) GetOption() VoteOption { + if m != nil { + return m.Option + } + return OptionEmpty +} + type EventProvision struct { // the sequence number of the bridge request Seq uint64 `protobuf:"varint,1,opt,name=seq,proto3" json:"seq,omitempty"` @@ -111,7 +219,7 @@ func (m *EventProvision) Reset() { *m = EventProvision{} } func (m *EventProvision) String() string { return proto.CompactTextString(m) } func (*EventProvision) ProtoMessage() {} func (*EventProvision) Descriptor() ([]byte, []int) { - return fileDescriptor_a36aa6e56f2275b8, []int{1} + return fileDescriptor_a36aa6e56f2275b8, []int{3} } func (m *EventProvision) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -184,7 +292,7 @@ func (m *EventConfirmProvision) Reset() { *m = EventConfirmProvision{} } func (m *EventConfirmProvision) String() string { return proto.CompactTextString(m) } func (*EventConfirmProvision) ProtoMessage() {} func (*EventConfirmProvision) Descriptor() ([]byte, []int) { - return fileDescriptor_a36aa6e56f2275b8, []int{2} + return fileDescriptor_a36aa6e56f2275b8, []int{4} } func (m *EventConfirmProvision) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -235,7 +343,7 @@ func (m *EventClaim) Reset() { *m = EventClaim{} } func (m *EventClaim) String() string { return proto.CompactTextString(m) } func (*EventClaim) ProtoMessage() {} func (*EventClaim) Descriptor() ([]byte, []int) { - return fileDescriptor_a36aa6e56f2275b8, []int{3} + return fileDescriptor_a36aa6e56f2275b8, []int{5} } func (m *EventClaim) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -294,6 +402,8 @@ func (m *EventClaim) GetAmount() string { func init() { proto.RegisterType((*EventTransfer)(nil), "lbm.fbridge.v1.EventTransfer") + proto.RegisterType((*EventSuggestRole)(nil), "lbm.fbridge.v1.EventSuggestRole") + proto.RegisterType((*EventAddVoteForRole)(nil), "lbm.fbridge.v1.EventAddVoteForRole") proto.RegisterType((*EventProvision)(nil), "lbm.fbridge.v1.EventProvision") proto.RegisterType((*EventConfirmProvision)(nil), "lbm.fbridge.v1.EventConfirmProvision") proto.RegisterType((*EventClaim)(nil), "lbm.fbridge.v1.EventClaim") @@ -302,25 +412,33 @@ func init() { func init() { proto.RegisterFile("lbm/fbridge/v1/event.proto", fileDescriptor_a36aa6e56f2275b8) } var fileDescriptor_a36aa6e56f2275b8 = []byte{ - // 276 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x91, 0xbd, 0x4e, 0xc3, 0x30, - 0x10, 0xc7, 0x63, 0x5a, 0x2a, 0xb0, 0x44, 0x85, 0x22, 0x81, 0xa2, 0x0e, 0x56, 0x95, 0xa9, 0x0c, - 0xc4, 0x54, 0xbc, 0x01, 0x08, 0x06, 0x26, 0x54, 0x31, 0xb1, 0xe5, 0xe3, 0xd2, 0x1a, 0x62, 0x3b, - 0x9c, 0x5d, 0x0b, 0x5e, 0x81, 0x89, 0xc7, 0x62, 0xec, 0xc8, 0x88, 0x92, 0x17, 0x41, 0xf9, 0xa0, - 0x63, 0xb7, 0x6e, 0xf7, 0xd3, 0xff, 0x7e, 0xba, 0xbf, 0x74, 0x74, 0x52, 0x24, 0x92, 0xe7, 0x09, - 0x8a, 0x6c, 0x09, 0xdc, 0xcd, 0x39, 0x38, 0x50, 0x36, 0x2a, 0x51, 0x5b, 0xed, 0x8f, 0x8b, 0x44, - 0x46, 0x7d, 0x16, 0xb9, 0x79, 0x28, 0xe9, 0xc9, 0x5d, 0x13, 0x3f, 0x61, 0xac, 0x4c, 0x0e, 0xe8, - 0x9f, 0xd2, 0x81, 0x81, 0xb7, 0x80, 0x4c, 0xc9, 0x6c, 0xb8, 0x68, 0x46, 0xff, 0x9c, 0x8e, 0x0c, - 0xa8, 0x0c, 0x30, 0x38, 0x98, 0x92, 0xd9, 0xf1, 0xa2, 0x27, 0x7f, 0x42, 0x8f, 0x10, 0x52, 0x10, - 0x0e, 0x30, 0x18, 0xb4, 0xc9, 0x96, 0x1b, 0x27, 0x96, 0x7a, 0xad, 0x6c, 0x30, 0xec, 0x9c, 0x8e, - 0xc2, 0x4f, 0x42, 0xc7, 0xed, 0xbd, 0x47, 0xd4, 0x4e, 0x18, 0xa1, 0xd5, 0x7e, 0x0f, 0x36, 0x8e, - 0x2e, 0x01, 0x63, 0xab, 0x31, 0x38, 0xec, 0x9c, 0x7f, 0x0e, 0x2f, 0xe8, 0x59, 0xdb, 0xe5, 0x56, - 0xab, 0x5c, 0xa0, 0xdc, 0x51, 0x29, 0x7c, 0xa1, 0xb4, 0x5b, 0x2d, 0x62, 0x21, 0xf7, 0x5b, 0xf9, - 0xe6, 0xe1, 0xbb, 0x62, 0x64, 0x53, 0x31, 0xf2, 0x5b, 0x31, 0xf2, 0x55, 0x33, 0x6f, 0x53, 0x33, - 0xef, 0xa7, 0x66, 0xde, 0xf3, 0xd5, 0x52, 0xd8, 0xd5, 0x3a, 0x89, 0x52, 0x2d, 0xf9, 0xbd, 0x50, - 0x26, 0x5d, 0x89, 0x98, 0xe7, 0xfd, 0x70, 0x69, 0xb2, 0x57, 0xfe, 0xbe, 0xfd, 0xbb, 0xfd, 0x28, - 0xc1, 0x24, 0xa3, 0xf6, 0xeb, 0xd7, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x3b, 0x5f, 0xda, 0xeb, - 0x13, 0x02, 0x00, 0x00, + // 408 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x52, 0x3d, 0x6f, 0xd4, 0x40, + 0x10, 0xf5, 0x12, 0xe7, 0x94, 0x4c, 0xc4, 0x29, 0x32, 0x01, 0x59, 0x56, 0xe4, 0x44, 0xae, 0x42, + 0x81, 0x4d, 0x8e, 0x1e, 0x89, 0x20, 0x22, 0x41, 0x43, 0xb4, 0x20, 0x0a, 0x1a, 0x64, 0x9f, 0xc7, + 0xce, 0x82, 0xbd, 0x63, 0x76, 0xf7, 0x2c, 0xe8, 0xa8, 0xa9, 0xf8, 0x59, 0x29, 0x53, 0x52, 0x21, + 0x74, 0xf7, 0x47, 0x90, 0xd7, 0xf6, 0x49, 0x5c, 0x91, 0xee, 0xba, 0x79, 0x7e, 0x1f, 0xf3, 0xc6, + 0x5a, 0x08, 0xaa, 0xac, 0x4e, 0x8a, 0x4c, 0x89, 0xbc, 0xc4, 0xa4, 0x3d, 0x4f, 0xb0, 0x45, 0x69, + 0xe2, 0x46, 0x91, 0x21, 0x6f, 0x5a, 0x65, 0x75, 0x3c, 0x70, 0x71, 0x7b, 0x1e, 0x1c, 0x95, 0x54, + 0x92, 0xa5, 0x92, 0x6e, 0xea, 0x55, 0xc1, 0xf1, 0x46, 0xc2, 0x68, 0xb0, 0x6c, 0x54, 0xc3, 0xfd, + 0x57, 0x5d, 0xe4, 0x7b, 0x95, 0x4a, 0x5d, 0xa0, 0xf2, 0x0e, 0x61, 0x47, 0xe3, 0x57, 0x9f, 0x9d, + 0xb2, 0x33, 0x97, 0x77, 0xa3, 0xf7, 0x08, 0x26, 0x1a, 0x65, 0x8e, 0xca, 0xbf, 0x77, 0xca, 0xce, + 0xf6, 0xf9, 0x80, 0xbc, 0x00, 0xf6, 0x14, 0xce, 0x51, 0xb4, 0xa8, 0xfc, 0x1d, 0xcb, 0xac, 0x71, + 0xe7, 0x49, 0x6b, 0x5a, 0x48, 0xe3, 0xbb, 0xbd, 0xa7, 0x47, 0x11, 0x87, 0x43, 0xbb, 0xee, 0xdd, + 0xa2, 0x2c, 0x51, 0x1b, 0x4e, 0x15, 0x7a, 0xcf, 0x61, 0xaf, 0x51, 0xd4, 0x90, 0x4e, 0x2b, 0xbb, + 0xf6, 0x60, 0x76, 0x1c, 0xff, 0x7f, 0x59, 0xdc, 0xe9, 0xae, 0x06, 0xcd, 0x85, 0x7b, 0xf3, 0xe7, + 0xc4, 0xe1, 0x6b, 0x4f, 0xf4, 0x83, 0xc1, 0x03, 0x1b, 0xfa, 0x22, 0xcf, 0x3f, 0x90, 0xc1, 0x4b, + 0x52, 0x36, 0xf7, 0x08, 0x76, 0x5b, 0x32, 0xa8, 0x6c, 0xe8, 0x3e, 0xef, 0x81, 0x77, 0x02, 0x07, + 0xa3, 0xf3, 0x93, 0xc8, 0xed, 0x49, 0x2e, 0x87, 0xf1, 0xd3, 0xeb, 0xdc, 0x9b, 0xc1, 0x84, 0x1a, + 0x23, 0x48, 0xda, 0xa3, 0xa6, 0xb3, 0x60, 0xb3, 0x4c, 0xb7, 0xe3, 0xad, 0x55, 0xf0, 0x41, 0x19, + 0xfd, 0x64, 0x30, 0xb5, 0x15, 0xae, 0x14, 0xb5, 0x42, 0x0b, 0x92, 0xdb, 0xfd, 0x8f, 0x9d, 0x87, + 0x1a, 0x54, 0xa9, 0x21, 0xe5, 0xef, 0xf6, 0x9e, 0x11, 0x47, 0x8f, 0xe1, 0xa1, 0xed, 0xf2, 0x92, + 0x64, 0x21, 0x54, 0x7d, 0x47, 0xa5, 0xe8, 0x33, 0x40, 0x2f, 0xad, 0x52, 0x51, 0x6f, 0xb7, 0xf2, + 0xc5, 0x9b, 0x9b, 0x65, 0xc8, 0x6e, 0x97, 0x21, 0xfb, 0xbb, 0x0c, 0xd9, 0xaf, 0x55, 0xe8, 0xdc, + 0xae, 0x42, 0xe7, 0xf7, 0x2a, 0x74, 0x3e, 0x3e, 0x2d, 0x85, 0xb9, 0x5e, 0x64, 0xf1, 0x9c, 0xea, + 0xe4, 0x52, 0x48, 0x3d, 0xbf, 0x16, 0x69, 0x52, 0x0c, 0xc3, 0x13, 0x9d, 0x7f, 0x49, 0xbe, 0xad, + 0x1f, 0xb0, 0xf9, 0xde, 0xa0, 0xce, 0x26, 0xf6, 0xf1, 0x3e, 0xfb, 0x17, 0x00, 0x00, 0xff, 0xff, + 0x96, 0x66, 0x6c, 0xc3, 0x1e, 0x03, 0x00, 0x00, } func (m *EventTransfer) Marshal() (dAtA []byte, err error) { @@ -372,6 +490,79 @@ func (m *EventTransfer) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *EventSuggestRole) 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 *EventSuggestRole) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventSuggestRole) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Proposal.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvent(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *EventAddVoteForRole) 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 *EventAddVoteForRole) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventAddVoteForRole) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Option != 0 { + i = encodeVarintEvent(dAtA, i, uint64(m.Option)) + i-- + dAtA[i] = 0x18 + } + if m.ProposalId != 0 { + i = encodeVarintEvent(dAtA, i, uint64(m.ProposalId)) + i-- + dAtA[i] = 0x10 + } + if len(m.Voter) > 0 { + i -= len(m.Voter) + copy(dAtA[i:], m.Voter) + i = encodeVarintEvent(dAtA, i, uint64(len(m.Voter))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *EventProvision) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -540,6 +731,36 @@ func (m *EventTransfer) Size() (n int) { return n } +func (m *EventSuggestRole) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Proposal.Size() + n += 1 + l + sovEvent(uint64(l)) + return n +} + +func (m *EventAddVoteForRole) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Voter) + if l > 0 { + n += 1 + l + sovEvent(uint64(l)) + } + if m.ProposalId != 0 { + n += 1 + sovEvent(uint64(m.ProposalId)) + } + if m.Option != 0 { + n += 1 + sovEvent(uint64(m.Option)) + } + return n +} + func (m *EventProvision) Size() (n int) { if m == nil { return 0 @@ -775,6 +996,209 @@ func (m *EventTransfer) Unmarshal(dAtA []byte) error { } return nil } +func (m *EventSuggestRole) 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 ErrIntOverflowEvent + } + 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: EventSuggestRole: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventSuggestRole: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Proposal", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvent + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Proposal.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvent(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvent + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EventAddVoteForRole) 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 ErrIntOverflowEvent + } + 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: EventAddVoteForRole: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventAddVoteForRole: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Voter", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + 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 ErrInvalidLengthEvent + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Voter = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ProposalId", wireType) + } + m.ProposalId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ProposalId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Option", wireType) + } + m.Option = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Option |= VoteOption(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipEvent(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvent + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *EventProvision) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/fbridge/types/fbridge.go b/x/fbridge/types/fbridge.go new file mode 100644 index 0000000000..fa20ca542e --- /dev/null +++ b/x/fbridge/types/fbridge.go @@ -0,0 +1,39 @@ +package types + +import ( + "errors" +) + +var QueryParamToRole = map[string]Role{ + "unspecified": 0, + "guardian": 1, + "operator": 2, + "judge": 3, +} + +func IsValidRole(role Role) error { + switch role { + case RoleGuardian, RoleOperator, RoleJudge: + return nil + } + + return errors.New("unsupported role") +} + +func IsValidVoteOption(option VoteOption) error { + switch option { + case OptionYes, OptionNo: + return nil + } + + return errors.New("unsupported vote option") +} + +func IsValidBridgeStatus(status BridgeStatus) error { + switch status { + case StatusActive, StatusInactive: + return nil + } + + return errors.New("unsupported bridge status") +} diff --git a/x/fbridge/types/fbridge.pb.go b/x/fbridge/types/fbridge.pb.go index a9b8197a74..e81d70a81b 100644 --- a/x/fbridge/types/fbridge.pb.go +++ b/x/fbridge/types/fbridge.pb.go @@ -8,15 +8,19 @@ import ( github_com_Finschia_finschia_sdk_types "github.com/Finschia/finschia-sdk/types" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" + _ "google.golang.org/protobuf/types/known/timestamppb" io "io" math "math" math_bits "math/bits" + time "time" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf +var _ = time.Kitchen // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. @@ -28,10 +32,10 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type Role int32 const ( - Role_UNSPECIFIED Role = 0 - Role_GUARDIAN Role = 1 - Role_OPERATOR Role = 2 - Role_JUDGE Role = 3 + RoleEmpty Role = 0 + RoleGuardian Role = 1 + RoleOperator Role = 2 + RoleJudge Role = 3 ) var Role_name = map[int32]string{ @@ -56,6 +60,69 @@ func (Role) EnumDescriptor() ([]byte, []int) { return fileDescriptor_62374d75fc6aa1ba, []int{0} } +// VoteOption enumerates the valid vote options for a given role proposal. +type VoteOption int32 + +const ( + // VOTE_OPTION_UNSPECIFIED defines a no-op vote option. + OptionEmpty VoteOption = 0 + // VOTE_OPTION_YES defines a yes vote option. + OptionYes VoteOption = 1 + // VOTE_OPTION_NO defines a no vote option. + OptionNo VoteOption = 2 +) + +var VoteOption_name = map[int32]string{ + 0: "VOTE_OPTION_UNSPECIFIED", + 1: "VOTE_OPTION_YES", + 2: "VOTE_OPTION_NO", +} + +var VoteOption_value = map[string]int32{ + "VOTE_OPTION_UNSPECIFIED": 0, + "VOTE_OPTION_YES": 1, + "VOTE_OPTION_NO": 2, +} + +func (x VoteOption) String() string { + return proto.EnumName(VoteOption_name, int32(x)) +} + +func (VoteOption) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_62374d75fc6aa1ba, []int{1} +} + +type BridgeStatus int32 + +const ( + // BRIDGE_STATUS_UNSPECIFIED defines an unspecified bridge status. + StatusEmpty BridgeStatus = 0 + // BRIDGE_STATUS_ACTIVE defines an active bridge status. + StatusActive BridgeStatus = 1 + // BRIDGE_STATUS_INACTIVE defines an inactive bridge status. + StatusInactive BridgeStatus = 2 +) + +var BridgeStatus_name = map[int32]string{ + 0: "BRIDGE_STATUS_UNSPECIFIED", + 1: "BRIDGE_STATUS_ACTIVE", + 2: "BRIDGE_STATUS_INACTIVE", +} + +var BridgeStatus_value = map[string]int32{ + "BRIDGE_STATUS_UNSPECIFIED": 0, + "BRIDGE_STATUS_ACTIVE": 1, + "BRIDGE_STATUS_INACTIVE": 2, +} + +func (x BridgeStatus) String() string { + return proto.EnumName(BridgeStatus_name, int32(x)) +} + +func (BridgeStatus) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_62374d75fc6aa1ba, []int{2} +} + type Params struct { // ratio of how many operators' confirmations are needed to be valid. OperatorTrustLevel Fraction `protobuf:"bytes,1,opt,name=operator_trust_level,json=operatorTrustLevel,proto3" json:"operator_trust_level"` @@ -322,6 +389,58 @@ func (m *Fraction) GetDenominator() uint64 { return 0 } +type RolePair struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + Role Role `protobuf:"varint,2,opt,name=role,proto3,enum=lbm.fbridge.v1.Role" json:"role,omitempty"` +} + +func (m *RolePair) Reset() { *m = RolePair{} } +func (m *RolePair) String() string { return proto.CompactTextString(m) } +func (*RolePair) ProtoMessage() {} +func (*RolePair) Descriptor() ([]byte, []int) { + return fileDescriptor_62374d75fc6aa1ba, []int{4} +} +func (m *RolePair) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RolePair) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RolePair.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 *RolePair) XXX_Merge(src proto.Message) { + xxx_messageInfo_RolePair.Merge(m, src) +} +func (m *RolePair) XXX_Size() int { + return m.Size() +} +func (m *RolePair) XXX_DiscardUnknown() { + xxx_messageInfo_RolePair.DiscardUnknown(m) +} + +var xxx_messageInfo_RolePair proto.InternalMessageInfo + +func (m *RolePair) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *RolePair) GetRole() Role { + if m != nil { + return m.Role + } + return RoleEmpty +} + type RoleProposal struct { Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` // the proposer address @@ -335,14 +454,14 @@ type RoleProposal struct { // - judge : 3 Role Role `protobuf:"varint,4,opt,name=role,proto3,enum=lbm.fbridge.v1.Role" json:"role,omitempty"` // the unix timestamp the proposal will be expired (unix timestamp) - ExpiredAt uint64 `protobuf:"varint,5,opt,name=expired_at,json=expiredAt,proto3" json:"expired_at,omitempty"` + ExpiredAt time.Time `protobuf:"bytes,5,opt,name=expired_at,json=expiredAt,proto3,stdtime" json:"expired_at"` } func (m *RoleProposal) Reset() { *m = RoleProposal{} } func (m *RoleProposal) String() string { return proto.CompactTextString(m) } func (*RoleProposal) ProtoMessage() {} func (*RoleProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_62374d75fc6aa1ba, []int{4} + return fileDescriptor_62374d75fc6aa1ba, []int{5} } func (m *RoleProposal) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -396,68 +515,276 @@ func (m *RoleProposal) GetRole() Role { if m != nil { return m.Role } - return Role_UNSPECIFIED + return RoleEmpty } -func (m *RoleProposal) GetExpiredAt() uint64 { +func (m *RoleProposal) GetExpiredAt() time.Time { if m != nil { return m.ExpiredAt } + return time.Time{} +} + +// Vote defines a vote on a role proposal. +type Vote struct { + ProposalId uint64 `protobuf:"varint,1,opt,name=proposal_id,json=proposalId,proto3" json:"proposal_id,omitempty"` + Voter string `protobuf:"bytes,2,opt,name=voter,proto3" json:"voter,omitempty"` + Option VoteOption `protobuf:"varint,3,opt,name=option,proto3,enum=lbm.fbridge.v1.VoteOption" json:"option,omitempty"` +} + +func (m *Vote) Reset() { *m = Vote{} } +func (m *Vote) String() string { return proto.CompactTextString(m) } +func (*Vote) ProtoMessage() {} +func (*Vote) Descriptor() ([]byte, []int) { + return fileDescriptor_62374d75fc6aa1ba, []int{6} +} +func (m *Vote) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Vote) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Vote.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 *Vote) XXX_Merge(src proto.Message) { + xxx_messageInfo_Vote.Merge(m, src) +} +func (m *Vote) XXX_Size() int { + return m.Size() +} +func (m *Vote) XXX_DiscardUnknown() { + xxx_messageInfo_Vote.DiscardUnknown(m) +} + +var xxx_messageInfo_Vote proto.InternalMessageInfo + +func (m *Vote) GetProposalId() uint64 { + if m != nil { + return m.ProposalId + } + return 0 +} + +func (m *Vote) GetVoter() string { + if m != nil { + return m.Voter + } + return "" +} + +func (m *Vote) GetOption() VoteOption { + if m != nil { + return m.Option + } + return OptionEmpty +} + +// RoleMetadata defines the metadata of the role. +type RoleMetadata struct { + // the number of registered guardians + Guardian uint64 `protobuf:"varint,1,opt,name=guardian,proto3" json:"guardian,omitempty"` + // the number of the operators + Operator uint64 `protobuf:"varint,2,opt,name=operator,proto3" json:"operator,omitempty"` + // the number of the judges + Judge uint64 `protobuf:"varint,3,opt,name=judge,proto3" json:"judge,omitempty"` +} + +func (m *RoleMetadata) Reset() { *m = RoleMetadata{} } +func (m *RoleMetadata) String() string { return proto.CompactTextString(m) } +func (*RoleMetadata) ProtoMessage() {} +func (*RoleMetadata) Descriptor() ([]byte, []int) { + return fileDescriptor_62374d75fc6aa1ba, []int{7} +} +func (m *RoleMetadata) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RoleMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RoleMetadata.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 *RoleMetadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_RoleMetadata.Merge(m, src) +} +func (m *RoleMetadata) XXX_Size() int { + return m.Size() +} +func (m *RoleMetadata) XXX_DiscardUnknown() { + xxx_messageInfo_RoleMetadata.DiscardUnknown(m) +} + +var xxx_messageInfo_RoleMetadata proto.InternalMessageInfo + +func (m *RoleMetadata) GetGuardian() uint64 { + if m != nil { + return m.Guardian + } + return 0 +} + +func (m *RoleMetadata) GetOperator() uint64 { + if m != nil { + return m.Operator + } + return 0 +} + +func (m *RoleMetadata) GetJudge() uint64 { + if m != nil { + return m.Judge + } + return 0 +} + +// BridgeStatusMetadata defines the metadata of the bridge status. +type BridgeStatusMetadata struct { + // the number of inactived bridge switch + Inactive uint64 `protobuf:"varint,1,opt,name=inactive,proto3" json:"inactive,omitempty"` + // the number of activated bridge switch + Active uint64 `protobuf:"varint,2,opt,name=active,proto3" json:"active,omitempty"` +} + +func (m *BridgeStatusMetadata) Reset() { *m = BridgeStatusMetadata{} } +func (m *BridgeStatusMetadata) String() string { return proto.CompactTextString(m) } +func (*BridgeStatusMetadata) ProtoMessage() {} +func (*BridgeStatusMetadata) Descriptor() ([]byte, []int) { + return fileDescriptor_62374d75fc6aa1ba, []int{8} +} +func (m *BridgeStatusMetadata) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BridgeStatusMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BridgeStatusMetadata.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 *BridgeStatusMetadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_BridgeStatusMetadata.Merge(m, src) +} +func (m *BridgeStatusMetadata) XXX_Size() int { + return m.Size() +} +func (m *BridgeStatusMetadata) XXX_DiscardUnknown() { + xxx_messageInfo_BridgeStatusMetadata.DiscardUnknown(m) +} + +var xxx_messageInfo_BridgeStatusMetadata proto.InternalMessageInfo + +func (m *BridgeStatusMetadata) GetInactive() uint64 { + if m != nil { + return m.Inactive + } + return 0 +} + +func (m *BridgeStatusMetadata) GetActive() uint64 { + if m != nil { + return m.Active + } return 0 } func init() { proto.RegisterEnum("lbm.fbridge.v1.Role", Role_name, Role_value) + proto.RegisterEnum("lbm.fbridge.v1.VoteOption", VoteOption_name, VoteOption_value) + proto.RegisterEnum("lbm.fbridge.v1.BridgeStatus", BridgeStatus_name, BridgeStatus_value) proto.RegisterType((*Params)(nil), "lbm.fbridge.v1.Params") proto.RegisterType((*ProvisionData)(nil), "lbm.fbridge.v1.ProvisionData") proto.RegisterType((*ProvisionStatus)(nil), "lbm.fbridge.v1.ProvisionStatus") proto.RegisterType((*Fraction)(nil), "lbm.fbridge.v1.Fraction") + proto.RegisterType((*RolePair)(nil), "lbm.fbridge.v1.RolePair") proto.RegisterType((*RoleProposal)(nil), "lbm.fbridge.v1.RoleProposal") + proto.RegisterType((*Vote)(nil), "lbm.fbridge.v1.Vote") + proto.RegisterType((*RoleMetadata)(nil), "lbm.fbridge.v1.RoleMetadata") + proto.RegisterType((*BridgeStatusMetadata)(nil), "lbm.fbridge.v1.BridgeStatusMetadata") } func init() { proto.RegisterFile("lbm/fbridge/v1/fbridge.proto", fileDescriptor_62374d75fc6aa1ba) } var fileDescriptor_62374d75fc6aa1ba = []byte{ - // 614 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0x41, 0x4f, 0x1b, 0x3d, - 0x10, 0xcd, 0x86, 0x10, 0x65, 0x27, 0x90, 0xe4, 0xb3, 0xd0, 0x27, 0x84, 0x68, 0xa0, 0x91, 0xaa, - 0x22, 0xa4, 0x26, 0x85, 0xde, 0x2b, 0x05, 0x12, 0x50, 0xa2, 0x0a, 0x56, 0x06, 0x2e, 0xbd, 0x44, - 0xce, 0xae, 0x59, 0x5c, 0x76, 0xed, 0xad, 0xed, 0x8d, 0x68, 0x7f, 0x45, 0xef, 0x3d, 0xf5, 0xdf, - 0xa0, 0x9e, 0x38, 0x56, 0x3d, 0xa0, 0x0a, 0xfe, 0x48, 0x65, 0xef, 0x6e, 0x0a, 0xbd, 0x94, 0xdb, - 0xcc, 0xdb, 0x37, 0xcf, 0xcf, 0xcf, 0x93, 0xc0, 0x7a, 0x34, 0x8d, 0x7b, 0xe7, 0x53, 0xc9, 0x82, - 0x90, 0xf6, 0x66, 0x3b, 0x45, 0xd9, 0x4d, 0xa4, 0xd0, 0x02, 0x35, 0xa2, 0x69, 0xdc, 0x2d, 0xa0, - 0xd9, 0xce, 0xda, 0x4a, 0x28, 0x42, 0x61, 0x3f, 0xf5, 0x4c, 0x95, 0xb1, 0x3a, 0xdf, 0xcb, 0x50, - 0xf5, 0x88, 0x24, 0xb1, 0x42, 0x1e, 0xac, 0x88, 0x84, 0x4a, 0xa2, 0x85, 0x9c, 0x68, 0x99, 0x2a, - 0x3d, 0x89, 0xe8, 0x8c, 0x46, 0xab, 0xce, 0xa6, 0xb3, 0x55, 0xdf, 0x5d, 0xed, 0x3e, 0xd6, 0xeb, - 0x1e, 0x48, 0xe2, 0x6b, 0x26, 0xf8, 0x5e, 0xe5, 0xfa, 0x76, 0xa3, 0x84, 0x51, 0x31, 0x7b, 0x6a, - 0x46, 0xdf, 0x99, 0x49, 0xa3, 0x18, 0xa6, 0x44, 0x06, 0x8c, 0xf0, 0x47, 0x8a, 0xe5, 0xa7, 0x29, - 0x16, 0xb3, 0x0f, 0x14, 0xc7, 0xf0, 0xdf, 0x87, 0x34, 0x08, 0xe9, 0x23, 0xb9, 0x85, 0x27, 0xc9, - 0x35, 0xed, 0xe0, 0x03, 0xad, 0x97, 0xd0, 0xd4, 0x2c, 0xa6, 0x91, 0xf0, 0x2f, 0x27, 0x09, 0x95, - 0x4c, 0x04, 0xab, 0x95, 0x4d, 0x67, 0xab, 0x82, 0x1b, 0x05, 0xec, 0x59, 0xd4, 0x10, 0x13, 0x29, - 0x12, 0xa1, 0x48, 0x54, 0x10, 0x17, 0x33, 0x62, 0x01, 0x67, 0xc4, 0xce, 0x37, 0x07, 0x96, 0x3d, - 0x29, 0x66, 0x4c, 0x31, 0xc1, 0x07, 0x44, 0x13, 0xd4, 0x82, 0x05, 0x45, 0x3f, 0xda, 0x08, 0x2b, - 0xd8, 0x94, 0x68, 0x0c, 0x55, 0x12, 0x8b, 0x94, 0x6b, 0x9b, 0x82, 0xbb, 0xb7, 0x6b, 0xcc, 0xfd, - 0xbc, 0xdd, 0xd8, 0x0e, 0x99, 0xbe, 0x48, 0xa7, 0x5d, 0x5f, 0xc4, 0xbd, 0x03, 0xc6, 0x95, 0x7f, - 0xc1, 0x48, 0xef, 0x3c, 0x2f, 0x5e, 0xa9, 0xe0, 0xb2, 0xa7, 0x3f, 0x25, 0x54, 0x75, 0x47, 0x5c, - 0xe3, 0x5c, 0x01, 0xfd, 0x0f, 0x55, 0x45, 0x79, 0x40, 0xa5, 0x8d, 0xc0, 0xc5, 0x79, 0x87, 0xd6, - 0xa0, 0x26, 0xa9, 0x4f, 0xd9, 0x8c, 0x4a, 0x7b, 0x25, 0x17, 0xcf, 0xfb, 0xce, 0x67, 0x68, 0xce, - 0x2d, 0x9e, 0x68, 0xa2, 0x53, 0x85, 0x9e, 0xc3, 0xd2, 0x3c, 0x08, 0xca, 0x83, 0xdc, 0x6d, 0xbd, - 0xc0, 0x86, 0x3c, 0x40, 0x2f, 0xa0, 0xe1, 0x0b, 0x7e, 0xce, 0x64, 0x3c, 0xf1, 0xcd, 0xd1, 0xca, - 0xba, 0x5f, 0xc4, 0xcb, 0x39, 0xba, 0x6f, 0x41, 0xf4, 0x0c, 0x80, 0xa9, 0x89, 0x1f, 0x11, 0x16, - 0xd3, 0xc0, 0x9a, 0xaa, 0x61, 0x97, 0xa9, 0xfd, 0x0c, 0xe8, 0x8c, 0xa1, 0x56, 0x3c, 0x0a, 0x5a, - 0x07, 0x97, 0xa7, 0x71, 0xb6, 0x32, 0xf9, 0x89, 0x7f, 0x00, 0xb4, 0x09, 0xf5, 0x80, 0x72, 0x11, - 0x33, 0x6e, 0xbf, 0x97, 0x33, 0x47, 0x0f, 0xa0, 0xce, 0x57, 0x07, 0x96, 0xb0, 0x88, 0xa8, 0x97, - 0x3f, 0x01, 0x6a, 0x40, 0x99, 0x15, 0xde, 0xcb, 0x2c, 0x30, 0x21, 0x64, 0xcf, 0x43, 0xb3, 0x79, - 0x17, 0xcf, 0x7b, 0x13, 0x9c, 0x26, 0x32, 0xa4, 0xba, 0x08, 0x2e, 0xeb, 0xd0, 0x16, 0x54, 0xa4, - 0x88, 0xa8, 0x0d, 0xad, 0xb1, 0xbb, 0xf2, 0xf7, 0x46, 0x99, 0xf3, 0xb0, 0x65, 0x98, 0x9b, 0xd2, - 0xab, 0x84, 0x49, 0x1a, 0x4c, 0x88, 0xce, 0xd7, 0xc1, 0xcd, 0x91, 0xbe, 0xde, 0x7e, 0x0b, 0x15, - 0x43, 0x46, 0x4d, 0xa8, 0x9f, 0x1d, 0x9d, 0x78, 0xc3, 0xfd, 0xd1, 0xc1, 0x68, 0x38, 0x68, 0x95, - 0xd0, 0x12, 0xd4, 0x0e, 0xcf, 0xfa, 0x78, 0x30, 0xea, 0x1f, 0xb5, 0x1c, 0xd3, 0x1d, 0x7b, 0x43, - 0xdc, 0x3f, 0x3d, 0xc6, 0xad, 0x32, 0x72, 0x61, 0x71, 0x7c, 0x36, 0x38, 0x1c, 0xb6, 0x16, 0xf6, - 0xc6, 0xd7, 0x77, 0x6d, 0xe7, 0xe6, 0xae, 0xed, 0xfc, 0xba, 0x6b, 0x3b, 0x5f, 0xee, 0xdb, 0xa5, - 0x9b, 0xfb, 0x76, 0xe9, 0xc7, 0x7d, 0xbb, 0xf4, 0xfe, 0xf5, 0x3f, 0xf7, 0xe4, 0x6a, 0xfe, 0x9f, - 0x60, 0x37, 0x66, 0x5a, 0xb5, 0xbf, 0xf4, 0x37, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x74, 0xf3, - 0xa0, 0x53, 0x2f, 0x04, 0x00, 0x00, + // 973 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0x4f, 0x6f, 0xe3, 0x44, + 0x14, 0x8f, 0xb3, 0x6e, 0x49, 0x5e, 0xda, 0x34, 0x8c, 0xa2, 0xa5, 0x58, 0x4b, 0x12, 0x22, 0x21, + 0xaa, 0x0a, 0x1c, 0x36, 0xdc, 0xb8, 0x25, 0xad, 0x5b, 0x39, 0x82, 0x24, 0x72, 0xd3, 0x4a, 0x8b, + 0x90, 0x22, 0x27, 0x9e, 0x66, 0x87, 0xb5, 0x3d, 0x66, 0x3c, 0x09, 0xbb, 0x7c, 0x00, 0x84, 0x7a, + 0xda, 0x2f, 0x50, 0x69, 0x11, 0x9f, 0x84, 0xdb, 0x8a, 0xd3, 0x1e, 0x11, 0x87, 0x05, 0xb5, 0x17, + 0x3e, 0x06, 0x9a, 0x19, 0x8f, 0x9b, 0xac, 0x90, 0x76, 0x6f, 0xf3, 0xde, 0xfc, 0xde, 0xef, 0xfd, + 0xde, 0x9f, 0xb1, 0xe1, 0x41, 0x38, 0x8b, 0x3a, 0x97, 0x33, 0x46, 0x82, 0x05, 0xee, 0xac, 0x1e, + 0xea, 0xa3, 0x9d, 0x30, 0xca, 0x29, 0xaa, 0x86, 0xb3, 0xc8, 0xd6, 0xae, 0xd5, 0x43, 0xab, 0xb9, + 0xa0, 0x74, 0x11, 0xe2, 0x8e, 0xbc, 0x9d, 0x2d, 0x2f, 0x3b, 0x9c, 0x44, 0x38, 0xe5, 0x7e, 0x94, + 0xa8, 0x00, 0xab, 0xbe, 0xa0, 0x0b, 0x2a, 0x8f, 0x1d, 0x71, 0x52, 0xde, 0xf6, 0x1f, 0x45, 0xd8, + 0x1e, 0xfb, 0xcc, 0x8f, 0x52, 0x34, 0x86, 0x3a, 0x4d, 0x30, 0xf3, 0x39, 0x65, 0x53, 0xce, 0x96, + 0x29, 0x9f, 0x86, 0x78, 0x85, 0xc3, 0x7d, 0xa3, 0x65, 0x1c, 0x54, 0xba, 0xfb, 0xf6, 0x66, 0x42, + 0xfb, 0x84, 0xf9, 0x73, 0x4e, 0x68, 0xdc, 0x37, 0x5f, 0xbe, 0x6e, 0x16, 0x3c, 0xa4, 0x63, 0x27, + 0x22, 0xf4, 0x6b, 0x11, 0x29, 0x18, 0x17, 0x4b, 0x9f, 0x05, 0xc4, 0x8f, 0x37, 0x18, 0x8b, 0xef, + 0xc6, 0xa8, 0x63, 0xd7, 0x18, 0x07, 0xf0, 0xfe, 0xf7, 0xcb, 0x60, 0x81, 0x37, 0xe8, 0xee, 0xbd, + 0x13, 0xdd, 0x9e, 0x0c, 0x5c, 0xe3, 0xfa, 0x14, 0xf6, 0x44, 0x8f, 0x42, 0x3a, 0x7f, 0x32, 0x4d, + 0x30, 0x23, 0x34, 0xd8, 0x37, 0x5b, 0xc6, 0x81, 0xe9, 0x55, 0xb5, 0x7b, 0x2c, 0xbd, 0x02, 0x98, + 0x30, 0x9a, 0xd0, 0xd4, 0x0f, 0x35, 0x70, 0x4b, 0x01, 0xb5, 0x5b, 0x01, 0xdb, 0xbf, 0x1a, 0xb0, + 0x3b, 0x66, 0x74, 0x45, 0x52, 0x42, 0xe3, 0x63, 0x9f, 0xfb, 0xa8, 0x06, 0xf7, 0x52, 0xfc, 0x83, + 0x6c, 0xa1, 0xe9, 0x89, 0x23, 0x1a, 0xc0, 0xb6, 0x1f, 0xd1, 0x65, 0xcc, 0x65, 0x17, 0xca, 0xfd, + 0xae, 0x10, 0xf7, 0xd7, 0xeb, 0xe6, 0xe1, 0x82, 0xf0, 0xc7, 0xcb, 0x99, 0x3d, 0xa7, 0x51, 0xe7, + 0x84, 0xc4, 0xe9, 0xfc, 0x31, 0xf1, 0x3b, 0x97, 0xd9, 0xe1, 0xf3, 0x34, 0x78, 0xd2, 0xe1, 0xcf, + 0x12, 0x9c, 0xda, 0x6e, 0xcc, 0xbd, 0x8c, 0x01, 0xdd, 0x87, 0xed, 0x14, 0xc7, 0x01, 0x66, 0xb2, + 0x05, 0x65, 0x2f, 0xb3, 0x90, 0x05, 0x25, 0x86, 0xe7, 0x98, 0xac, 0x30, 0x93, 0x25, 0x95, 0xbd, + 0xdc, 0x6e, 0xff, 0x04, 0x7b, 0xb9, 0xc4, 0x33, 0xee, 0xf3, 0x65, 0x8a, 0x3e, 0x86, 0x9d, 0xbc, + 0x11, 0x38, 0x0e, 0x32, 0xb5, 0x15, 0xed, 0x73, 0xe2, 0x00, 0x7d, 0x02, 0xd5, 0x39, 0x8d, 0x2f, + 0x09, 0x8b, 0xa6, 0x73, 0x91, 0x3a, 0x95, 0xea, 0xb7, 0xbc, 0xdd, 0xcc, 0x7b, 0x24, 0x9d, 0xe8, + 0x23, 0x00, 0x92, 0x4e, 0xe7, 0xa1, 0x4f, 0x22, 0x1c, 0x48, 0x51, 0x25, 0xaf, 0x4c, 0xd2, 0x23, + 0xe5, 0x68, 0x0f, 0xa0, 0xa4, 0x87, 0x82, 0x1e, 0x40, 0x39, 0x5e, 0x46, 0x6a, 0x65, 0xb2, 0x8c, + 0x77, 0x0e, 0xd4, 0x82, 0x4a, 0x80, 0x63, 0x1a, 0x91, 0x58, 0xde, 0x17, 0x95, 0xa2, 0x35, 0x57, + 0x7b, 0x08, 0x25, 0x8f, 0x86, 0x78, 0xec, 0x13, 0x86, 0xf6, 0xe1, 0x3d, 0x3f, 0x08, 0x18, 0x4e, + 0x53, 0xc9, 0x54, 0xf6, 0xb4, 0x89, 0x0e, 0xc0, 0x64, 0x34, 0xc4, 0x92, 0xa0, 0xda, 0xad, 0xbf, + 0xb9, 0x22, 0x82, 0xc1, 0x93, 0x88, 0xf6, 0xef, 0x06, 0xec, 0x48, 0xc2, 0x6c, 0xa4, 0xa8, 0x0a, + 0x45, 0xa2, 0x7b, 0x51, 0x24, 0x81, 0x68, 0xaa, 0x1a, 0x37, 0x56, 0x7a, 0xca, 0x5e, 0x6e, 0x8b, + 0x41, 0x70, 0x9f, 0x2d, 0x30, 0xd7, 0x83, 0x50, 0x56, 0x9e, 0xde, 0x7c, 0x5b, 0x7a, 0x74, 0x04, + 0x80, 0x9f, 0x26, 0x84, 0xe1, 0x60, 0xea, 0x73, 0xb9, 0x5e, 0x95, 0xae, 0x65, 0xab, 0x37, 0x6d, + 0xeb, 0x37, 0x6d, 0x4f, 0xf4, 0x9b, 0xee, 0x97, 0xc4, 0xda, 0x3c, 0xff, 0xbb, 0x69, 0x78, 0xe5, + 0x2c, 0xae, 0xc7, 0xdb, 0x3f, 0x82, 0x79, 0x41, 0x39, 0x46, 0x4d, 0xa8, 0xe4, 0x0b, 0x9b, 0xd7, + 0x00, 0xda, 0xe5, 0x06, 0xa8, 0x0e, 0x5b, 0x2b, 0xca, 0xf3, 0x42, 0x94, 0x81, 0xba, 0xb0, 0x4d, + 0x13, 0x31, 0x1c, 0x59, 0x45, 0xb5, 0x6b, 0xbd, 0xa9, 0x57, 0x90, 0x8f, 0x24, 0xc2, 0xcb, 0x90, + 0x5f, 0x99, 0xff, 0xbe, 0x68, 0x16, 0xda, 0xdf, 0xa9, 0xde, 0x7d, 0x83, 0xb9, 0x1f, 0x88, 0xb5, + 0xb7, 0xa0, 0xa4, 0x1f, 0x6f, 0x96, 0x3d, 0xb7, 0xc5, 0x9d, 0xfe, 0x54, 0x64, 0x73, 0xcd, 0x6d, + 0xa1, 0x4b, 0xbe, 0x52, 0x29, 0xc0, 0xf4, 0x94, 0xd1, 0x1e, 0x40, 0xbd, 0x2f, 0x35, 0xa8, 0x7d, + 0x5d, 0xcf, 0x42, 0x62, 0xb1, 0x4e, 0x2b, 0xac, 0xb3, 0x68, 0x5b, 0x4c, 0x24, 0xbb, 0x51, 0x39, + 0x32, 0xeb, 0xf0, 0x67, 0x03, 0x4c, 0x21, 0x15, 0x35, 0xa0, 0x72, 0x3e, 0x3c, 0x1b, 0x3b, 0x47, + 0xee, 0x89, 0xeb, 0x1c, 0xd7, 0x0a, 0xd6, 0xee, 0xd5, 0x75, 0xab, 0x2c, 0xae, 0x9c, 0x28, 0xe1, + 0xcf, 0x50, 0x03, 0x4a, 0xa7, 0xe7, 0x3d, 0xef, 0xd8, 0xed, 0x0d, 0x6b, 0x86, 0x55, 0xbb, 0xba, + 0x6e, 0xc9, 0x12, 0x4f, 0x75, 0x19, 0x0d, 0x28, 0x8d, 0xc6, 0x8e, 0xd7, 0x9b, 0x8c, 0xbc, 0x5a, + 0xf1, 0xee, 0x7e, 0xa4, 0x4b, 0xd9, 0x87, 0xad, 0xc1, 0xf9, 0xf1, 0xa9, 0x53, 0xbb, 0x77, 0xc7, + 0x3c, 0x10, 0xe5, 0x58, 0xe6, 0x2f, 0xbf, 0x35, 0x0a, 0x42, 0x08, 0xdc, 0xf5, 0x13, 0x7d, 0x06, + 0x1f, 0x5c, 0x8c, 0x26, 0xce, 0x74, 0x34, 0x9e, 0xb8, 0xa3, 0xe1, 0x74, 0x53, 0xda, 0xde, 0xd5, + 0x75, 0xab, 0xa2, 0x80, 0x4a, 0x5c, 0x1b, 0xf6, 0xd6, 0xd1, 0x8f, 0x9c, 0xb3, 0x9a, 0xa1, 0xd2, + 0x28, 0xd4, 0x23, 0x9c, 0xa2, 0x16, 0x54, 0xd7, 0x31, 0xc3, 0x51, 0xad, 0x68, 0xed, 0x5c, 0x5d, + 0xb7, 0x4a, 0x0a, 0x32, 0xa4, 0x99, 0x90, 0x17, 0x06, 0xec, 0xac, 0xb7, 0x17, 0xd9, 0xf0, 0x61, + 0xdf, 0x73, 0x8f, 0x4f, 0x9d, 0xe9, 0xd9, 0xa4, 0x37, 0x39, 0x3f, 0xfb, 0x3f, 0x31, 0x0a, 0xaa, + 0xc4, 0x1c, 0x42, 0x7d, 0x13, 0xdf, 0x3b, 0x9a, 0xb8, 0x17, 0x8e, 0xee, 0x9a, 0x82, 0xf6, 0xd4, + 0x58, 0x6c, 0xb8, 0xbf, 0x89, 0x75, 0x87, 0x19, 0xba, 0x68, 0xa1, 0xab, 0xeb, 0x56, 0x55, 0xa1, + 0xdd, 0x6c, 0x8c, 0x4a, 0x62, 0x7f, 0xf0, 0xf2, 0xa6, 0x61, 0xbc, 0xba, 0x69, 0x18, 0xff, 0xdc, + 0x34, 0x8c, 0xe7, 0xb7, 0x8d, 0xc2, 0xab, 0xdb, 0x46, 0xe1, 0xcf, 0xdb, 0x46, 0xe1, 0xdb, 0x2f, + 0xde, 0xfa, 0xd5, 0x7c, 0x9a, 0xff, 0x42, 0xe5, 0xf7, 0x73, 0xb6, 0x2d, 0x1f, 0xd3, 0x97, 0xff, + 0x05, 0x00, 0x00, 0xff, 0xff, 0xfa, 0x2c, 0x09, 0x1f, 0x5e, 0x07, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -651,6 +978,41 @@ func (m *Fraction) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *RolePair) 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 *RolePair) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RolePair) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Role != 0 { + i = encodeVarintFbridge(dAtA, i, uint64(m.Role)) + i-- + dAtA[i] = 0x10 + } + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintFbridge(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *RoleProposal) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -671,11 +1033,14 @@ func (m *RoleProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.ExpiredAt != 0 { - i = encodeVarintFbridge(dAtA, i, uint64(m.ExpiredAt)) - i-- - dAtA[i] = 0x28 + n4, err4 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.ExpiredAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.ExpiredAt):]) + if err4 != nil { + return 0, err4 } + i -= n4 + i = encodeVarintFbridge(dAtA, i, uint64(n4)) + i-- + dAtA[i] = 0x2a if m.Role != 0 { i = encodeVarintFbridge(dAtA, i, uint64(m.Role)) i-- @@ -703,46 +1068,157 @@ func (m *RoleProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func encodeVarintFbridge(dAtA []byte, offset int, v uint64) int { - offset -= sovFbridge(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *Vote) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *Params) Size() (n int) { - if m == nil { - return 0 - } + +func (m *Vote) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Vote) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = m.OperatorTrustLevel.Size() - n += 1 + l + sovFbridge(uint64(l)) - l = m.GuardianTrustLevel.Size() - n += 1 + l + sovFbridge(uint64(l)) - l = m.JudgeTrustLevel.Size() - n += 1 + l + sovFbridge(uint64(l)) - if m.TimelockPeriod != 0 { - n += 1 + sovFbridge(uint64(m.TimelockPeriod)) + if m.Option != 0 { + i = encodeVarintFbridge(dAtA, i, uint64(m.Option)) + i-- + dAtA[i] = 0x18 } - if m.ProposalPeriod != 0 { - n += 1 + sovFbridge(uint64(m.ProposalPeriod)) + if len(m.Voter) > 0 { + i -= len(m.Voter) + copy(dAtA[i:], m.Voter) + i = encodeVarintFbridge(dAtA, i, uint64(len(m.Voter))) + i-- + dAtA[i] = 0x12 } - return n + if m.ProposalId != 0 { + i = encodeVarintFbridge(dAtA, i, uint64(m.ProposalId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil } -func (m *ProvisionData) Size() (n int) { - if m == nil { - return 0 +func (m *RoleMetadata) 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 *RoleMetadata) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RoleMetadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.Seq != 0 { - n += 1 + sovFbridge(uint64(m.Seq)) + if m.Judge != 0 { + i = encodeVarintFbridge(dAtA, i, uint64(m.Judge)) + i-- + dAtA[i] = 0x18 + } + if m.Operator != 0 { + i = encodeVarintFbridge(dAtA, i, uint64(m.Operator)) + i-- + dAtA[i] = 0x10 + } + if m.Guardian != 0 { + i = encodeVarintFbridge(dAtA, i, uint64(m.Guardian)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *BridgeStatusMetadata) 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 *BridgeStatusMetadata) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BridgeStatusMetadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Active != 0 { + i = encodeVarintFbridge(dAtA, i, uint64(m.Active)) + i-- + dAtA[i] = 0x10 + } + if m.Inactive != 0 { + i = encodeVarintFbridge(dAtA, i, uint64(m.Inactive)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintFbridge(dAtA []byte, offset int, v uint64) int { + offset -= sovFbridge(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.OperatorTrustLevel.Size() + n += 1 + l + sovFbridge(uint64(l)) + l = m.GuardianTrustLevel.Size() + n += 1 + l + sovFbridge(uint64(l)) + l = m.JudgeTrustLevel.Size() + n += 1 + l + sovFbridge(uint64(l)) + if m.TimelockPeriod != 0 { + n += 1 + sovFbridge(uint64(m.TimelockPeriod)) + } + if m.ProposalPeriod != 0 { + n += 1 + sovFbridge(uint64(m.ProposalPeriod)) + } + return n +} + +func (m *ProvisionData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Seq != 0 { + n += 1 + sovFbridge(uint64(m.Seq)) } l = m.Amount.Size() n += 1 + l + sovFbridge(uint64(l)) @@ -790,6 +1266,22 @@ func (m *Fraction) Size() (n int) { return n } +func (m *RolePair) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovFbridge(uint64(l)) + } + if m.Role != 0 { + n += 1 + sovFbridge(uint64(m.Role)) + } + return n +} + func (m *RoleProposal) Size() (n int) { if m == nil { return 0 @@ -810,8 +1302,59 @@ func (m *RoleProposal) Size() (n int) { if m.Role != 0 { n += 1 + sovFbridge(uint64(m.Role)) } - if m.ExpiredAt != 0 { - n += 1 + sovFbridge(uint64(m.ExpiredAt)) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.ExpiredAt) + n += 1 + l + sovFbridge(uint64(l)) + return n +} + +func (m *Vote) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ProposalId != 0 { + n += 1 + sovFbridge(uint64(m.ProposalId)) + } + l = len(m.Voter) + if l > 0 { + n += 1 + l + sovFbridge(uint64(l)) + } + if m.Option != 0 { + n += 1 + sovFbridge(uint64(m.Option)) + } + return n +} + +func (m *RoleMetadata) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Guardian != 0 { + n += 1 + sovFbridge(uint64(m.Guardian)) + } + if m.Operator != 0 { + n += 1 + sovFbridge(uint64(m.Operator)) + } + if m.Judge != 0 { + n += 1 + sovFbridge(uint64(m.Judge)) + } + return n +} + +func (m *BridgeStatusMetadata) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Inactive != 0 { + n += 1 + sovFbridge(uint64(m.Inactive)) + } + if m.Active != 0 { + n += 1 + sovFbridge(uint64(m.Active)) } return n } @@ -1372,6 +1915,107 @@ func (m *Fraction) Unmarshal(dAtA []byte) error { } return nil } +func (m *RolePair) 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 ErrIntOverflowFbridge + } + 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: RolePair: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RolePair: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFbridge + } + 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 ErrInvalidLengthFbridge + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthFbridge + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) + } + m.Role = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFbridge + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Role |= Role(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipFbridge(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthFbridge + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *RoleProposal) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -1504,10 +2148,339 @@ func (m *RoleProposal) Unmarshal(dAtA []byte) error { } } case 5: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ExpiredAt", wireType) } - m.ExpiredAt = 0 + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFbridge + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthFbridge + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthFbridge + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.ExpiredAt, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipFbridge(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthFbridge + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Vote) 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 ErrIntOverflowFbridge + } + 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: Vote: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Vote: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ProposalId", wireType) + } + m.ProposalId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFbridge + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ProposalId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Voter", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFbridge + } + 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 ErrInvalidLengthFbridge + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthFbridge + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Voter = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Option", wireType) + } + m.Option = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFbridge + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Option |= VoteOption(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipFbridge(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthFbridge + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RoleMetadata) 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 ErrIntOverflowFbridge + } + 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: RoleMetadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RoleMetadata: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Guardian", wireType) + } + m.Guardian = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFbridge + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Guardian |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Operator", wireType) + } + m.Operator = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFbridge + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Operator |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Judge", wireType) + } + m.Judge = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFbridge + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Judge |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipFbridge(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthFbridge + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BridgeStatusMetadata) 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 ErrIntOverflowFbridge + } + 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: BridgeStatusMetadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BridgeStatusMetadata: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Inactive", wireType) + } + m.Inactive = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFbridge + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Inactive |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Active", wireType) + } + m.Active = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowFbridge @@ -1517,7 +2490,7 @@ func (m *RoleProposal) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ExpiredAt |= uint64(b&0x7F) << shift + m.Active |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/fbridge/types/genesis.go b/x/fbridge/types/genesis.go index 07af6f9677..358f64b2fa 100644 --- a/x/fbridge/types/genesis.go +++ b/x/fbridge/types/genesis.go @@ -5,26 +5,104 @@ import ( sdk "github.com/Finschia/finschia-sdk/types" authtypes "github.com/Finschia/finschia-sdk/x/auth/types" + foundationtypes "github.com/Finschia/finschia-sdk/x/foundation" govtypes "github.com/Finschia/finschia-sdk/x/gov/types" ) func DefaultGenesisState() *GenesisState { return &GenesisState{ + Params: DefaultParams(), SendingState: SendingState{ NextSeq: 1, }, - ReceivingState: ReceivingState{}, + ReceivingState: ReceivingState{}, + NextRoleProposalId: 1, + } +} + +func DefaultAuthority() sdk.AccAddress { + return authtypes.NewModuleAddress(govtypes.ModuleName) +} + +func AuthorityCandiates() []sdk.AccAddress { + return []sdk.AccAddress{ + authtypes.NewModuleAddress(govtypes.ModuleName), + authtypes.NewModuleAddress(foundationtypes.ModuleName), } } func ValidateGenesis(data GenesisState) error { - if data.SendingState.NextSeq < 1 { - panic(errors.New("next sequence must be positive")) + if err := ValidateParams(data.Params); err != nil { + return err + } + + if err := validateSendingState(data.SendingState); err != nil { + return err + } + + if data.NextRoleProposalId < 1 { + return errors.New("next role proposal ID must be positive") + } + + for _, v := range data.RoleProposals { + if v.Id < 1 { + return errors.New("role proposal ID must be positive") + } + sdk.MustAccAddressFromBech32(v.Proposer) + sdk.MustAccAddressFromBech32(v.Target) + if err := IsValidRole(v.Role); err != nil { + return err + } + } + + for _, v := range data.Votes { + if v.ProposalId < 1 { + return errors.New("role proposal ID must be positive") + } + sdk.MustAccAddressFromBech32(v.Voter) + if err := IsValidVoteOption(v.Option); err != nil { + return err + } + } + + for _, v := range data.Roles { + sdk.MustAccAddressFromBech32(v.Address) + if err := IsValidRole(v.Role); err != nil { + return err + } + } + + for _, v := range data.BridgeSwitches { + sdk.MustAccAddressFromBech32(v.Guardian) + if err := IsValidBridgeStatus(v.Status); err != nil { + return err + } } return nil } -func DefaultAuthority() sdk.AccAddress { - return authtypes.NewModuleAddress(govtypes.ModuleName) +func validateSendingState(state SendingState) error { + if state.NextSeq < 1 { + return errors.New("next sequence must be positive") + } + + if state.NextSeq-1 != uint64(len(state.SeqToBlocknum)) { + return errors.New("sequence to blocknum mapping is invalid") + } + + chkSeq := make(map[uint64]struct{}) + for _, v := range state.SeqToBlocknum { + if v.Blocknum == 0 || v.Seq == 0 { + return errors.New("blocknum and seq must be positive") + } + + if _, ok := chkSeq[v.Seq]; ok { + return errors.New("duplicate sequence") + } + + chkSeq[v.Seq] = struct{}{} + } + + return nil } diff --git a/x/fbridge/types/genesis.pb.go b/x/fbridge/types/genesis.pb.go index 7b28e12f13..844eb131ae 100644 --- a/x/fbridge/types/genesis.pb.go +++ b/x/fbridge/types/genesis.pb.go @@ -31,6 +31,16 @@ type GenesisState struct { SendingState SendingState `protobuf:"bytes,2,opt,name=sending_state,json=sendingState,proto3" json:"sending_state"` // receiving_state defines status saved when receiving tokens from a counterpart chain ReceivingState ReceivingState `protobuf:"bytes,3,opt,name=receiving_state,json=receivingState,proto3" json:"receiving_state"` + // next_role_proposal_id is the next role proposal ID to be used. + NextRoleProposalId uint64 `protobuf:"varint,4,opt,name=next_role_proposal_id,json=nextRoleProposalId,proto3" json:"next_role_proposal_id,omitempty"` + // role_proposals defines all the role proposals present at genesis. + RoleProposals []RoleProposal `protobuf:"bytes,5,rep,name=role_proposals,json=roleProposals,proto3" json:"role_proposals"` + // votes defines all the votes present for role proposals at genesis. + Votes []Vote `protobuf:"bytes,6,rep,name=votes,proto3" json:"votes"` + // roles defines all addresses assigned roles at genesis. + Roles []RolePair `protobuf:"bytes,7,rep,name=roles,proto3" json:"roles"` + // bridge_switches defines the status of whether each guardian has allowed the bridge to operate. + BridgeSwitches []BridgeSwitch `protobuf:"bytes,8,rep,name=bridge_switches,json=bridgeSwitches,proto3" json:"bridge_switches"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -87,6 +97,41 @@ func (m *GenesisState) GetReceivingState() ReceivingState { return ReceivingState{} } +func (m *GenesisState) GetNextRoleProposalId() uint64 { + if m != nil { + return m.NextRoleProposalId + } + return 0 +} + +func (m *GenesisState) GetRoleProposals() []RoleProposal { + if m != nil { + return m.RoleProposals + } + return nil +} + +func (m *GenesisState) GetVotes() []Vote { + if m != nil { + return m.Votes + } + return nil +} + +func (m *GenesisState) GetRoles() []RolePair { + if m != nil { + return m.Roles + } + return nil +} + +func (m *GenesisState) GetBridgeSwitches() []BridgeSwitch { + if m != nil { + return m.BridgeSwitches + } + return nil +} + type SendingState struct { // the next sequence number of the bridge request (greatest sequence number + 1) NextSeq uint64 `protobuf:"varint,1,opt,name=next_seq,json=nextSeq,proto3" json:"next_seq,omitempty"` @@ -461,6 +506,59 @@ func (m *ConfirmedProvision) GetCommitment() string { return "" } +type BridgeSwitch struct { + // the guardian address + Guardian string `protobuf:"bytes,1,opt,name=guardian,proto3" json:"guardian,omitempty"` + Status BridgeStatus `protobuf:"varint,2,opt,name=status,proto3,enum=lbm.fbridge.v1.BridgeStatus" json:"status,omitempty"` +} + +func (m *BridgeSwitch) Reset() { *m = BridgeSwitch{} } +func (m *BridgeSwitch) String() string { return proto.CompactTextString(m) } +func (*BridgeSwitch) ProtoMessage() {} +func (*BridgeSwitch) Descriptor() ([]byte, []int) { + return fileDescriptor_0fc3cc4535a29f6d, []int{8} +} +func (m *BridgeSwitch) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BridgeSwitch) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BridgeSwitch.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 *BridgeSwitch) XXX_Merge(src proto.Message) { + xxx_messageInfo_BridgeSwitch.Merge(m, src) +} +func (m *BridgeSwitch) XXX_Size() int { + return m.Size() +} +func (m *BridgeSwitch) XXX_DiscardUnknown() { + xxx_messageInfo_BridgeSwitch.DiscardUnknown(m) +} + +var xxx_messageInfo_BridgeSwitch proto.InternalMessageInfo + +func (m *BridgeSwitch) GetGuardian() string { + if m != nil { + return m.Guardian + } + return "" +} + +func (m *BridgeSwitch) GetStatus() BridgeStatus { + if m != nil { + return m.Status + } + return StatusEmpty +} + func init() { proto.RegisterType((*GenesisState)(nil), "lbm.fbridge.v1.GenesisState") proto.RegisterType((*SendingState)(nil), "lbm.fbridge.v1.SendingState") @@ -470,54 +568,64 @@ func init() { proto.RegisterType((*Commitment)(nil), "lbm.fbridge.v1.Commitment") proto.RegisterType((*Provision)(nil), "lbm.fbridge.v1.Provision") proto.RegisterType((*ConfirmedProvision)(nil), "lbm.fbridge.v1.ConfirmedProvision") + proto.RegisterType((*BridgeSwitch)(nil), "lbm.fbridge.v1.BridgeSwitch") } func init() { proto.RegisterFile("lbm/fbridge/v1/genesis.proto", fileDescriptor_0fc3cc4535a29f6d) } var fileDescriptor_0fc3cc4535a29f6d = []byte{ - // 666 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0xcd, 0x6e, 0xd3, 0x40, - 0x10, 0xc7, 0xe3, 0xc4, 0x4a, 0xdb, 0x69, 0xfa, 0xa1, 0x15, 0x54, 0x6e, 0x28, 0x4e, 0x64, 0x71, - 0xe8, 0x01, 0x62, 0x0a, 0x48, 0x7c, 0xa8, 0x12, 0x52, 0x8a, 0x5a, 0x51, 0x09, 0x81, 0x6c, 0x0e, - 0xa8, 0x17, 0xcb, 0x76, 0x36, 0xee, 0xaa, 0xb1, 0x37, 0xf6, 0x6e, 0xa2, 0x56, 0xbc, 0x00, 0x47, - 0x6e, 0x5c, 0xb9, 0xf0, 0x2e, 0x3d, 0xf6, 0xc8, 0x01, 0x21, 0xd4, 0xbe, 0x08, 0xf2, 0x76, 0xfd, - 0x11, 0x37, 0x95, 0xe0, 0xb6, 0xbb, 0xf3, 0x9f, 0xdf, 0xfc, 0x67, 0x3d, 0x5e, 0xd8, 0x1a, 0x79, - 0xa1, 0x39, 0xf4, 0x12, 0x32, 0x08, 0xb0, 0x39, 0xdd, 0x31, 0x03, 0x1c, 0x61, 0x46, 0x58, 0x6f, - 0x9c, 0x50, 0x4e, 0xd1, 0xea, 0xc8, 0x0b, 0x7b, 0x32, 0xda, 0x9b, 0xee, 0xb4, 0xef, 0x04, 0x34, - 0xa0, 0x22, 0x64, 0xa6, 0xab, 0x6b, 0x55, 0xbb, 0xca, 0xc8, 0x12, 0x44, 0xd4, 0xf8, 0xa5, 0x40, - 0xeb, 0xe0, 0x9a, 0x6a, 0x73, 0x97, 0x63, 0xf4, 0x0c, 0x9a, 0x63, 0x37, 0x71, 0x43, 0xa6, 0x29, - 0x5d, 0x65, 0x7b, 0xf9, 0xc9, 0x46, 0x6f, 0xb6, 0x4a, 0xef, 0x83, 0x88, 0xf6, 0xd5, 0xf3, 0xdf, - 0x9d, 0x9a, 0x25, 0xb5, 0xe8, 0x00, 0x56, 0x18, 0x8e, 0x06, 0x24, 0x0a, 0x1c, 0x96, 0x62, 0xb4, - 0xba, 0x48, 0xde, 0xaa, 0x26, 0xdb, 0xd7, 0x22, 0x51, 0x4a, 0x22, 0x5a, 0xac, 0x74, 0x86, 0xde, - 0xc1, 0x5a, 0x82, 0x7d, 0x4c, 0xa6, 0x05, 0xaa, 0x21, 0x50, 0x7a, 0x15, 0x65, 0x65, 0xb2, 0x32, - 0x6c, 0x35, 0x99, 0x39, 0x35, 0x3e, 0x43, 0xab, 0x5c, 0x12, 0x6d, 0xc2, 0x62, 0x84, 0x4f, 0xb9, - 0xc3, 0x70, 0x2c, 0xfa, 0x53, 0xad, 0x85, 0x74, 0x6f, 0xe3, 0x18, 0x1d, 0xc2, 0x1a, 0xc3, 0xb1, - 0xc3, 0xa9, 0xe3, 0x8d, 0xa8, 0x7f, 0x12, 0x4d, 0x42, 0xad, 0xde, 0x6d, 0xcc, 0x6b, 0xa2, 0x9f, - 0xc6, 0x6d, 0x1c, 0xbf, 0x8d, 0x86, 0x54, 0xd6, 0x5d, 0x61, 0x38, 0xfe, 0x48, 0xfb, 0x32, 0xf1, - 0x95, 0xfa, 0xe5, 0x7b, 0xa7, 0x66, 0xec, 0x42, 0xab, 0x2c, 0x45, 0xeb, 0xd0, 0x28, 0xea, 0xa6, - 0x4b, 0xd4, 0x86, 0xc5, 0x52, 0xb1, 0xf4, 0x38, 0xdf, 0x1b, 0x3f, 0x54, 0x58, 0x9d, 0xed, 0x11, - 0x51, 0x78, 0x10, 0x24, 0xd8, 0xe5, 0x98, 0x71, 0xc7, 0xa7, 0x11, 0xc3, 0xfe, 0x84, 0x93, 0x29, - 0x4e, 0xbb, 0x71, 0xbc, 0x33, 0x87, 0x8e, 0x71, 0xe2, 0x72, 0x9a, 0x68, 0x8a, 0xf0, 0xdd, 0xa9, - 0xfa, 0x7e, 0x2f, 0xe3, 0xd2, 0x8f, 0xd5, 0xcd, 0x60, 0x7b, 0x05, 0xcb, 0xc6, 0x71, 0xff, 0x2c, - 0x13, 0xa2, 0x4f, 0xa0, 0xe5, 0x05, 0xab, 0x45, 0xea, 0xff, 0x56, 0xe4, 0x6e, 0x06, 0x98, 0x25, - 0xbf, 0x28, 0x91, 0x2b, 0xad, 0x88, 0x0f, 0xae, 0x5a, 0x1b, 0xf3, 0xdd, 0xa1, 0x87, 0x80, 0xc6, - 0x72, 0xd4, 0xfc, 0x91, 0x4b, 0xc2, 0x34, 0x85, 0x69, 0x6a, 0xb7, 0xb1, 0xad, 0x5a, 0xeb, 0x32, - 0xb2, 0x97, 0x06, 0x6c, 0x1c, 0x33, 0xb4, 0x0b, 0xcb, 0x3e, 0x0d, 0x43, 0xc2, 0x43, 0x1c, 0x71, - 0xa6, 0x35, 0x85, 0xe9, 0x76, 0xd5, 0xf4, 0x5e, 0x2e, 0xb1, 0xca, 0x72, 0xf4, 0x12, 0x60, 0x9c, - 0xd0, 0x29, 0x61, 0x84, 0x46, 0x4c, 0x5b, 0x10, 0xc9, 0x9b, 0x37, 0x7e, 0x88, 0x4c, 0x61, 0x95, - 0xc4, 0xc8, 0x85, 0x7b, 0x3e, 0x8d, 0x86, 0x24, 0x09, 0xf1, 0xc0, 0x91, 0x83, 0x55, 0xa0, 0xb5, - 0x45, 0xc1, 0x32, 0x6e, 0x1a, 0x91, 0x29, 0x05, 0x54, 0xcb, 0x31, 0x76, 0x3a, 0x63, 0x85, 0x55, - 0x39, 0x65, 0xaf, 0x61, 0xad, 0x72, 0xe7, 0xe9, 0x58, 0x95, 0x66, 0x41, 0xd9, 0x5e, 0xb2, 0xf2, - 0x7d, 0x36, 0x84, 0xf5, 0x7c, 0x08, 0x8d, 0x23, 0x80, 0x02, 0xfa, 0x7f, 0xb9, 0x48, 0x07, 0x28, - 0x35, 0xd5, 0x10, 0xfa, 0xd2, 0x89, 0xf1, 0x4d, 0x81, 0xa5, 0xbc, 0x95, 0x8a, 0x5a, 0xa9, 0xaa, - 0xd1, 0x0e, 0xa8, 0x03, 0x97, 0xbb, 0xf2, 0xf1, 0xb8, 0x7f, 0xeb, 0x45, 0xbf, 0x71, 0xb9, 0x6b, - 0x09, 0x29, 0x7a, 0x0e, 0xcd, 0xf4, 0x95, 0x98, 0x30, 0xf9, 0x4c, 0x74, 0x6e, 0x4d, 0xb2, 0x85, - 0xcc, 0x92, 0x72, 0x63, 0x1f, 0xd0, 0xcd, 0xcb, 0x9e, 0xf3, 0x8b, 0xce, 0x7a, 0xae, 0x57, 0x3d, - 0xf7, 0x0f, 0xcf, 0x2f, 0x75, 0xe5, 0xe2, 0x52, 0x57, 0xfe, 0x5c, 0xea, 0xca, 0xd7, 0x2b, 0xbd, - 0x76, 0x71, 0xa5, 0xd7, 0x7e, 0x5e, 0xe9, 0xb5, 0xa3, 0xc7, 0x01, 0xe1, 0xc7, 0x13, 0xaf, 0xe7, - 0xd3, 0xd0, 0xdc, 0x27, 0x11, 0xf3, 0x8f, 0x89, 0x6b, 0x0e, 0xe5, 0xe2, 0x11, 0x1b, 0x9c, 0x98, - 0xa7, 0xf9, 0xbb, 0xcc, 0xcf, 0xc6, 0x98, 0x79, 0x4d, 0xf1, 0x26, 0x3f, 0xfd, 0x1b, 0x00, 0x00, - 0xff, 0xff, 0x21, 0xae, 0xb3, 0xc6, 0xf7, 0x05, 0x00, 0x00, + // 808 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xcf, 0x8f, 0xdb, 0x44, + 0x14, 0x8e, 0x13, 0x6f, 0xba, 0x7d, 0x4d, 0x93, 0x6a, 0xd4, 0x56, 0x6e, 0x28, 0x4e, 0x64, 0x71, + 0xc8, 0x01, 0x92, 0x06, 0x2a, 0xf1, 0x43, 0x95, 0x90, 0xb2, 0xa8, 0xd5, 0x16, 0x21, 0x2a, 0x1b, + 0x21, 0xd4, 0x8b, 0x19, 0xdb, 0x13, 0xef, 0xa8, 0xb1, 0xc7, 0xf1, 0x4c, 0x42, 0x57, 0xfc, 0x03, + 0xdc, 0xe0, 0xc6, 0x95, 0x0b, 0xff, 0x4b, 0x8f, 0x7b, 0xe4, 0x84, 0xd0, 0xee, 0x3f, 0x82, 0x66, + 0x32, 0x76, 0x1c, 0x27, 0x91, 0xe0, 0x36, 0x33, 0xef, 0x7b, 0xdf, 0xfb, 0xe6, 0xf9, 0xf3, 0x1b, + 0x78, 0xbc, 0x08, 0x92, 0xc9, 0x3c, 0xc8, 0x69, 0x14, 0x93, 0xc9, 0x7a, 0x3a, 0x89, 0x49, 0x4a, + 0x38, 0xe5, 0xe3, 0x2c, 0x67, 0x82, 0xa1, 0xee, 0x22, 0x48, 0xc6, 0x3a, 0x3a, 0x5e, 0x4f, 0xfb, + 0xf7, 0x63, 0x16, 0x33, 0x15, 0x9a, 0xc8, 0xd5, 0x06, 0xd5, 0xaf, 0x73, 0x14, 0x09, 0x2a, 0xea, + 0xfc, 0x6a, 0x42, 0xe7, 0xc5, 0x86, 0xd5, 0x13, 0x58, 0x10, 0xf4, 0x14, 0xda, 0x19, 0xce, 0x71, + 0xc2, 0x2d, 0x63, 0x68, 0x8c, 0xee, 0x7c, 0xfc, 0x70, 0xbc, 0x5b, 0x65, 0xfc, 0x4a, 0x45, 0x67, + 0xe6, 0xbb, 0xbf, 0x07, 0x0d, 0x57, 0x63, 0xd1, 0x0b, 0xb8, 0xcb, 0x49, 0x1a, 0xd1, 0x34, 0xf6, + 0xb9, 0xa4, 0xb1, 0x9a, 0x2a, 0xf9, 0x71, 0x3d, 0xd9, 0xdb, 0x80, 0x54, 0x29, 0x4d, 0xd1, 0xe1, + 0x95, 0x33, 0xf4, 0x0d, 0xf4, 0x72, 0x12, 0x12, 0xba, 0xde, 0x52, 0xb5, 0x14, 0x95, 0x5d, 0xa7, + 0x72, 0x0b, 0x58, 0x95, 0xac, 0x9b, 0xef, 0x9c, 0xa2, 0x29, 0x3c, 0x48, 0xc9, 0x5b, 0xe1, 0xe7, + 0x6c, 0x41, 0xfc, 0x2c, 0x67, 0x19, 0xe3, 0x78, 0xe1, 0xd3, 0xc8, 0x32, 0x87, 0xc6, 0xc8, 0x74, + 0x91, 0x0c, 0xba, 0x6c, 0x41, 0x5e, 0xe9, 0xd0, 0x79, 0x84, 0xce, 0xa1, 0xbb, 0x83, 0xe6, 0xd6, + 0xc9, 0xb0, 0x75, 0xe8, 0x2e, 0xd5, 0x3c, 0x5d, 0xfe, 0x6e, 0x5e, 0x39, 0xe3, 0xe8, 0x09, 0x9c, + 0xac, 0x99, 0x20, 0xdc, 0x6a, 0x2b, 0x86, 0xfb, 0x75, 0x86, 0xef, 0x59, 0x29, 0x7c, 0x03, 0x44, + 0x4f, 0xe1, 0x44, 0x52, 0x70, 0xeb, 0x96, 0xca, 0xb0, 0x0e, 0xd6, 0xc4, 0x34, 0x2f, 0xb2, 0x14, + 0x18, 0x7d, 0x0d, 0xbd, 0x0d, 0xc4, 0xe7, 0x3f, 0x51, 0x11, 0x5e, 0x10, 0x6e, 0x9d, 0x1e, 0xd6, + 0x3c, 0x53, 0x2b, 0x4f, 0xa1, 0x8a, 0x96, 0x05, 0x95, 0x33, 0xc2, 0x9d, 0x9f, 0xa1, 0x53, 0xfd, + 0x4a, 0xe8, 0x11, 0x9c, 0xaa, 0x16, 0x72, 0xb2, 0x54, 0x96, 0x30, 0xdd, 0x5b, 0x72, 0xef, 0x91, + 0x25, 0x7a, 0x09, 0x3d, 0x4e, 0x96, 0xbe, 0x60, 0x7e, 0xb0, 0x60, 0xe1, 0x9b, 0x74, 0x95, 0x58, + 0xcd, 0x23, 0x75, 0x65, 0xdc, 0x23, 0xcb, 0xf3, 0x74, 0xce, 0x8a, 0x5e, 0x71, 0xb2, 0xfc, 0x8e, + 0xcd, 0x74, 0xe2, 0x17, 0xe6, 0x2f, 0x7f, 0x0c, 0x1a, 0xce, 0x33, 0xe8, 0x54, 0xa1, 0xe8, 0x1e, + 0xb4, 0xb6, 0x75, 0xe5, 0x12, 0xf5, 0xe1, 0xb4, 0x52, 0x4c, 0x1e, 0x97, 0x7b, 0xe7, 0x4f, 0x13, + 0xba, 0xbb, 0xb6, 0x40, 0x0c, 0x3e, 0x88, 0x73, 0x82, 0x05, 0xe1, 0xc2, 0x0f, 0x59, 0xca, 0x49, + 0xb8, 0x12, 0x74, 0x4d, 0xe4, 0x6d, 0xfc, 0xe0, 0xd2, 0x67, 0x19, 0xc9, 0xb1, 0x60, 0xb9, 0x65, + 0x28, 0xdd, 0x83, 0xba, 0xee, 0x6f, 0x75, 0x5c, 0xeb, 0x71, 0x87, 0x05, 0xd9, 0xd9, 0x96, 0xcb, + 0x23, 0xcb, 0xd9, 0x65, 0x01, 0x44, 0x3f, 0x80, 0x55, 0x16, 0xac, 0x17, 0x69, 0xfe, 0xb7, 0x22, + 0x0f, 0x0a, 0x82, 0x5d, 0xe6, 0xcf, 0x2a, 0xcc, 0xb5, 0xab, 0xa8, 0x7f, 0xc4, 0x74, 0x1f, 0x1e, + 0x56, 0x87, 0x3e, 0x04, 0x94, 0xe9, 0xbf, 0x33, 0x5c, 0x60, 0x9a, 0xc8, 0x14, 0x6e, 0x99, 0xc3, + 0xd6, 0xc8, 0x74, 0xef, 0xe9, 0xc8, 0x99, 0x0c, 0x78, 0x64, 0xc9, 0xd1, 0x33, 0xb8, 0x13, 0xb2, + 0x24, 0xa1, 0x22, 0x21, 0xa9, 0x28, 0xbc, 0xdb, 0xaf, 0x8b, 0x3e, 0x2b, 0x21, 0x6e, 0x15, 0x8e, + 0x3e, 0x07, 0xc8, 0x72, 0xb6, 0xa6, 0x9c, 0xb2, 0xb4, 0xb0, 0xf1, 0xa3, 0xbd, 0x19, 0x52, 0x20, + 0xdc, 0x0a, 0x18, 0x61, 0x78, 0x2f, 0x64, 0xe9, 0x9c, 0xe6, 0x09, 0x89, 0x7c, 0x6d, 0xac, 0x2d, + 0xb5, 0xb6, 0xb4, 0xb3, 0x2f, 0x44, 0xa7, 0x6c, 0x49, 0xad, 0x92, 0xc6, 0x93, 0x1e, 0xdb, 0x4a, + 0xd5, 0x2e, 0xfb, 0x12, 0x7a, 0xb5, 0x9e, 0x4b, 0x5b, 0x55, 0xbc, 0x60, 0x8c, 0x6e, 0xbb, 0xe5, + 0xbe, 0x30, 0x61, 0xb3, 0x34, 0xa1, 0xf3, 0x1a, 0x60, 0x4b, 0xfa, 0xff, 0x72, 0x91, 0x0d, 0x50, + 0xb9, 0x54, 0x4b, 0xe1, 0x2b, 0x27, 0xce, 0xef, 0x06, 0xdc, 0x2e, 0xaf, 0x52, 0x43, 0x1b, 0x75, + 0x34, 0x9a, 0x82, 0x19, 0x61, 0x81, 0xf5, 0xbc, 0x7d, 0xff, 0x68, 0xa3, 0xbf, 0xc2, 0x02, 0xbb, + 0x0a, 0x8a, 0x3e, 0x85, 0xb6, 0x1c, 0xac, 0x2b, 0xae, 0x27, 0xeb, 0xe0, 0x68, 0x92, 0xa7, 0x60, + 0xae, 0x86, 0x3b, 0xcf, 0x01, 0xed, 0x37, 0xfb, 0xc0, 0x2f, 0xba, 0xab, 0xb9, 0xb9, 0x77, 0xc3, + 0x1f, 0xa1, 0x53, 0x9d, 0x43, 0xb2, 0x7f, 0xf1, 0x0a, 0xe7, 0x11, 0xc5, 0x69, 0xd1, 0xbf, 0x62, + 0x2f, 0x9f, 0x23, 0x2d, 0x56, 0xf2, 0x74, 0x8f, 0x4e, 0xb4, 0x1d, 0xa5, 0xb3, 0x97, 0xef, 0xae, + 0x6d, 0xe3, 0xea, 0xda, 0x36, 0xfe, 0xb9, 0xb6, 0x8d, 0xdf, 0x6e, 0xec, 0xc6, 0xd5, 0x8d, 0xdd, + 0xf8, 0xeb, 0xc6, 0x6e, 0xbc, 0x7e, 0x12, 0x53, 0x71, 0xb1, 0x0a, 0xc6, 0x21, 0x4b, 0x26, 0xcf, + 0x69, 0xca, 0xc3, 0x0b, 0x8a, 0x27, 0x73, 0xbd, 0xf8, 0x88, 0x47, 0x6f, 0x26, 0x6f, 0xcb, 0xc7, + 0x52, 0x5c, 0x66, 0x84, 0x07, 0x6d, 0xf5, 0x50, 0x7e, 0xf2, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xd3, 0xf5, 0xbb, 0x75, 0x8c, 0x07, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -540,6 +648,67 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.BridgeSwitches) > 0 { + for iNdEx := len(m.BridgeSwitches) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.BridgeSwitches[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + } + if len(m.Roles) > 0 { + for iNdEx := len(m.Roles) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Roles[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + } + if len(m.Votes) > 0 { + for iNdEx := len(m.Votes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Votes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } + if len(m.RoleProposals) > 0 { + for iNdEx := len(m.RoleProposals) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.RoleProposals[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + if m.NextRoleProposalId != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.NextRoleProposalId)) + i-- + dAtA[i] = 0x20 + } { size, err := m.ReceivingState.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -930,6 +1099,41 @@ func (m *ConfirmedProvision) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *BridgeSwitch) 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 *BridgeSwitch) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BridgeSwitch) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Status != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.Status)) + i-- + dAtA[i] = 0x10 + } + if len(m.Guardian) > 0 { + i -= len(m.Guardian) + copy(dAtA[i:], m.Guardian) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Guardian))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { offset -= sovGenesis(v) base := offset @@ -953,6 +1157,33 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) l = m.ReceivingState.Size() n += 1 + l + sovGenesis(uint64(l)) + if m.NextRoleProposalId != 0 { + n += 1 + sovGenesis(uint64(m.NextRoleProposalId)) + } + if len(m.RoleProposals) > 0 { + for _, e := range m.RoleProposals { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.Votes) > 0 { + for _, e := range m.Votes { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.Roles) > 0 { + for _, e := range m.Roles { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.BridgeSwitches) > 0 { + for _, e := range m.BridgeSwitches { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } return n } @@ -1111,6 +1342,22 @@ func (m *ConfirmedProvision) Size() (n int) { return n } +func (m *BridgeSwitch) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Guardian) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + if m.Status != 0 { + n += 1 + sovGenesis(uint64(m.Status)) + } + return n +} + func sovGenesis(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1245,6 +1492,161 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NextRoleProposalId", wireType) + } + m.NextRoleProposalId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NextRoleProposalId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RoleProposals", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RoleProposals = append(m.RoleProposals, RoleProposal{}) + if err := m.RoleProposals[len(m.RoleProposals)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Votes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Votes = append(m.Votes, Vote{}) + if err := m.Votes[len(m.Votes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Roles = append(m.Roles, RolePair{}) + if err := m.Roles[len(m.Roles)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BridgeSwitches", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BridgeSwitches = append(m.BridgeSwitches, BridgeSwitch{}) + if err := m.BridgeSwitches[len(m.BridgeSwitches)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) @@ -2261,6 +2663,107 @@ func (m *ConfirmedProvision) Unmarshal(dAtA []byte) error { } return nil } +func (m *BridgeSwitch) 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 ErrIntOverflowGenesis + } + 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: BridgeSwitch: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BridgeSwitch: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Guardian", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + 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 ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Guardian = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + m.Status = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Status |= BridgeStatus(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipGenesis(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/fbridge/types/keys.go b/x/fbridge/types/keys.go index 714c3b4fcf..81653c6456 100644 --- a/x/fbridge/types/keys.go +++ b/x/fbridge/types/keys.go @@ -1,19 +1,52 @@ package types -import "encoding/binary" +import ( + "encoding/binary" + + sdk "github.com/Finschia/finschia-sdk/types" + "github.com/Finschia/finschia-sdk/types/address" + "github.com/Finschia/finschia-sdk/types/kv" +) const ( // ModuleName is the module name constant used in many places ModuleName = "fbridge" - // StoreKey is the store key string for distribution + // StoreKey is the store key string for fbridge StoreKey = ModuleName + + // MemStoreKey is the in-memory store key string for fbridge + MemStoreKey = "mem_" + StoreKey ) +// - 0x01: params +// - 0x02: next sequence number for bridge sending +// - 0x03