From da4093325525c23c4bc117b97765378fc335d503 Mon Sep 17 00:00:00 2001 From: Jaeseung Lee <41176085+tkxkd0159@users.noreply.github.com> Date: Tue, 7 May 2024 21:26:19 +0900 Subject: [PATCH] feat: add role-based access control for bridge (#1358) * 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 (cherry picked from commit 1c272c99f254e80575476b635fc80475194db59a) # Conflicts: # CHANGELOG.md # client/docs/swagger-ui/swagger.yaml # x/ERRORS.md --- CHANGELOG.md | 5 + client/docs/config.json | 9 +- client/docs/swagger-ui/swagger.yaml | 1106 ++++++++++---- 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 | 323 ++++ 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, 7418 insertions(+), 1819 deletions(-) create mode 100644 x/ERRORS.md 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 2bfcd7d7fa..92ede9ab58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,12 +39,17 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased](https://github.com/Finschia/finschia-sdk/compare/v0.48.1...HEAD) ### Features +<<<<<<< HEAD +======= +* (consensus) [\#1178](https://github.com/Finschia/finschia-sdk/pull/1178) change the consensus from Ostracon to Tendermint v0.34.24 +>>>>>>> 1c272c99f (feat: add role-based access control for bridge (#1358)) * (x/fswap) [\#1336](https://github.com/Finschia/finschia-sdk/pull/1336) Initialize fswap module * (x/fswap) [\#1339](https://github.com/Finschia/finschia-sdk/pull/1339) Implement fswap module's genesis * (x/fbridge) [\#1340](https://github.com/Finschia/finschia-sdk/pull/1340) Initialize fbridge module * (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 * (types) [\#1314](https://github.com/Finschia/finschia-sdk/pull/1314) replace IsEqual with Equal diff --git a/client/docs/config.json b/client/docs/config.json index 5f216e3efe..97cd452052 100644 --- a/client/docs/config.json +++ b/client/docs/config.json @@ -197,11 +197,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 3a744c18f7..6bbb6d56bf 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -33998,17 +33998,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 @@ -34034,60 +34034,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: + role: 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 - /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: @@ -34110,6 +34076,11 @@ paths: value: type: string format: byte + parameters: + - name: address + in: path + required: true + type: string tags: - Query /lbm/fbridge/v1/params: @@ -34164,13 +34135,366 @@ paths: timelock_period: type: string format: uint64 - title: >- - default timelock period for each provision (unix - timestamp) - proposal_period: + title: >- + default timelock period for each provision (unix + timestamp) + proposal_period: + type: string + format: uint64 + title: default period of the proposal to update the role + 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 + /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 - format: uint64 - title: default period of the proposal to update the role + 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: @@ -34193,6 +34517,18 @@ paths: 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}': @@ -34523,221 +34859,10 @@ paths: 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 - tags: - - Query - '/lbm/fbridge/v1/role/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: uint64 - title: >- - the unix timestamp the proposal will be expired (unix - timestamp) + provision. + + To optimize computational cost, we have collected frequently + changing values from provision. default: description: An unexpected error response schema: @@ -34761,11 +34886,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: @@ -34856,16 +34982,53 @@ paths: format: byte tags: - Query +<<<<<<< HEAD '/lbm/tx/v1beta1/txs/block/{height}': get: summary: GetBlockWithTxs fetches a block with decoded txs. description: 'Since: finschia-sdk 0.47.0' operationId: GetBlockWithTxs2 +======= + /lbm/fbridge/v1/status: + get: + summary: BridgeStatus queries the status of the bridge + operationId: BridgeStatus +>>>>>>> 1c272c99f (feat: add role-based access control for bridge (#1358)) responses: '200': description: A successful response. schema: +<<<<<<< HEAD $ref: '#/definitions/lbm.tx.v1beta1.GetBlockWithTxsResponse' +======= + 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. +>>>>>>> 1c272c99f (feat: add role-based access control for bridge (#1358)) default: description: An unexpected error response schema: @@ -34885,6 +35048,7 @@ paths: properties: type_url: type: string +<<<<<<< HEAD description: >- A URL/resource name that uniquely identifies the type of the serialized @@ -35122,6 +35286,13 @@ paths: format: boolean tags: - Service +======= + value: + type: string + format: byte + tags: + - Query +>>>>>>> 1c272c99f (feat: add role-based access control for bridge (#1358)) definitions: cosmos.auth.v1beta1.Params: type: object @@ -58229,7 +58400,34 @@ definitions: minimum_gas_price: type: string description: ConfigResponse defines the response structure for the Config gRPC query. +<<<<<<< HEAD lbm.tx.v1beta1.GetBlockWithTxsResponse: +======= + 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: +>>>>>>> 1c272c99f (feat: add role-based access control for bridge (#1358)) type: object properties: txs: @@ -58274,6 +58472,7 @@ definitions: Consensus captures the consensus rules for processing a block in the blockchain, +<<<<<<< HEAD including all blockchain data structures and the rules of the application's @@ -58794,6 +58993,195 @@ definitions: format: byte pagination: description: pagination defines a pagination for the response. +======= + 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: + commitments: + type: array + items: + type: string + lbm.fbridge.v1.QueryConfirmedProvisionResponse: + 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. + lbm.fbridge.v1.QueryGreatestConsecutiveConfirmedSeqResponse: + type: object + properties: + seq: + type: string + format: uint64 + lbm.fbridge.v1.QueryGreatestSeqByOperatorResponse: + type: object + properties: + seq: + type: string + format: uint64 + lbm.fbridge.v1.QueryMemberResponse: + type: object + properties: + role: + type: string + lbm.fbridge.v1.QueryMembersResponse: + type: object + properties: + members: + type: array + items: + type: string + lbm.fbridge.v1.QueryNeededSubmissionSeqsResponse: + type: object + properties: + seqs: + type: array + items: + type: string + format: uint64 + lbm.fbridge.v1.QueryNextSeqSendResponse: + type: object + properties: + seq: + type: string + format: uint64 + lbm.fbridge.v1.QueryParamsResponse: + type: object + properties: + params: +>>>>>>> 1c272c99f (feat: add role-based access control for bridge (#1358)) + type: object + properties: + next_key: + type: string + format: byte + title: |- +<<<<<<< HEAD + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently + total: +======= + 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) + lbm.fbridge.v1.QueryProposalsResponse: + 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: @@ -58809,6 +59197,47 @@ definitions: 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: + blocknums: + type: array + items: + type: string + format: uint64 + lbm.fbridge.v1.QuerySubmittedProvisionResponse: + 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: +>>>>>>> 1c272c99f (feat: add role-based access control for bridge (#1358)) + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total + +<<<<<<< HEAD was set, its value is undefined otherwise description: >- GetBlockWithTxsResponse is the response type for the @@ -58816,3 +59245,138 @@ definitions: Since: finschia-sdk 0.47.0 +======= + 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: + - UNSPECIFIED + - GUARDIAN + - OPERATOR + - JUDGE + default: UNSPECIFIED + description: 'Role defines the role of the operator, guardian, and judge.' + lbm.fbridge.v1.RoleProposal: + 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) + 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. +>>>>>>> 1c272c99f (feat: add role-based access control for bridge (#1358)) diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index 244844700d..b608648fca 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -777,23 +777,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) @@ -803,6 +812,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) @@ -811,16 +822,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) @@ -831,6 +840,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) @@ -841,8 +854,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) @@ -851,8 +862,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) @@ -11746,77 +11757,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) | | | @@ -11824,6 +11922,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. | + + @@ -11832,119 +11970,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 | | + + + @@ -11976,6 +12111,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 @@ -12020,6 +12171,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. | @@ -12112,6 +12268,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 @@ -12228,50 +12410,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 | | @@ -12334,31 +12526,6 @@ GenesisState defines the fbridge module's genesis state. - - -### QueryOperatorsRequest - - - - - - - - - -### QueryOperatorsResponse - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `operators` | [string](#string) | repeated | | - - - - - - ### QueryParamsRequest @@ -12392,7 +12559,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 | @@ -12438,6 +12605,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. | @@ -12505,6 +12673,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. | + + + + + @@ -12528,11 +12757,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| @@ -12555,7 +12786,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 | @@ -12624,31 +12855,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 @@ -12756,24 +12962,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 @@ -12857,8 +13064,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 c0e5597804..7c9d8c98d3 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -276,7 +276,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 @@ -378,7 +378,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 ****/ @@ -476,6 +476,7 @@ func NewSimApp( capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, + fbridgetypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, @@ -493,7 +494,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 new file mode 100644 index 0000000000..d8dc1ea25e --- /dev/null +++ b/x/ERRORS.md @@ -0,0 +1,323 @@ + +# Category + * [Authz](#authz) + * [Bank](#bank) + * [Capability](#capability) + * [Collection](#collection) + * [Crisis](#crisis) + * [Distribution](#distribution) + * [Evidence](#evidence) + * [Fbridge](#fbridge) + * [Feegrant](#feegrant) + * [Foundation](#foundation) + * [Fswap](#fswap) + * [Gov](#gov) + * [Params](#params) + * [Slashing](#slashing) + * [Staking](#staking) + * [Token](#token) + + +## Authz + +|Error Name|Codespace|Code|Description| +|:-|:-|:-|:-| +|ErrInvalidExpirationTime|authz|3|expiration time of authorization should be more than current time| + +>You can also find detailed information in the following Errors.go files: + * [authz/errors.go](authz/errors.go) + +## Bank + +|Error Name|Codespace|Code|Description| +|:-|:-|:-|:-| +|ErrNoInputs|bank|2|no inputs to send transaction| +|ErrNoOutputs|bank|3|no outputs to send transaction| +|ErrInputOutputMismatch|bank|4|sum inputs != sum outputs| +|ErrSendDisabled|bank|5|send transactions are disabled| +|ErrDenomMetadataNotFound|bank|6|client denom metadata not found| +|ErrInvalidKey|bank|7|invalid key| + +>You can also find detailed information in the following Errors.go files: + * [bank/types/errors.go](bank/types/errors.go) + +## Capability + +|Error Name|Codespace|Code|Description| +|:-|:-|:-|:-| +|ErrInvalidCapabilityName|capability|2|capability name not valid| +|ErrNilCapability|capability|3|provided capability is nil| +|ErrCapabilityTaken|capability|4|capability name already taken| +|ErrOwnerClaimed|capability|5|given owner already claimed capability| +|ErrCapabilityNotOwned|capability|6|capability not owned by module| +|ErrCapabilityNotFound|capability|7|capability not found| +|ErrCapabilityOwnersNotFound|capability|8|owners not found for capability| + +>You can also find detailed information in the following Errors.go files: + * [capability/types/errors.go](capability/types/errors.go) + +## Collection + +|Error Name|Codespace|Code|Description| +|:-|:-|:-|:-| +|ErrTokenNotExist|collection|2|token symbol, token-id does not exist| +|ErrTokenNotMintable|collection|3|token symbol, token-id is not mintable| +|ErrInvalidTokenName|collection|4|token name should not be empty| +|ErrInvalidTokenID|collection|5|invalid token id| +|ErrInvalidTokenDecimals|collection|6|token decimals should be within the range in 0 ~ 18| +|ErrInvalidIssueFT|collection|7|Issuing token with amount[1], decimals[0], mintable[false] prohibited. Issue nft token instead.| +|ErrInvalidAmount|collection|8|invalid token amount| +|ErrInvalidBaseImgURILength|collection|9|invalid base_img_uri length| +|ErrInvalidNameLength|collection|10|invalid name length| +|ErrInvalidTokenType|collection|11|invalid token type pattern found| +|ErrInvalidTokenIndex|collection|12|invalid token index pattern found| +|ErrCollectionExist|collection|13|collection already exists| +|ErrCollectionNotExist|collection|14|collection does not exists| +|ErrTokenTypeExist|collection|15|token type for contract_id, token-type already exists| +|ErrTokenTypeNotExist|collection|16|token type for contract_id, token-type does not exist| +|ErrTokenTypeFull|collection|17|all token type for contract_id are occupied| +|ErrTokenIndexFull|collection|18|all non-fungible token index for contract_id, token-type are occupied| +|ErrTokenIDFull|collection|19|all fungible token-id for contract_id are occupied| +|ErrTokenNoPermission|collection|20|account does not have the permission| +|ErrTokenAlreadyAChild|collection|21|token is already a child of some other| +|ErrTokenNotAChild|collection|22|token is not a child of some other| +|ErrTokenNotOwnedBy|collection|23|token is being not owned by| +|ErrTokenCannotTransferChildToken|collection|24|cannot transfer a child token| +|ErrTokenNotNFT|collection|25|token is not a NFT| +|ErrCannotAttachToItself|collection|26|cannot attach token to itself| +|ErrCannotAttachToADescendant|collection|27|cannot attach token to a descendant| +|ErrApproverProxySame|collection|28|approver is same with proxy| +|ErrCollectionNotApproved|collection|29|proxy is not approved on the collection| +|ErrCollectionAlreadyApproved|collection|30|proxy is already approved on the collection| +|ErrAccountExist|collection|31|account already exists| +|ErrAccountNotExist|collection|32|account does not exists| +|ErrInsufficientSupply|collection|33|insufficient supply| +|ErrInvalidCoin|collection|34|invalid coin| +|ErrInvalidChangesFieldCount|collection|35|invalid count of field changes| +|ErrEmptyChanges|collection|36|changes is empty| +|ErrInvalidChangesField|collection|37|invalid field of changes| +|ErrTokenIndexWithoutType|collection|38|There is a token index but no token type| +|ErrTokenTypeFTWithoutIndex|collection|39|There is a token type of ft but no token index| +|ErrInsufficientToken|collection|40|insufficient token| +|ErrDuplicateChangesField|collection|41|duplicate field of changes| +|ErrInvalidMetaLength|collection|42|invalid meta length| +|ErrSupplyOverflow|collection|43|supply for collection reached maximum| +|ErrEmptyField|collection|44|required field cannot be empty| +|ErrCompositionTooDeep|collection|45|cannot attach token (composition too deep)| +|ErrCompositionTooWide|collection|46|cannot attach token (composition too wide)| +|ErrBurnNonRootNFT|collection|47|cannot burn non-root NFTs| + +>You can also find detailed information in the following Errors.go files: + * [collection/errors.go](collection/errors.go) + +## Crisis + +|Error Name|Codespace|Code|Description| +|:-|:-|:-|:-| +|ErrNoSender|crisis|2|sender address is empty| +|ErrUnknownInvariant|crisis|3|unknown invariant| + +>You can also find detailed information in the following Errors.go files: + * [crisis/types/errors.go](crisis/types/errors.go) + +## Distribution + +|Error Name|Codespace|Code|Description| +|:-|:-|:-|:-| +|ErrEmptyDelegatorAddr|distribution|2|delegator address is empty| +|ErrEmptyWithdrawAddr|distribution|3|withdraw address is empty| +|ErrEmptyValidatorAddr|distribution|4|validator address is empty| +|ErrEmptyDelegationDistInfo|distribution|5|no delegation distribution info| +|ErrNoValidatorDistInfo|distribution|6|no validator distribution info| +|ErrNoValidatorCommission|distribution|7|no validator commission to withdraw| +|ErrSetWithdrawAddrDisabled|distribution|8|set withdraw address disabled| +|ErrBadDistribution|distribution|9|community pool does not have sufficient coins to distribute| +|ErrInvalidProposalAmount|distribution|10|invalid community pool spend proposal amount| +|ErrEmptyProposalRecipient|distribution|11|invalid community pool spend proposal recipient| +|ErrNoValidatorExists|distribution|12|validator does not exist| +|ErrNoDelegationExists|distribution|13|delegation does not exist| + +>You can also find detailed information in the following Errors.go files: + * [distribution/types/errors.go](distribution/types/errors.go) + +## Evidence + +|Error Name|Codespace|Code|Description| +|:-|:-|:-|:-| +|ErrNoEvidenceHandlerExists|evidence|2|unregistered handler for evidence type| +|ErrInvalidEvidence|evidence|3|invalid evidence| +|ErrNoEvidenceExists|evidence|4|evidence does not exist| +|ErrEvidenceExists|evidence|5|evidence already exists| + +>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| +|:-|:-|:-|:-| +|ErrFeeLimitExceeded|feegrant|2|fee limit exceeded| +|ErrFeeLimitExpired|feegrant|3|fee allowance expired| +|ErrInvalidDuration|feegrant|4|invalid duration| +|ErrNoAllowance|feegrant|5|no allowance| +|ErrNoMessages|feegrant|6|allowed messages are empty| +|ErrMessageNotAllowed|feegrant|7|message not allowed| + +>You can also find detailed information in the following Errors.go files: + * [feegrant/errors.go](feegrant/errors.go) + +## Foundation + +|Error Name|Codespace|Code|Description| +|:-|:-|:-|:-| + +>You can also find detailed information in the following Errors.go files: + * [foundation/errors.go](foundation/errors.go) + +## Fswap + +|Error Name|Codespace|Code|Description| +|:-|:-|:-|:-| +|ErrInvalidState|fswap|2|swap module invalid state| +|ErrCanNotHaveMoreSwap|fswap|3|no more swap allowed| +|ErrSwappedNotFound|fswap|4|swapped does not exist| +|ErrExceedSwappableToCoinAmount|fswap|5|exceed swappable to-coin amount| + +>You can also find detailed information in the following Errors.go files: + * [fswap/types/errors.go](fswap/types/errors.go) + +## Gov + +|Error Name|Codespace|Code|Description| +|:-|:-|:-|:-| +|ErrUnknownProposal|gov|2|unknown proposal| +|ErrInactiveProposal|gov|3|inactive proposal| +|ErrAlreadyActiveProposal|gov|4|proposal already active| +|ErrInvalidProposalContent|gov|5|invalid proposal content| +|ErrInvalidProposalType|gov|6|invalid proposal type| +|ErrInvalidVote|gov|7|invalid vote option| +|ErrInvalidGenesis|gov|8|invalid genesis state| +|ErrNoProposalHandlerExists|gov|9|no handler exists for proposal type| + +>You can also find detailed information in the following Errors.go files: + * [gov/types/errors.go](gov/types/errors.go) + +## Params + +|Error Name|Codespace|Code|Description| +|:-|:-|:-|:-| +|ErrUnknownSubspace|params|2|unknown subspace| +|ErrSettingParameter|params|3|failed to set parameter| +|ErrEmptyChanges|params|4|submitted parameter changes are empty| +|ErrEmptySubspace|params|5|parameter subspace is empty| +|ErrEmptyKey|params|6|parameter key is empty| +|ErrEmptyValue|params|7|parameter value is empty| + +>You can also find detailed information in the following Errors.go files: + * [params/types/proposal/errors.go](params/types/proposal/errors.go) + +## Slashing + +|Error Name|Codespace|Code|Description| +|:-|:-|:-|:-| +|ErrNoValidatorForAddress|slashing|2|address is not associated with any known validator| +|ErrBadValidatorAddr|slashing|3|validator does not exist for that address| +|ErrValidatorJailed|slashing|4|validator still jailed; cannot be unjailed| +|ErrValidatorNotJailed|slashing|5|validator not jailed; cannot be unjailed| +|ErrMissingSelfDelegation|slashing|6|validator has no self-delegation; cannot be unjailed| +|ErrSelfDelegationTooLowToUnjail|slashing|7|validator's self delegation less than minimum; cannot be unjailed| +|ErrNoSigningInfoFound|slashing|8|no validator signing info found| + +>You can also find detailed information in the following Errors.go files: + * [slashing/types/errors.go](slashing/types/errors.go) + +## Staking + +|Error Name|Codespace|Code|Description| +|:-|:-|:-|:-| +|ErrEmptyValidatorAddr|staking|2|empty validator address| +|ErrNoValidatorFound|staking|3|validator does not exist| +|ErrValidatorOwnerExists|staking|4|validator already exist for this operator address; must use new validator operator address| +|ErrValidatorPubKeyExists|staking|5|validator already exist for this pubkey; must use new validator pubkey| +|ErrValidatorPubKeyTypeNotSupported|staking|6|validator pubkey type is not supported| +|ErrValidatorJailed|staking|7|validator for this address is currently jailed| +|ErrBadRemoveValidator|staking|8|failed to remove validator| +|ErrCommissionNegative|staking|9|commission must be positive| +|ErrCommissionHuge|staking|10|commission cannot be more than 100%| +|ErrCommissionGTMaxRate|staking|11|commission cannot be more than the max rate| +|ErrCommissionUpdateTime|staking|12|commission cannot be changed more than once in 24h| +|ErrCommissionChangeRateNegative|staking|13|commission change rate must be positive| +|ErrCommissionChangeRateGTMaxRate|staking|14|commission change rate cannot be more than the max rate| +|ErrCommissionGTMaxChangeRate|staking|15|commission cannot be changed more than max change rate| +|ErrSelfDelegationBelowMinimum|staking|16|validator's self delegation must be greater than their minimum self delegation| +|ErrMinSelfDelegationDecreased|staking|17|minimum self delegation cannot be decrease| +|ErrEmptyDelegatorAddr|staking|18|empty delegator address| +|ErrNoDelegation|staking|19|no delegation for (address, validator) tuple| +|ErrBadDelegatorAddr|staking|20|delegator does not exist with address| +|ErrNoDelegatorForAddress|staking|21|delegator does not contain delegation| +|ErrInsufficientShares|staking|22|insufficient delegation shares| +|ErrDelegationValidatorEmpty|staking|23|cannot delegate to an empty validator| +|ErrNotEnoughDelegationShares|staking|24|not enough delegation shares| +|ErrNotMature|staking|25|entry not mature| +|ErrNoUnbondingDelegation|staking|26|no unbonding delegation found| +|ErrMaxUnbondingDelegationEntries|staking|27|too many unbonding delegation entries for (delegator, validator) tuple| +|ErrNoRedelegation|staking|28|no redelegation found| +|ErrSelfRedelegation|staking|29|cannot redelegate to the same validator| +|ErrTinyRedelegationAmount|staking|30|too few tokens to redelegate (truncates to zero tokens)| +|ErrBadRedelegationDst|staking|31|redelegation destination validator not found| +|ErrTransitiveRedelegation|staking|32|redelegation to this validator already in progress; first redelegation to this validator must complete before next redelegation| +|ErrMaxRedelegationEntries|staking|33|too many redelegation entries for (delegator, src-validator, dst-validator) tuple| +|ErrDelegatorShareExRateInvalid|staking|34|cannot delegate to validators with invalid (zero) ex-rate| +|ErrBothShareMsgsGiven|staking|35|both shares amount and shares percent provided| +|ErrNeitherShareMsgsGiven|staking|36|neither shares amount nor shares percent provided| +|ErrInvalidHistoricalInfo|staking|37|invalid historical info| +|ErrNoHistoricalInfo|staking|38|no historical info found| +|ErrEmptyValidatorPubKey|staking|39|empty validator public key| + +>You can also find detailed information in the following Errors.go files: + * [staking/types/errors.go](staking/types/errors.go) + +## Token + +|Error Name|Codespace|Code|Description| +|:-|:-|:-|:-| +|ErrInvalidContractID|contract|2|invalid contractID| +|ErrContractNotExist|contract|3|contract does not exist| +|ErrTokenNotExist|token|2|token does not exist| +|ErrTokenNotMintable|token|3|token is not mintable| +|ErrInvalidTokenName|token|4|token name should not be empty| +|ErrInvalidTokenDecimals|token|5|token decimals should be within the range in 0 ~ 18| +|ErrInvalidAmount|token|6|invalid token amount| +|ErrInvalidImageURILength|token|7|invalid token uri length| +|ErrInvalidNameLength|token|8|invalid name length| +|ErrInvalidTokenSymbol|token|9|invalid token symbol| +|ErrTokenNoPermission|token|10|account does not have the permission| +|ErrAccountExist|token|11|account already exists| +|ErrAccountNotExist|token|12|account does not exists| +|ErrInsufficientBalance|token|13|insufficient balance| +|ErrSupplyExist|token|14|supply for token already exists| +|ErrInsufficientSupply|token|15|insufficient supply| +|ErrInvalidChangesFieldCount|token|16|invalid count of field changes| +|ErrEmptyChanges|token|17|changes is empty| +|ErrInvalidChangesField|token|18|invalid field of changes| +|ErrDuplicateChangesField|token|19|invalid field of changes| +|ErrInvalidMetaLength|token|20|invalid meta length| +|ErrSupplyOverflow|token|21|supply for token reached maximum| +|ErrApproverProxySame|token|22|approver is same with proxy| +|ErrTokenNotApproved|token|23|proxy is not approved on the token| +|ErrTokenAlreadyApproved|token|24|proxy is already approved on the token| + +>You can also find detailed information in the following Errors.go files: + * [token/class/errors.go](token/class/errors.go) + * [token/errors.go](token/errors.go) 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 19e78ec84f..c20ee8e34d 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/Finschia/ostracon/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 12b746828d..48774f7896 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