diff --git a/docs/common/bridging/001-bridging.md b/docs/common/bridging/001-bridging.md index fab4a03b..666d80b5 100644 --- a/docs/common/bridging/001-bridging.md +++ b/docs/common/bridging/001-bridging.md @@ -7,5 +7,5 @@ title: Bridging Bridging documentation describes current existing implementations over our cross-chain messaging protocol. -* [Bridging identity from Polygon](./002-identity.md) +* [Bridging identity from Polygon](./002-identity.md) * [Bridging identity from Rarimo](./003-rarimo-identity.md) \ No newline at end of file diff --git a/docs/common/bridging/002-identity.md b/docs/common/bridging/002-identity.md index e2a7e857..7d90d806 100644 --- a/docs/common/bridging/002-identity.md +++ b/docs/common/bridging/002-identity.md @@ -35,14 +35,20 @@ TBD In the current implementation the identity saver subscribes to the certain EVM chain state smart contract and tracks the `StateLibStateUpdated` events. Event definition: + ```go +package main + +import "math/big" + type StateLibStateUpdated struct { - Id *big.Int - BlockN *big.Int - Timestamp *big.Int - State *big.Int - Raw types.Log // Blockchain specific contextual infos + Id *big.Int + BlockN *big.Int + Timestamp *big.Int + State *big.Int + Raw types.Log // Blockchain specific contextual infos } + ``` The following configuration .yaml file should be provided to launch your oracle: diff --git a/docs/common/bridging/003-rarimo-identity.md b/docs/common/bridging/003-rarimo-identity.md index e26dc430..1a964ec4 100644 --- a/docs/common/bridging/003-rarimo-identity.md +++ b/docs/common/bridging/003-rarimo-identity.md @@ -10,7 +10,9 @@ that allows to skip transferring from Polygon to Rarimo in default flow. Also, a aggregated into one Merkle hash that allows us to update all states by single transaction. Generally, common flow looks like this: -- There is an operation type `IDENTITY_AGGREGATED_TRANSFER` that is used to transfer aggregated identity state overall issuers. + +- There is an operation type `IDENTITY_AGGREGATED_TRANSFER` that is used to transfer aggregated identity state overall + issuers. - Issuer publishes state transition into Rarimo EVM identity state contract. That state contract is fully compatible with original Iden3 state smartcontract. @@ -19,14 +21,18 @@ Generally, common flow looks like this: - In the `identiy` module `EndBlock` method the corresponding operation will be created. -- After some time, the threshold signature producers provides the ECDSA signature for aggregated state update information hash. +- After some time, the threshold signature producers provides the ECDSA signature for aggregated state update + information hash. -- There is a [modified state smart contracts](https://gitlab.com/rarimo/rarimoid/state-contracts) that accepts aggregated state updates with ECDSA signature instead of ZK proof of state update validity. +- There is a [modified state smart contracts](https://gitlab.com/rarimo/rarimoid/state-contracts) that accepts + aggregated state updates with ECDSA signature instead of ZK proof of state update validity. - Such smart contract should be deployed into every chain that we have to support. -- The information about state update with its witness (ECDSA signature) can be delivered into modified state smart contracts on the target chain by everyone. - After such signed update execution, all state updates on Rarimo chain becomes delivered on target chain by single transaction. +- The information about state update with its witness (ECDSA signature) can be delivered into modified state smart + contracts on the target chain by everyone. + After such signed update execution, all state updates on Rarimo chain becomes delivered on target chain by single + transaction. ---- @@ -34,12 +40,17 @@ Generally, common flow looks like this: On the DApp side the following flow should be executed to use our aggregated state: -1. Get state information from Rarimo: `/rarimo/rarimo-core/identity/state/{id}`. Also get path from `/rarimo/rarimo-core/identity/state/{id}/proof`. +1. Get state information from Rarimo: `/rarimo/rarimo-core/identity/state/{id}`. Also get path + from `/rarimo/rarimo-core/identity/state/{id}/proof`. 2. If the last state update timestamp is equal (or less) to the timestamp on target chain - go to (5). -3. Using `lastUpdateOperationIndex` call: `/rarimo/rarimo-core/rarimocore/operation/{index}`. It provides the information about GISTRoot and StatesRoot hash. Use it in state transition. +3. Using `lastUpdateOperationIndex` call: `/rarimo/rarimo-core/rarimocore/operation/{index}`. It provides the + information about GISTRoot and StatesRoot hash. Use it in state transition. -4. Using `lastUpdateOperationIndex` call: `/rarimo/rarimo-core/rarimocore/operation/{index}/proof`. Using signature, path and information from previous request execute `signedStateTransition` on target chain state smart contract. +4. Using `lastUpdateOperationIndex` call: `/rarimo/rarimo-core/rarimocore/operation/{index}/proof`. Using signature, + path and information from previous request execute `signedStateTransition` on target chain state smart contract. -5. Generate ZKP using state information from (1) request. Execute ZKP verification on [modified Verificator contract](https://gitlab.com/rarimo/rarimoid/state-contracts) using generated proof information, information and path from (1). +5. Generate ZKP using state information from (1) request. Execute ZKP verification + on [modified Verificator contract](https://gitlab.com/rarimo/rarimoid/state-contracts) using generated proof + information, information and path from (1). diff --git a/docs/common/contracts/001-contracts.md b/docs/common/contracts/001-contracts.md index ab198593..eb6ff51a 100644 --- a/docs/common/contracts/001-contracts.md +++ b/docs/common/contracts/001-contracts.md @@ -6,7 +6,8 @@ title: Smart-contracts overview # Smart-contracts overview Rarimo smart-contracts are the primary way to interact with our multi-chain protocol. -Developers can send data, assets, or liquidity; build cross-chain integrations; or retrieve protocol information using these contracts. +Developers can send data, assets, or liquidity; build cross-chain integrations; or retrieve protocol information using +these contracts. Whenever possible, we made sure to maintain similar interface and signatures to make integrating cross-chain easy. ---- @@ -18,5 +19,6 @@ Whenever possible, we made sure to maintain similar interface and signatures to - Repo: [EVM Bridge](https://github.com/rarimo/contracts/evm-bridge) Documentation: + * [Bridge architecture](./002-bridge.md) * [Bridge comission architecture](./003-commission.md) \ No newline at end of file diff --git a/docs/common/contracts/002-bridge.md b/docs/common/contracts/002-bridge.md index 5e9cc1b0..dbc607b0 100644 --- a/docs/common/contracts/002-bridge.md +++ b/docs/common/contracts/002-bridge.md @@ -5,10 +5,13 @@ title: Bridge overview # Bridge overview -Rarimo decentralized bridge contract is responsible for managing deposits and withdrawals for Native, fungible and non-fungible tokens. All withdrawal operations are protected by ECDSA secp256k1 threshold (t-n) signature. +Rarimo decentralized bridge contract is responsible for managing deposits and withdrawals for Native, fungible and +non-fungible tokens. All withdrawal operations are protected by ECDSA secp256k1 threshold (t-n) signature. This signature is produced by core multi-sig services depending on the validated core state. -The core service stores information to be signed in `operation` entries. `Operation` data structure consist of the following fields: +The core service stores information to be signed in `operation` entries. `Operation` data structure consist of the +following fields: + - index - operation type - details @@ -16,8 +19,9 @@ The core service stores information to be signed in `operation` entries. `Operat - creator address - timestamp +For token transfer there is an operation type `Type_TRANSFER` and the details field contain the following proto-encoded +information: -For token transfer there is an operation type `Type_TRANSFER` and the details field contain the following proto-encoded information: - origin hash (hash of tx, id and current network) - tx - event id (or operation id) @@ -28,7 +32,11 @@ For token transfer there is an operation type `Type_TRANSFER` and the details fi - bundle info (data and salt) - token information -For signing operations, the signature producer turns the operation content into special Merkle leaf content, creates a Merkle tree, signs its hash and submits the confirmation operation to the core. After, operation will be marked as signed and users can pool signature and operation information to submit into the bridge contract on the target chain. Smart-contract on the target chain should accept all information, perform validation, withdraw the corresponding token, and store information about the completed withdrawals to prevent double-spending. +For signing operations, the signature producer turns the operation content into special Merkle leaf content, creates a +Merkle tree, signs its hash and submits the confirmation operation to the core. After, operation will be marked as +signed and users can pool signature and operation information to submit into the bridge contract on the target chain. +Smart-contract on the target chain should accept all information, perform validation, withdraw the corresponding token, +and store information about the completed withdrawals to prevent double-spending. ---- @@ -40,7 +48,8 @@ Common transfer hash can be derived from the following sequence: OriginHash is a hash of `tx | eventId | current network`. Some parameters can be empty. -On our bridge currently supports the following token types: Native / ERC20 / ERC721 / ERC1155 / MetaplexFT / MetaplexNFT / NearFT / NearNFT +On our bridge currently supports the following token types: Native / ERC20 / ERC721 / ERC1155 / MetaplexFT / +MetaplexNFT / NearFT / NearNFT ---- @@ -55,12 +64,17 @@ On our bridge currently supports the following token types: Native / ERC20 / ERC ## Bridging flow -1. User wants to transfer the token from the current chain to the target one. For this, user submits a deposit transaction to the current chain bridge smart-contract. -2. Any other external services (or users by themselves) submit deposit information into the core service. Core service performs transaction validation before adding them to the ledger. +1. User wants to transfer the token from the current chain to the target one. For this, user submits a deposit + transaction to the current chain bridge smart-contract. +2. Any other external services (or users by themselves) submit deposit information into the core service. Core service + performs transaction validation before adding them to the ledger. 3. External services (signature producers) observe new operations in the core state and add them to the local pool. -4. Signature producers combine deposits into the Merkle tree, produce the threshold signature, and submit that info to the core. Core service performs the Merkle tree data and signature validation before adding it to the ledger. -5. After signed deposit information appears in the core state it becomes possible to call the withdrawal operation on the target network. -6. Smart-contract on the target network validates information about the deposit, Merkle path, and signature for the Merkle root, and performs a token withdrawal. +4. Signature producers combine deposits into the Merkle tree, produce the threshold signature, and submit that info to + the core. Core service performs the Merkle tree data and signature validation before adding it to the ledger. +5. After signed deposit information appears in the core state it becomes possible to call the withdrawal operation on + the target network. +6. Smart-contract on the target network validates information about the deposit, Merkle path, and signature for the + Merkle root, and performs a token withdrawal. diff --git a/docs/common/contracts/003-commission.md b/docs/common/contracts/003-commission.md index 49706188..a783f55e 100644 --- a/docs/common/contracts/003-commission.md +++ b/docs/common/contracts/003-commission.md @@ -10,6 +10,7 @@ To maintain successful work and reward validators and other people that support should charge protocol usage fee. Protocol fee in Rarimo will be charged for every type of cross-chain token transfer: + - Native - FT - and NFT transfers. @@ -21,8 +22,10 @@ For every transfer we will charge a constant amount on start and prepare ground ## Architecture In parameters, fee smart contract should contain the acceptable token addresses list, -amount for every token to be charged and bridge contract address. Those parameters should be managed by threshold signature. -To check the signature fee contract should execute a cross-contract call to the bridge contract to fetch the threshold public key. +amount for every token to be charged and bridge contract address. Those parameters should be managed by threshold +signature. +To check the signature fee contract should execute a cross-contract call to the bridge contract to fetch the threshold +public key. ---- @@ -33,11 +36,12 @@ address of selected fee token. Deposit method should check if the provided token If everything is well, deposit method performs charging of the corresponding fee amount and executes deposit method on the bridge contract. - Lets described flow more accurately: + 1. User selects the fee token and calls the deposit method on the fee contract. 2. Fee contract checks if the token is available to be charged fee in, and gets the fee amount. -3. Fee contract charges a fee amount from the user. (If it is EVM or Near, the approval token method should be called before by the user). +3. Fee contract charges a fee amount from the user. (If it is EVM or Near, the approval token method should be called + before by the user). 4. If charging was successful, the fee contract calls a bridge contract with provided deposit arguments. Also bridge smart-contract should be extended to receive deposit calls only from corresponding fee smart-contract. @@ -55,10 +59,12 @@ The public key should be taken from the bridge contract state. ## Management -For managing fee tokens, fee smart-contract should implement the **AddFeeToken**, **UpdateFeeToken**, **RemoveFeeToken**, +For managing fee tokens, fee smart-contract should implement the **AddFeeToken**, **UpdateFeeToken**, **RemoveFeeToken +**, **Withdraw** methods that accept token information and signature for corresponding hash. Let’s define the operation type enum with the following fields: + ``` 0 => AddFeeToken 1 => RemoveFeeToken @@ -69,30 +75,31 @@ Let’s define the operation type enum with the following fields: Let’s described flow more accurately: 1. Core provides signature and data to be changed on the fee contract. - For the AddFeeToken, UpdateFeeToken and RemoveFeeToken operation it should be: - __HASH( - nonce 32 byte, - contract addr, - network name, - operation type, - token addr if non-native otherwise none (in evm 20 zero bytes for native), - amount - )__ + For the AddFeeToken, UpdateFeeToken and RemoveFeeToken operation it should be: + __HASH( + nonce 32 byte, + contract addr, + network name, + operation type, + token addr if non-native otherwise none (in evm 20 zero bytes for native), + amount + )__ 2. For the withdrawal operation it should be: - __HASH( - nonce 32 byte, - receiver address, - contract addr, - network name, - operation type, - token addr if non-native otherwise none (in evm 20 zero bytes for native), - amount - )__ + __HASH( + nonce 32 byte, + receiver address, + contract addr, + network name, + operation type, + token addr if non-native otherwise none (in evm 20 zero bytes for native), + amount + )__ 3. Someone submits that information to the fee smart-contract. -4. Fee contract calculates hash of provided data and checks that signature public key corresponds to the key on bridge smart contract. +4. Fee contract calculates hash of provided data and checks that signature public key corresponds to the key on bridge + smart contract. 5. If all checks were correct, fee smart-contract updates state according to the provided information. @@ -100,5 +107,6 @@ Let’s described flow more accurately: ## Conclusion -On different networks the smart contracts architecture can be may differ from what is described cause of chain smart contracts peculiarities. +On different networks the smart contracts architecture can be may differ from what is described cause of chain smart +contracts peculiarities. Explore every contract by yourself to gent better understanding. diff --git a/docs/common/core/001-adding-operation.md b/docs/common/core/001-adding-operation.md index a1c853c4..821a444d 100644 --- a/docs/common/core/001-adding-operation.md +++ b/docs/common/core/001-adding-operation.md @@ -7,18 +7,20 @@ title: Adding new operation To provide TSS signature core uses operations and confirmation entities. Operation entity represents some data to be signed by threshold signature producers. -Confirmation entity represents information about signature: indexes list, merkle root based on provided list and signature. +Confirmation entity represents information about signature: indexes list, merkle root based on provided list and +signature. Operation entity contains the following fields: + ```protobuf - message Operation { - string index = 1; - opType operationType = 2; - google.protobuf.Any details = 3; - opStatus status = 4; - string creator = 5; - uint64 timestamp = 6; - } +message Operation { + string index = 1; + opType operationType = 2; + google.protobuf.Any details = 3; + opStatus status = 4; + string creator = 5; + uint64 timestamp = 6; +} ``` - index is the unique string that should be deterministic created depending on operation data @@ -26,15 +28,16 @@ Operation entity contains the following fields: - details contain any necessary information about operation to provide signature for - status defines the current status of operation (signed, approved, initialize, etc.) - creator defines the creator of certain operation -- timestamp contains the unix block timestamp then operation was created (the timestamp should be received from the context) +- timestamp contains the unix block timestamp then operation was created (the timestamp should be received from the + context) ---- **To add new operation developer should lead the following steps:** 1. Add operation data definition in the `proto/rarimocore`. Example: -
- proto/ratimocore/op_fee_token_management.proto + + ___proto/ratimocore/op_fee_token_management.proto___ ```protobuf enum FeeTokenManagementType { @@ -51,11 +54,10 @@ Operation entity contains the following fields: string receiver = 4; } ``` -
- Also, add new operation type in `proto/rarimocore/operation.proto`. -
- proto/rarimocore/operation.proto + Also, add new operation type in `proto/rarimocore/operation.proto`. + + ___proto/rarimocore/operation.proto___ ```protobuf enum opType { @@ -64,14 +66,14 @@ Operation entity contains the following fields: FEE_TOKEN_MANAGEMENT = 2; } ``` -
---- -2. In `x/rarimocore/crypto/operation` define the operation content that should implement `merkle.Content` interface from `merkle "github.com/rarimo/go-merkle"`. - Example: -
- x/rarimocore/crypto/operation/op_fee_token_management.go +2. In `x/rarimocore/crypto/operation` define the operation content that should implement `merkle.Content` interface + from `merkle "github.com/rarimo/go-merkle"`. + Example: + + ___x/rarimocore/crypto/operation/op_fee_token_management.go___ ```go package operation @@ -111,17 +113,17 @@ Operation entity contains the following fields: return false } ``` -
---- 3. In `x/rarimocore/crypto/pkg` define the following methods: `Get{op name}` and `Get{op name} content`. - Example: -
- x/rarimocore/crypto/operation/op_fee_token_management.go + Example: + ___x/rarimocore/crypto/operation/op_fee_token_management.go___ ```go + package operation + func GetFeeTokenManagement(operation types.Operation) (*types.FeeTokenManagement, error) { if operation.OperationType == types.OpType_FEE_TOKEN_MANAGEMENT { op := new(types.FeeTokenManagement) @@ -139,65 +141,71 @@ Operation entity contains the following fields: Data: data.NewFeeTokenDataBuilder().SetOpType(op.OpType).SetAmount(op.Token.Amount).SetAmount(op.Token.Amount).Build().GetContent(), }, nil } + ``` -
- **Tips**: explore the `x/rarimocore/crypto/operation/data` and `x/rarimocore/crypto/operation/origin` packages to use some useful utils from it or add the new if required. +**Tips**: explore the `x/rarimocore/crypto/operation/data` and `x/rarimocore/crypto/operation/origin` packages to use +some useful utils from it or add the new if required. ---- -4. In the `x/rarimocore/keeper` define function that creates the operation and define function call where it is required. +4. In the `x/rarimocore/keeper` define function that creates the operation and define function call where it is + required. ---- -5. In the `x/rarimocore/keeper/msg_server_confirmation.go` extend the existing logic of `getContent(ctx sdk.Context, op types.Operation) (merkle.Content, error)` method. - For example add: - ```go - case types.OpType_FEE_TOKEN_MANAGEMENT: - manage, err := pkg.GetFeeTokenManagement(op) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "failed to unmarshal details") - } - return k.getFeeTokenManagementContent(ctx, op.Index, manage) - ``` - -
- Example +5. In the `x/rarimocore/keeper/msg_server_confirmation.go` extend the existing logic + of `getContent(ctx sdk.Context, op types.Operation) (merkle.Content, error)` method. + For example add: - ```go - func (k msgServer) getContent(ctx sdk.Context, op types.Operation) (merkle.Content, error) { - switch op.OperationType { - case types.OpType_TRANSFER: - transfer, err := pkg.GetTransfer(op) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "failed to unmarshal details") - } - - return k.getTransferOperationContent(ctx, transfer) - case types.OpType_CHANGE_PARTIES: - change, err := pkg.GetChangeParties(op) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "failed to unmarshal details") - } - - return pkg.GetChangePartiesContent(change) - case types.OpType_FEE_TOKEN_MANAGEMENT: - manage, err := pkg.GetFeeTokenManagement(op) - if err != nil { + ```go + case types.OpType_FEE_TOKEN_MANAGEMENT: + manage, err := pkg.GetFeeTokenManagement(op) + if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "failed to unmarshal details") - } - return k.getFeeTokenManagementContent(ctx, op.Index, manage) - default: - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid operation") } - } - ``` -
+ return k.getFeeTokenManagementContent(ctx, op.Index, manage) + ``` + + Example: + + ```go + func (k msgServer) getContent(ctx sdk.Context, op types.Operation) (merkle.Content, error) { + switch op.OperationType { + case types.OpType_TRANSFER: + transfer, err := pkg.GetTransfer(op) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "failed to unmarshal details") + } + + return k.getTransferOperationContent(ctx, transfer) + case types.OpType_CHANGE_PARTIES: + change, err := pkg.GetChangeParties(op) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "failed to unmarshal details") + } + + return pkg.GetChangePartiesContent(change) + case types.OpType_FEE_TOKEN_MANAGEMENT: + manage, err := pkg.GetFeeTokenManagement(op) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "failed to unmarshal details") + } + return k.getFeeTokenManagementContent(ctx, op.Index, manage) + default: + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid operation") + } + } + ``` + ---- -6. Also, you can provide additional logic in `ApplyOperation(ctx sdk.Context, op types.Operation) error` to execute some stuff after signing if required. +6. Also, you can provide additional logic in `ApplyOperation(ctx sdk.Context, op types.Operation) error` to execute some + stuff after signing if required. ---- -7. Extend `tss-svc` service ` GetContents(client *grpc.ClientConn, operations ...*rarimo.Operation) ([]merkle.Content, error)` method in `internal/core/controllers/util.go` to include new operation in the signing process. +7. Extend `tss-svc` + service ` GetContents(client *grpc.ClientConn, operations ...*rarimo.Operation) ([]merkle.Content, error)` method + in `internal/core/controllers/util.go` to include new operation in the signing process. diff --git a/docs/common/core/002-creating-genesis.md b/docs/common/core/002-creating-genesis.md index dd6b9542..f2d4f15d 100644 --- a/docs/common/core/002-creating-genesis.md +++ b/docs/common/core/002-creating-genesis.md @@ -3,34 +3,40 @@ layout: default title: Setup local genesis state --- -# Setup local genesis state +# Setup local genesis state ### Creating validator key + ```shell rarimo-cored keys add validator_key --keyring-backend test --home=./genesis ``` ### Exporting validator address + ```shell export MY_VALIDATOR_ADDRESS=rarimo10efu3md78z8qhlzjsx8u0kq3p7j3uhhf80yp5u ``` ### Init chain + ```shell rarimo-cored init main --chain-id rarimo-core --home=./genesis ``` ### Adding account to genesis + ```shell rarimo-cored add-genesis-account $MY_VALIDATOR_ADDRESS 1000000000000stake --home=./genesis ``` ### Generating add-validator transaction + ```shell rarimo-cored gentx validator_key 10000000000stake --chain-id rarimo-core --keyring-backend test --home=./genesis ``` ### Importing transaction into genesis file + ```shell rarimo-cored collect-gentxs --home=./genesis ``` diff --git a/docs/common/mainnet/002-upgrades.md b/docs/common/mainnet/002-upgrades.md index 3f56fe3a..b3d3421d 100644 --- a/docs/common/mainnet/002-upgrades.md +++ b/docs/common/mainnet/002-upgrades.md @@ -6,36 +6,43 @@ title: Mainnet upgrades # Mainnet upgrades ## V1.0.7 + Core binary: (alpine-linux/amd64): "". -Also, you can build core from sources by yourself: Use <"https://github.com/rarimo/rarimo-core"> repo and `chains/mainnet` branch. +Also, you can build core from sources by yourself: Use <"https://github.com/rarimo/rarimo-core"> repo +and `chains/mainnet` branch. Upgrade will perform automatically if you are using `cosmovisor` under Alpine linux. -Also, if you are using Ubuntu linux, please install `musl-dev` using `sudo apt install musl-dev` command to be able to use Alpine binary on your machine. +Also, if you are using Ubuntu linux, please install `musl-dev` using `sudo apt install musl-dev` command to be able to +use Alpine binary on your machine. Upgrade v1.0.7 introduces fixes to the `rarimocore` module: + - Adding feature to clear old TSS violation reports. -- Manual unfreeze of all TSS parties without necessity to reshare keys. +- Manual unfreeze of all TSS parties without necessity to reshare keys. ## V1.0.6 Core binary: (alpine-linux/amd64): "" Upgrade will perform automatically if you are using `cosmovisor` under Alpine linux. -Also, if you are using Ubuntu linux, please install `musl-dev` using `sudo apt install musl-dev` command to be able to use Alpine binary on your machine. +Also, if you are using Ubuntu linux, please install `musl-dev` using `sudo apt install musl-dev` command to be able to +use Alpine binary on your machine. Upgrade V1.0.6 introduces: + - Adding message for operation resign by Threshold signature producers. - Changing of stored TSS pub-key format: removing constant 0x04 prefix. -- Adding `admin` field in supported network BridgeParams that will contain the pub-key of the bridge admin on Solana. -- Some minor fixes in: several operation creation entrypoints, updating params of the supported networks, +- Adding `admin` field in supported network BridgeParams that will contain the pub-key of the bridge admin on Solana. +- Some minor fixes in: several operation creation entrypoints, updating params of the supported networks, ## V1.0.5 Core binary: (alpine-linux/amd64): "" Upgrade will perform automatically if you are using `cosmovisor` under Alpine linux. -Also, if you are using Ubuntu linux, please install `musl-dev` using `sudo apt install musl-dev` command to be able to use Alpine binary on your machine. +Also, if you are using Ubuntu linux, please install `musl-dev` using `sudo apt install musl-dev` command to be able to +use Alpine binary on your machine. Upgrade v1.0.5 introduces several fixes: @@ -47,18 +54,22 @@ Upgrade v1.0.5 introduces several fixes: Core binary (linux/amd64): "" Upgrade will perform automatically if you are using `cosmovisor` under Alpine linux. -Also, if you are using Ubuntu linux, please install `musl-dev` using `sudo apt install musl-dev` command to be able to use Alpine binary on your machine. +Also, if you are using Ubuntu linux, please install `musl-dev` using `sudo apt install musl-dev` command to be able to +use Alpine binary on your machine. Upgrade v1.0.4 introduces `identity` core module that is responsible for storing aggregated information about -identity state transitions published into Rarimo chain. It uses deployed into Rarimo EVM original Iden3 state smart-contracts. +identity state transitions published into Rarimo chain. It uses deployed into Rarimo EVM original Iden3 state +smart-contracts. Also, there was a couple of fixes in Rarimo evm part and other modules. -`rarimocore` and `oraclemanager` modules genesis `freezedBlock` parameters was set to `103680` that is equal to 2x `gov` voting time. +`rarimocore` and `oraclemanager` modules genesis `freezedBlock` parameters was set to `103680` that is equal to 2x `gov` +voting time. `feemanager` module `baseFee` parameter was set to 0 to disable fee for EVM transactions. Also, we introduce new version of the following services: + - tss-svc:v1.0.4 Link:"" @@ -69,21 +80,24 @@ Also, we introduce new version of the following services: Note, that there is a couple of changes in `evm-identity-saver-svc` config file: Old: + ```yaml state_contract_cfg: issuer_id: "24681524151353338075533135666067797260271579497198610066639546696060309762" ``` New: + ```yaml state_contract_cfg: - issuer_id: [''] + issuer_id: [ '' ] disable_filtration: true ``` Also, there are some updates in Rarimo node configuration: config.toml: + ```yaml max_subscriptions_per_client = 50 ``` @@ -91,4 +105,5 @@ max_subscriptions_per_client = 50 ---- ## v1.0.1 + Mainnet launched! diff --git a/docs/common/mainnet/003-validator-guide.md b/docs/common/mainnet/003-validator-guide.md index c4ccef51..a9942da0 100644 --- a/docs/common/mainnet/003-validator-guide.md +++ b/docs/common/mainnet/003-validator-guide.md @@ -9,6 +9,7 @@ This instruction tells how to start one or another system service. It is assumed that you are already familiar with Linux and are fluent in it Service start order: + 1. node (rarimo-core) 2. broadcaster-svc 3. evm-identity-saver-svc @@ -27,6 +28,7 @@ APP file: "" Rarimo core binary (linux/amd64): "" To, generate validator configs, use: + - `rarimo-core` file in link. - node ip connect: `34.66.205.183`. Use for submitting TX as well as for p2p connection. @@ -35,6 +37,7 @@ Also use the following P2P connection to our RPC node: `39072210913bb52a6444543a Execute te following scripts: Set Envs + ```bash export MONIKER_NAME=YOU_VALIDATOR_NAME export RARIMO_HOME=YOU_RARIMO_HOME_PATH @@ -42,6 +45,7 @@ export RARIMO_NODE=tcp://34.66.205.183:26657 ``` Init folder structure: + ```bash rarimo-core init $MONIKER_NAME --chain-id=rarimo_201411-1 --home=$RARIMO_HOME ``` @@ -49,6 +53,7 @@ rarimo-core init $MONIKER_NAME --chain-id=rarimo_201411-1 --home=$RARIMO_HOME Paste custom `genesis.json` and `app.toml` in `$RARIMO_HOME/config/` folder. Create validator private key: + ```bash rarimo-core keys add --keyring-backend test --home=$RARIMO_HOME ``` @@ -58,16 +63,19 @@ Save your mnemonic and address. That address will be used for your validator sta Send you address (rarimo...) to `yp@distributedlab.com` or `vl@distributedlab.com`. To setup broadcaster service later you will need a private key. Use your mnemonic to get ECDSA private key (0x...): + ```bash rarimo-core tx rarimocore parse-mnemonic 'mnemonic phrase' ``` Also, add environment var with created address: + ```bash export LOCAL_VALIDATOR_ADDRESS=rarimo... ``` Please, backup the following files and folders: + ```bash $RARIMO_HOME/config/priv_validator_key.json $RARIMO_HOME/config/node_key.json @@ -75,28 +83,32 @@ $RARIMO_HOME/keyring-test ``` Check validator seed: + ```bash rarimo-core tendermint show-node-id --home=$RARIMO_HOME ``` Check key exists in keystore: + ```bash rarimo-core keys show $LOCAL_VALIDATOR_ADDRESS --keyring-backend test --home=$RARIMO_HOME ``` To run use env variables: + ```yaml - name: DAEMON_NAME value: "rarimo-core" -- name: DAEMON_HOME + - name: DAEMON_HOME value: $RARIMO_HOME -- name: DAEMON_ALLOW_DOWNLOAD_BINARIES + - name: DAEMON_ALLOW_DOWNLOAD_BINARIES value: "true" ``` Use the following command to start your node: + ```bash mkdir -p $DAEMON_HOME/cosmovisor/genesis/bin && cp YOU_STORE_CORE_BIN(name rarimo-core) $DAEMON_HOME/cosmovisor/genesis/bin && cosmovisor run start --home=$RARIMO_HOME --rpc.laddr tcp://0.0.0.0:26657 ``` @@ -137,6 +149,7 @@ cosmos: ``` You will also need some environment variables to run: + ```yaml - name: KV_VIPER_FILE value: /config/config.yaml # The path to your config file @@ -145,16 +158,19 @@ You will also need some environment variables to run: The execution of 2 following commands is required for launch: 1. To perform migrations + ```bash broadcaster-svc migrate up ``` 2. To start the service + ```bash broadcaster-svc run all ``` Also, you can run these commands together like this: + ```bash broadcaster-svc migrate up && broadcaster-svc run all ``` @@ -163,7 +179,8 @@ broadcaster-svc migrate up && broadcaster-svc run all ## EVM identity saver -EVM identity saver service binary (linux/amd64): "" +EVM identity saver service binary ( +linux/amd64): "" Currently, it should be one instance per account only for Polygon. @@ -213,11 +230,12 @@ profiler: ## Issuer information state_contract_cfg: - issuer_id: [''] + issuer_id: [ '' ] disable_filtration: true ``` Also, some environment variables will be needed to run + ```yaml - name: KV_VIPER_FILE value: /config/config.yaml # is the path to your config file @@ -227,6 +245,7 @@ Oracle service requires staking of some RMO tokens in Rarimo chain. Please, **do not start** the service before we confirm your oracle staking. To start the service (in vote mode) use the following command: + ```bash evm-identity-saver-svc run state-update-voter ``` @@ -245,7 +264,7 @@ To become an active TSS you need to follow that steps: rarimo-core keys add --keyring-backend test --home=$TSS_HOME ``` - Also, you need to parse mnemonic to get corresponding private key: +Also, you need to parse mnemonic to get corresponding private key: ```shell rarimo-core tx rarimocore parse-mnemonic 'mnemonic phrase' @@ -263,26 +282,27 @@ To become an active TSS you need to follow that steps: tss-svc run prvgen ``` -4. Setup the Vault service and create secret for your tss (type KV version 2). Secret should contain the following credentials: +4. Setup the Vault service and create secret for your tss (type KV version 2). Secret should contain the following + credentials: - * "data": "Leave empty" +* "data": "Leave empty" - * "pre": "Generated pre params JSON" +* "pre": "Generated pre params JSON" - * "account": "Your Rarimo account hex key" +* "account": "Your Rarimo account hex key" - * "trial": "Generated Trial ECDSA private key hex" +* "trial": "Generated Trial ECDSA private key hex" - JSON example: +JSON example: ```json { - "tls": true, - "data": "", - "pre": "pre-generated-secret-data", - "account": "rarimo-account-private-key-hex-leading-0x", - "trial": "trial-ecdsa-private-key-hex-leading-0x" - } + "tls": true, + "data": "", + "pre": "pre-generated-secret-data", + "account": "rarimo-account-private-key-hex-leading-0x", + "trial": "trial-ecdsa-private-key-hex-leading-0x" +} ``` 5. Create a configuration file `config.yaml` with the following structure: @@ -329,18 +349,18 @@ To become an active TSS you need to follow that steps: coin_name: "urmo" ``` - Set up host environment: +Set up host environment: ```yaml - name: KV_VIPER_FILE value: /config/config.yaml # is the path to your config file - - name: VAULT_PATH + - name: VAULT_PATH value: http://vault-internal:8200 # your vault endpoint - - name: VAULT_TOKEN + - name: VAULT_TOKEN value: "" # your vault token ("root"/"read/write") - - name: MOUNT_PATH + - name: MOUNT_PATH value: secret - - name: SECRET_PATH + - name: SECRET_PATH value: tss # name of the secret path vault (type KV version 2) ``` @@ -350,11 +370,12 @@ To become an active TSS you need to follow that steps: tss-svc migrate up && tss-svc run service ``` -7. After launching of your service, share your tss-svc URL, rarimo account address and ECDSA public key with `yp@distributedlab.com` or `vl@distributedlab.com`. +7. After launching of your service, share your tss-svc URL, rarimo account address and ECDSA public key + with `yp@distributedlab.com` or `vl@distributedlab.com`. - Note, that your TSS service should be accessible only using secure TLS connection. +Note, that your TSS service should be accessible only using secure TLS connection. - After some period your TSS will generate new keys with other active parties and become an active party. +After some period your TSS will generate new keys with other active parties and become an active party. ---- @@ -374,31 +395,37 @@ Congratulations, you are the Rarimo Mainnet validator! ## Useful commands Query delegator rewards for all validators: + ```shell rarimo-core query distribution rewards [delegator address rarimo...] --node=https://rpc.mainnet.rarimo.com:443 ``` or for certain validator: + ```shell rarimo-core query distribution rewards [delegator address rarimo...] [valdidator address rarimovaloper...] --node=https://rpc.mainnet.rarimo.com:443 ``` Query un-withdrawn rewards: + ```shell rarimo-core query distribution validator-outstanding-rewards [valdidator address rarimovaloper...] --node=https://rpc.mainnet.rarimo.com:443 ``` Query validator commission: + ```shell rarimo-core query distribution commission rarimovaloper... --node=https://rpc.mainnet.rarimo.com:443 ``` Withdraw all validator rewards for a delegator: + ```shell rarimo-core tx distribution withdraw-all-rewards --from=rarimo... --node=https://rpc.mainnet.rarimo.com:443 --home=path-to-home-with-keyring ``` Withdraw certain validator rewards for a delegator (add `--commission` flag to withdraw commissions also): + ```shell rarimo-core tx distribution withdraw-rewards rarimovaloper1... --from rarimo... --commission --node=https://rpc.mainnet.rarimo.com:443 --home=path-to-home-with-keyring ``` diff --git a/docs/common/oracles/001-oracles.md b/docs/common/oracles/001-oracles.md index b141911d..a44d0c9b 100644 --- a/docs/common/oracles/001-oracles.md +++ b/docs/common/oracles/001-oracles.md @@ -25,10 +25,12 @@ verify events delivered from other oracles. In particular oracles should observe create transfer operations, submit them into the core and vote for correctness of submitted operations. The oracle services designed to be launched by anyone in two supported modes: + - saver (connects to the chain rpc and submits new transfer operations to the Rarimo core) - voter (fetches new operations from core, verifies the content and votes for its correctness) Currently, there are three implementations exists: + - evm-saver (used with any evm-compatible chains) - solana-saver (used with any solana-compatible chains) - near-saver (used with any near-compatible chains) @@ -38,31 +40,41 @@ Currently, there are three implementations exists: ## Logic ### Native and FT + For native and fungible tokens all information should be pre-defined in collections of `tokenmanager` module. So oracles should only fetch the corresponding data and submit it in `MsgCreateTransferOp` transaction. ### NFT + NFT tokens collection can contain huge amount of tokens under it, and also they can be minted if future. -So we can not define all tokens in core during initialization or token add operation. That is why collections flow was created. +So we can not define all tokens in core during initialization or token add operation. That is why collections flow was +created. Using `tokenmanager` `Collection` and `CollectionData` we can define collection global and chain information regardless of the number of tokens in collection or their metadata. Token information (`Item` and `OnChainItem`) will be set up during the first token transfer. -During the first transfer oracles should fill the metadata field in `MsgCreateTransferOp` and provide all required token information to create `Item` and `OnChainItem`. +During the first transfer oracles should fill the metadata field in `MsgCreateTransferOp` and provide all required token +information to create `Item` and `OnChainItem`. -Token addresses are equal to the token collection addresses that is already defined in `Collection` but for token id we should provide more complicated implementation. +Token addresses are equal to the token collection addresses that is already defined in `Collection` but for token id we +should provide more complicated implementation. Let's describe the flow more accurately: -1. If token was already transferred between source and destination chain no additional actions required. Oracle just - fetches `OnChainItem` from core and leaves metadata field empty. +1. If token was already transferred between source and destination chain no additional actions required. Oracle just + fetches `OnChainItem` from core and leaves metadata field empty. -2. If source `OnChainItem` exists but destination `OnChainItem` does no (it means that token never was transferred on destination chain) - oracle should construct destination `OnChainItem` using the following rules: - - if destination chain is Solana, tokenId should be derived using bridge address and seed from `Item` metadata (`Item` should exist cause `OnChainItem` exists) -- otherwise tokenId will be equal to the home chain tokenId (the chain where token was minted firstly). +2. If source `OnChainItem` exists but destination `OnChainItem` does no (it means that token never was transferred on + destination chain) + oracle should construct destination `OnChainItem` using the following rules: -3. If source `OnChainItem` does not exists it means that we are transferring token at first time and `Item` with its metadata also does not exist. - So oracle should create `Item` metadata which means fetching on-chain metadata and generation of solana seed. Then using paragraph 2 rules oracle constructs destination `OnChainItem`. - Source `OnChainItem`, which is home `OnChainItem`, can be constructed using deposit event information. +- if destination chain is Solana, tokenId should be derived using bridge address and seed from `Item` metadata (`Item` + should exist cause `OnChainItem` exists) +- otherwise tokenId will be equal to the home chain tokenId (the chain where token was minted firstly). + +3. If source `OnChainItem` does not exists it means that we are transferring token at first time and `Item` with its + metadata also does not exist. + So oracle should create `Item` metadata which means fetching on-chain metadata and generation of solana seed. Then + using paragraph 2 rules oracle constructs destination `OnChainItem`. + Source `OnChainItem`, which is home `OnChainItem`, can be constructed using deposit event information. ---- @@ -70,7 +82,8 @@ Let's describe the flow more accurately: In `github.com/rarimo/saver-grpc-lib` we defined the common utils for all oracles. Every oracle should implement `verifiers.TransferOperator` interface for every supported token type -and put that implementations into the `voter.Subscriber` and `voter.Catchupper` using `verifiers.TransferVerifier` wrapper. +and put that implementations into the `voter.Subscriber` and `voter.Catchupper` using `verifiers.TransferVerifier` +wrapper. Also, we recommend to split `verifiers.TransferOperator` logic in two methods: verifier and message creator. It allows to use message creator while fetching new events and submitting them into core. @@ -79,7 +92,8 @@ It allows to use message creator while fetching new events and submitting them i ## Broadcaster integration -All oracles recommended to integrate with broadcaster service (`broadcaster-svc`) to submit queued transactions. Cause any transaction should contain valid account sequence +All oracles recommended to integrate with broadcaster service (`broadcaster-svc`) to submit queued transactions. Cause +any transaction should contain valid account sequence (is incremental value) it becomes problematically to submit concurrent transactions. So our oracles implementations use broadcaster service as an endpoint for sending messages using a queue. @@ -88,13 +102,18 @@ So our oracles implementations use broadcaster service as an endpoint for sendin ## Flow Saver mode flow: + 1. Oracle subscribes to the new events on bridge contract. 2. Oracle receives new event. 3. Oracle creates and submits `MsgCreateTransferOp` using `broadcaster-svc`. Voter mode flow: + 1. Oracle subscribes to the new operations on Rarimo core for defined oracle's chain. 2. Oracle receives new operation. -3. Oracle verifies operation and if it is correct submits `MsgVote` transaction with `YES` vote. Otherwise, oracle submits `MsgVote` transaction with `NO` vote. -4. After operation votes reaches `Quorum` (defined in `Rarimocore` module) `rarimocore` calculates the voting power and vote results. To become `APPROVED` there should be at least `Threshold` (defined in `Gov` module) percentage positive votes. - Otherwise, operation becomes `NOT_APPROVED`. +3. Oracle verifies operation and if it is correct submits `MsgVote` transaction with `YES` vote. Otherwise, oracle + submits `MsgVote` transaction with `NO` vote. +4. After operation votes reaches `Quorum` (defined in `Rarimocore` module) `rarimocore` calculates the voting power and + vote results. To become `APPROVED` there should be at least `Threshold` (defined in `Gov` module) percentage positive + votes. + Otherwise, operation becomes `NOT_APPROVED`. diff --git a/x/bridge/README.md b/x/bridge/README.md index 4f86bf62..760265b3 100644 --- a/x/bridge/README.md +++ b/x/bridge/README.md @@ -49,9 +49,7 @@ message Params { } ``` -
-Example - +Example: ```json { "params": { @@ -60,19 +58,18 @@ message Params { } ``` -
- ### Hash **Hash** - stores the hash of withdrawal operation to prevent double-spending. Definition: - ```protobuf - message Hash { - // hex-encoded - string index = 1; - } - ``` + +```protobuf +message Hash { + // hex-encoded + string index = 1; +} +``` ---- @@ -81,31 +78,33 @@ Definition: ### DepositNative **DepositNative** - burns user's tokens and creates transfer operation in ```rarimocore``` module (will be already approved). - ```protobuf - message MsgDepositNative { - string creator = 1; - // Random 32 bytes slice encoded to the hex string - string seed = 2; - // Information about deposit - string receiver = 3; - cosmos.base.v1beta1.Coin amount = 4; - string bundleData = 5;// hex-encoded - string bundleSalt = 6;// hex-encoded - // Information about target chain - rarimo.rarimocore.tokenmanager.OnChainItemIndex to = 7; - } - ``` + +```protobuf +message MsgDepositNative { + string creator = 1; + // Random 32 bytes slice encoded to the hex string + string seed = 2; + // Information about deposit + string receiver = 3; + cosmos.base.v1beta1.Coin amount = 4; + string bundleData = 5;// hex-encoded + string bundleSalt = 6;// hex-encoded + // Information about target chain + rarimo.rarimocore.tokenmanager.OnChainItemIndex to = 7; +} +``` ### WithdrawNative **WithdrawNative** - checks that operation in ```rarimocore``` is signed and valid and mints tokens to the receiver account. Operation hash (origin) will be stored in modules hash list. - ```protobuf - message MsgWithdrawNative { - string creator = 1; - // Evidence information - string origin = 2; + +```protobuf +message MsgWithdrawNative { + string creator = 1; + // Evidence information + string origin = 2; } - ``` +``` ---- \ No newline at end of file diff --git a/x/identity/README.md b/x/identity/README.md index dee116c5..daac4b6e 100644 --- a/x/identity/README.md +++ b/x/identity/README.md @@ -18,6 +18,7 @@ Collected events' information is recoded to the dynamic Merkle tree (based on tr The proof of concept for dynamic merkle tree is here: "". To collect events `identity` module uses `evm` module hooks by defining the following method: + ```go func (k Keeper) PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *ethtypes.Receipt) error ``` @@ -25,11 +26,13 @@ func (k Keeper) PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *eth It receives all emitted transaction logs in EVM module and filters them to process only `StateTransited` events. After all state updates in the module `EndBlock` method the `IDENTITY_AGGREGATED_TRANSFER` operation -will be created with current GIST and States root hash information. Also, the in all changed states `lastUpdateOperationIndex` will be updated. +will be created with current GIST and States root hash information. Also, the in all changed +states `lastUpdateOperationIndex` will be updated. ### Architecture The basic methods of dynamic merkle to work with is defined in `x/identity/keeper/treap.go`: + ```go func (t Treap) Split(ctx sdk.Context, root, key string) (string, string) @@ -48,7 +51,8 @@ Node index is based on corresponding `StateInfo` object hash (use `CalculateHash Also, every `Node` contains additional hash field that stores the `HASH(self,HASH(left,right))`. -Please refer to the corresponding `hash(a, b string) string` and `updateNode(ctx sdk.Context, node *types.Node)` to get more context about how we're constructing merkle tree. +Please refer to the corresponding `hash(a, b string) string` and `updateNode(ctx sdk.Context, node *types.Node)` to get +more context about how we're constructing merkle tree. In the `x/identity/keeper/keeper.go` file we are defining the main entrypoints to interact with: @@ -62,7 +66,7 @@ In the `x/identity/keeper/keeper.go` file we are defining the main entrypoints t ```go func (k Keeper) Path(ctx sdk.Context, id string) []string ``` - + ---- ## State @@ -70,86 +74,86 @@ In the `x/identity/keeper/keeper.go` file we are defining the main entrypoints t ### Params Definition: - ```protobuf - message Params { - // Linear congruential generator params - // https://en.wikipedia.org/wiki/Linear_congruential_generator - uint64 lcgA = 1; - uint64 lcgB = 2; - uint64 lcgMod = 3; - uint64 lcgValue = 4; - // Address of identity state smart contract in rarimo chain - string identityContractAddress = 5; - string chainName = 6; - string GISTHash = 7; - uint64 GISTUpdatedTimestamp = 8; - string treapRootKey = 9; - repeated string statesWaitingForSign = 10; - } - ``` -
- Example - - ```json - { - "params": { - "lcgA": "1664525", - "lcgB": "1013904223", - "lcgMod": "4294967296", - "lcgValue": "2900471886", - "identityContractAddress": "0x753a8678c85d5fb70A97CFaE37c84CE2fD67EDE8", - "chainName": "Rarimo", - "GISTHash": "0x049f1325d5227edcefbca1dc4dc1b76dd981e54c874ec49ba964443086b49950", - "GISTUpdatedTimestamp": "1691866982", - "treapRootKey": "0x36141b81b879c28068b3df0bbe9fad19c202b3ef7a140046e018c4153a8ce4c1", - "statesWaitingForSign": [] - } - } - ``` -
+```protobuf +message Params { + // Linear congruential generator params + // https://en.wikipedia.org/wiki/Linear_congruential_generator + uint64 lcgA = 1; + uint64 lcgB = 2; + uint64 lcgMod = 3; + uint64 lcgValue = 4; + // Address of identity state smart contract in rarimo chain + string identityContractAddress = 5; + string chainName = 6; + string GISTHash = 7; + uint64 GISTUpdatedTimestamp = 8; + string treapRootKey = 9; + repeated string statesWaitingForSign = 10; +} +``` + +Example: + +```json +{ + "params": { + "lcgA": "1664525", + "lcgB": "1013904223", + "lcgMod": "4294967296", + "lcgValue": "2900471886", + "identityContractAddress": "0x753a8678c85d5fb70A97CFaE37c84CE2fD67EDE8", + "chainName": "Rarimo", + "GISTHash": "0x049f1325d5227edcefbca1dc4dc1b76dd981e54c874ec49ba964443086b49950", + "GISTUpdatedTimestamp": "1691866982", + "treapRootKey": "0x36141b81b879c28068b3df0bbe9fad19c202b3ef7a140046e018c4153a8ce4c1", + "statesWaitingForSign": [] + } +} +``` ### Node Definition: - ```protobuf - message Node { - // Node key (identity state hash) - string key = 1; - // Node priority (should be random) - uint64 priority = 2; - // Node left son key - string left = 4; - // Node right son key - string right = 5; - // Merkle hash. H = Hash(Hash(left_key|right_key)|self_key) - string hash = 6; - // Hash(left_key|right_key) - string childrenHash = 7; + +```protobuf +message Node { + // Node key (identity state hash) + string key = 1; + // Node priority (should be random) + uint64 priority = 2; + // Node left son key + string left = 4; + // Node right son key + string right = 5; + // Merkle hash. H = Hash(Hash(left_key|right_key)|self_key) + string hash = 6; + // Hash(left_key|right_key) + string childrenHash = 7; +} +``` + +Example: + +```json +{ + "node": { + "key": "0x36141b81b879c28068b3df0bbe9fad19c202b3ef7a140046e018c4153a8ce4c1", + "priority": "4267815944", + "left": "0x2d6a7c009097397071398f3b2a1855a5df9f6d9ce258846ba92de23aee0dfdf9", + "right": "0x371e7f58b71fea562aa728619fed387134051e19a3efe0dac2c09557852c5a5c", + "hash": "0x9cc3d207a5e341279f698cad512f517edb0e9d8df44181680f8d1d75b5573be2", + "childrenHash": "0xeb2c9ef79b7415a7d38bd1497550084f6bf3ba2f871771b5030c8084b9ff51c8" } - ``` +} +``` -
- Example - - ```json - { - "node": { - "key": "0x36141b81b879c28068b3df0bbe9fad19c202b3ef7a140046e018c4153a8ce4c1", - "priority": "4267815944", - "left": "0x2d6a7c009097397071398f3b2a1855a5df9f6d9ce258846ba92de23aee0dfdf9", - "right": "0x371e7f58b71fea562aa728619fed387134051e19a3efe0dac2c09557852c5a5c", - "hash": "0x9cc3d207a5e341279f698cad512f517edb0e9d8df44181680f8d1d75b5573be2", - "childrenHash": "0xeb2c9ef79b7415a7d38bd1497550084f6bf3ba2f871771b5030c8084b9ff51c8" - } - } - ``` -
### StateInfo Definition: - ```protobuf + +```protobuf message StateInfo { // State info index (issuer id) string index = 1; @@ -162,23 +166,22 @@ message StateInfo { // Index of last update/create operation (will not be used in state hash) string lastUpdateOperationIndex = 5; } - ``` +``` + +Example: + +```json +{ + "state": { + "index": "0x106d23bb7bedce6caadddf7480ade7f2b8e93fa304fc51cc4030a66de90001", + "hash": "0x22121ba37492dbb16203cd6dcdb446c4a5c56a4395b145b9403819bcf34141bf", + "createdAtTimestamp": "1691866982", + "createdAtBlock": "923813", + "lastUpdateOperationIndex": "0x2fd7af49f584db04cc8048fd09be7fccf01bd7efe6c93127c0dbae55e643d625" + } +} +``` -
- Example - - ```json - { - "state": { - "index": "0x106d23bb7bedce6caadddf7480ade7f2b8e93fa304fc51cc4030a66de90001", - "hash": "0x22121ba37492dbb16203cd6dcdb446c4a5c56a4395b145b9403819bcf34141bf", - "createdAtTimestamp": "1691866982", - "createdAtBlock": "923813", - "lastUpdateOperationIndex": "0x2fd7af49f584db04cc8048fd09be7fccf01bd7efe6c93127c0dbae55e643d625" - } - } - ``` -
---- @@ -188,11 +191,12 @@ message StateInfo { **SetIdentityContractAddress** - sets the Rarimo EVM StateV2 contract address. Can be called only once when the current address is 0x. - ```protobuf - message MsgSetIdentityContractAddress { - string creator = 1; - string address = 2; - } - ``` + +```protobuf +message MsgSetIdentityContractAddress { + string creator = 1; + string address = 2; +} +``` ---- \ No newline at end of file diff --git a/x/multisig/README.md b/x/multisig/README.md index 0430389e..543e7fc3 100644 --- a/x/multisig/README.md +++ b/x/multisig/README.md @@ -20,7 +20,8 @@ The main differences between implementations: - Decision policy will be stored in the group entity. - There will be only one decision policy – threshold decision policy. - No group member entity - the base account will be used instead. -- No group administrator – the group will be managed by itself. The group member has to send a multi-signed message to remove or add a new member. The same flow works for other operations unrelated to the group management. +- No group administrator – the group will be managed by itself. The group member has to send a multi-signed message to + remove or add a new member. The same flow works for other operations unrelated to the group management. - The group member can’t leave the group at will. - If the message is valid – it will be executed automatically by the module, instead of manually execution. @@ -41,29 +42,27 @@ The multi-signature feature works in the following way: ### Params Definition: - ```protobuf - message Params { - option (gogoproto.goproto_stringer) = false; - uint64 groupSequence = 1; - uint64 proposalSequence = 2; - uint64 prunePeriod = 3; - uint64 votingPeriod = 4; - } - ``` - -
- Example - - ```json - { - "groupSequence": 0, - "proposalSequence": 0, - "prunePeriod": 240, - "votingPeriod": 120 - } - ``` -
+```protobuf +message Params { + option (gogoproto.goproto_stringer) = false; + uint64 groupSequence = 1; + uint64 proposalSequence = 2; + uint64 prunePeriod = 3; + uint64 votingPeriod = 4; +} +``` + +Example: + +```json +{ + "groupSequence": 0, + "proposalSequence": 0, + "prunePeriod": 240, + "votingPeriod": 120 +} +``` ### Group @@ -73,148 +72,154 @@ The module uses the group sequence parameter to generate a group ID for producin The group sequence is an integer stored in the module's parameters and increments during new group creation. Definition: - ```protobuf - message Group { - string account = 1; - repeated string members = 2; - uint64 threshold = 3; - } - ``` - -
- Example - - ```json - { - "account": "rarimo....", - "members": ["rarimo...", "rarimo..."], - "threshold": 1, - } - ``` -
+```protobuf +message Group { + string account = 1; + repeated string members = 2; + uint64 threshold = 3; +} +``` + +Example: + +```json +{ + "account": "rarimo....", + "members": [ + "rarimo...", + "rarimo..." + ], + "threshold": 1 +} +``` ### Proposal **Proposal** - proposal to execute some operation that should be signed by group. Definition: - ```protobuf - enum VoteOption { - YES = 0; - NO = 1; - } - - // ProposalStatus defines proposal statuses. - enum ProposalStatus { - // Initial status of a proposal when submitted. - SUBMITTED = 0; - // Status of a proposal when it passes the group's decision policy. - ACCEPTED = 1; - // Status of a proposal when it is rejected by the group's decision policy. - REJECTED = 2; - // Status of a proposal when it is successfully executed by the module. - EXECUTED = 3; - // Status of a proposal when execution is failed. - FAILED = 4; - } - - // Proposal defines a group proposal. Any member of a group can submit a proposal - // for a module to decide upon. - // A proposal consists of a set of `sdk.Msg`s that will be executed if the proposal - // passes as well. - message Proposal { - // Account address of the proposer. - string proposer = 1; - // Unique id of the proposal. - uint64 id = 2; - // Account address of the group. - string group = 3; - // Block height when the proposal was submitted. - uint64 submitBlock = 5; - // Status represents the high level position in the life cycle of the proposal. Initial value is Submitted. - ProposalStatus status = 8; - // Contains the sums of all votes for this proposal for each vote option. - // It is empty at submission, and only populated after tallying, at voting end block. - TallyResult finalTallyResult = 9; - // Block height before which voting must be done. - uint64 votingEndBlock = 10; - // List of `sdk.Msg`s that will be executed if the proposal passes. - repeated google.protobuf.Any messages = 12; - } - - // TallyResult represents the sum of votes for each vote option. - message TallyResult { - // Sum of yes votes. - uint64 yesCount = 1; - // Sum of no votes. - uint64 noCount = 3; - } - - // Vote represents a vote for a proposal. - message Vote { - // Unique ID of the proposal. - uint64 proposalId = 1; - // Voter is the account address of the voter. - string voter = 2; - // Option is the voter's choice on the proposal. - VoteOption option = 3; - // Block height when the vote was submitted. - uint64 submitBlock = 5; - } - ``` + +```protobuf +enum VoteOption { + YES = 0; + NO = 1; +} + +// ProposalStatus defines proposal statuses. +enum ProposalStatus { + // Initial status of a proposal when submitted. + SUBMITTED = 0; + // Status of a proposal when it passes the group's decision policy. + ACCEPTED = 1; + // Status of a proposal when it is rejected by the group's decision policy. + REJECTED = 2; + // Status of a proposal when it is successfully executed by the module. + EXECUTED = 3; + // Status of a proposal when execution is failed. + FAILED = 4; +} + +// Proposal defines a group proposal. Any member of a group can submit a proposal +// for a module to decide upon. +// A proposal consists of a set of `sdk.Msg`s that will be executed if the proposal +// passes as well. +message Proposal { + // Account address of the proposer. + string proposer = 1; + // Unique id of the proposal. + uint64 id = 2; + // Account address of the group. + string group = 3; + // Block height when the proposal was submitted. + uint64 submitBlock = 5; + // Status represents the high level position in the life cycle of the proposal. Initial value is Submitted. + ProposalStatus status = 8; + // Contains the sums of all votes for this proposal for each vote option. + // It is empty at submission, and only populated after tallying, at voting end block. + TallyResult finalTallyResult = 9; + // Block height before which voting must be done. + uint64 votingEndBlock = 10; + // List of `sdk.Msg`s that will be executed if the proposal passes. + repeated google.protobuf.Any messages = 12; +} + +// TallyResult represents the sum of votes for each vote option. +message TallyResult { + // Sum of yes votes. + uint64 yesCount = 1; + // Sum of no votes. + uint64 noCount = 3; +} + +// Vote represents a vote for a proposal. +message Vote { + // Unique ID of the proposal. + uint64 proposalId = 1; + // Voter is the account address of the voter. + string voter = 2; + // Option is the voter's choice on the proposal. + VoteOption option = 3; + // Block height when the vote was submitted. + uint64 submitBlock = 5; +} +``` ---- ## Transactions - ## RPC ### SubmitProposal **SubmitProposal** - creates proposal to execute some set of messages signed by group account. - ```protobuf - message MsgSubmitProposal { - string creator = 1; - string group = 2; - repeated google.protobuf.Any messages = 3; - } - ``` + +```protobuf +message MsgSubmitProposal { + string creator = 1; + string group = 2; + repeated google.protobuf.Any messages = 3; +} +``` ### Vote **Vote** - vote for proposal. - ```protobuf - message MsgVote { - string creator = 1; - uint64 proposalId = 2; - VoteOption option = 3; - } - ``` + +```protobuf +message MsgVote { + string creator = 1; + uint64 proposalId = 2; + VoteOption option = 3; +} +``` ### CreateGroup **CreateGroup** - creating of the new group. - ```protobuf - message MsgCreateGroup { - string creator = 1; - repeated string members = 2; - uint64 threshold = 3; - } - ``` + +```protobuf +message MsgCreateGroup { + string creator = 1; + repeated string members = 2; + uint64 threshold = 3; +} +``` ### ChangeGroup **ChangeGroup** - changing group parameters or set of participants. - The signer of that message should be a group account, so that message can be executed only from that module using multisig flow. - ```protobuf - message MsgChangeGroup { - string creator = 1; - string group = 2; - repeated string members = 3; - uint64 threshold = 4; - } - ``` +The signer of that message should be a group account, so that message can be executed only from that module using +multisig flow. + +```protobuf +message MsgChangeGroup { + string creator = 1; + string group = 2; + repeated string members = 3; + uint64 threshold = 4; +} +``` ---- \ No newline at end of file diff --git a/x/oraclemanager/README.md b/x/oraclemanager/README.md index 40b5a10d..091eddaa 100644 --- a/x/oraclemanager/README.md +++ b/x/oraclemanager/README.md @@ -7,7 +7,8 @@ title: x/oraclemanager ## Abstract -The `oraclemanager` cosmos module contains logic for managing distibuted public oracles that supports our bridge by delivering +The `oraclemanager` cosmos module contains logic for managing distibuted public oracles that supports our bridge by +delivering information about transfers. ---- @@ -18,6 +19,7 @@ In the `oraclemanager` the oracles will be organized into the groups for every s Of course, we imply that the same account can be the oracle in several groups. Also, oracle will have the following related data: + - Status: Slashed, Freezed, Jailed, Active and Inactive - Stake amount - Missed count - the count of missed vote @@ -26,42 +28,52 @@ Also, oracle will have the following related data: - Voted operations - Created operations - The following list full describes system rules and architecture: 1. There will be configured the following parameters: - min_oracle_stake - minimum amount of RMO tokens to become an oracle. - - check_op_delta - the amount of blocks after operation voting finish to perform slashing of malicious oracles (described below in 6). - - max_violation_count - the amount of violation that an oracle can reach before it will be freezed (described below in 6). + - check_op_delta - the amount of blocks after operation voting finish to perform slashing of malicious oracles ( + described below in 6). + - max_violation_count - the amount of violation that an oracle can reach before it will be freezed (described below + in 6). - max_missed_count - the amount of violation that oracle can reach before it will be jailed (described below in 6). - slashed_freeze_blocks - the amount of blocks until the oracle stake will be burned (described below in 7). - min_oracles_count - minimal count of oracles to verify operations on the certain chain (global for all chains). -2. Oracles will be separated to the lists of accounts that support certain chains (chains defined in params of `tokenmanager` module). +2. Oracles will be separated to the lists of accounts that support certain chains (chains defined in params + of `tokenmanager` module). So every chain will have their own list of oracles that observes its state, submits and votes for operations. 3. To become an oracle for a certain chain account (that will be used by oracle service) should stake at least min_oracle_stake tokens through the `oraclemanager` by submitting the `Stake` transaction. To use the same oracle account for several chains, the account owner should stake tokens for every chain separately. -4. It is possible to unstake tokens and stop taking part in voting and creating new operations if the oracle owner wants. +4. It is possible to unstake tokens and stop taking part in voting and creating new operations if the oracle owner + wants. Through the `oraclemanager` oracle owner can submit `Unstake` transaction and return the staked coins. After that oracle will not be able to create operations and vote for the created one. -5. After staking, if the chain has at least min_oracles_count oracles, every oracle can create and vote for new operations, - using the proxy method in `oraclemanager` (`CreateTransferOperation` and `Vote` that will trigger logic in the `rarimocore` module). +5. After staking, if the chain has at least min_oracles_count oracles, every oracle can create and vote for new + operations, + using the proxy method in `oraclemanager` (`CreateTransferOperation` and `Vote` that will trigger logic in + the `rarimocore` module). Oracle voting power will be calculated depending on the oracle account staked tokens amount. 6. The `oraclemanager` will control votes and new operations to perform slashing of malicious oracles. - For every operation that has Approved or NotApproved status after check_op_delta blocks `oraclemanager` EndBlock method will iterate over all votes and: + For every operation that has Approved or NotApproved status after check_op_delta blocks `oraclemanager` EndBlock + method will iterate over all votes and: - Increase missed counter for oracles that haven't submitted their Vote. - Increase violations counter for oracles that have submitted a `Vote` with answer `NO` for `Approved` operation. - - Increase violations counter for oracles that have submitted a `Vote` with answer `YES` for `NotApproved` operation. + - Increase violations counter for oracles that have submitted a `Vote` with answer `YES` for `NotApproved` + operation. - Increase violations counter for oracles that have created a `NotApproved` operation. Also, EndBlock method will iterate over all oracles and: -- if oracle reaches max_violation_count its status will be set as `Freezed`. Freezed oracle accounts will not be able to create operations and vote for the created one. -- if oracle reaches max_missed_count its status will be set as `Jailed`. Jailed oracle accounts will not be able to create operations and vote for the created one. + +- if oracle reaches max_violation_count its status will be set as `Freezed`. Freezed oracle accounts will not be able to + create operations and vote for the created one. +- if oracle reaches max_missed_count its status will be set as `Jailed`. Jailed oracle accounts will not be able to + create operations and vote for the created one. 7. After freezing the oracle owner can create a proposal to unfreeze his account (`CreateOracleUnfreezeProposal` transaction on `oraclemanager` module) and if it becomes accepted the oracle account @@ -79,86 +91,84 @@ Also, EndBlock method will iterate over all oracles and: ### Params Definition: - ```protobuf - message Params { - string minOracleStake = 1; - uint64 checkOperationDelta = 2; - uint64 maxViolationsCount = 3; - uint64 maxMissedCount = 4; - uint64 slashedFreezeBlocks = 5; - uint64 minOraclesCount = 6; - string stakeDenom = 7; - string voteQuorum = 8; - string voteThreshold = 9; - } - ``` - -
- Example - - ```json - { - "minOracleStake": "1000000", - "checkOperationDelta": "10", - "maxViolationsCount": "10", - "maxMissedCount": "10", - "slashedFreezeBlocks": "240", - "minOraclesCount": "1", - "stakeDenom": "stake", - "voteQuorum": "0.900000000000000000", - "voteThreshold": "0.667000000000000000" - } - ``` -
+ +```protobuf +message Params { + string minOracleStake = 1; + uint64 checkOperationDelta = 2; + uint64 maxViolationsCount = 3; + uint64 maxMissedCount = 4; + uint64 slashedFreezeBlocks = 5; + uint64 minOraclesCount = 6; + string stakeDenom = 7; + string voteQuorum = 8; + string voteThreshold = 9; +} +``` + +Example: + +```json +{ + "minOracleStake": "1000000", + "checkOperationDelta": "10", + "maxViolationsCount": "10", + "maxMissedCount": "10", + "slashedFreezeBlocks": "240", + "minOraclesCount": "1", + "stakeDenom": "stake", + "voteQuorum": "0.900000000000000000", + "voteThreshold": "0.667000000000000000" +} +``` ### Oracle Definition: - ```protobuf - enum OracleStatus { - Inactive = 0; - Active = 1; - Jailed = 2; - Freezed = 3; - Slashed = 4; - } - - message OracleIndex { - string chain = 1; - string account = 2; - } - - message Oracle { - OracleIndex index = 1; - OracleStatus status = 2; - string stake = 3; - uint64 missedCount = 4; - uint64 violationsCount = 5; - uint64 freezeEndBlock = 6; - uint64 votesCount = 7; - uint64 createOperationsCount = 8; - } - ``` - -
- Example - - ```json - { - "index": { - "chain": "Solana", - "account": "rarimo1g9p4ejp9p877j9vdnuyqtgqm4lhm4f6j7uaztx" - }, - "status": "Active", - "stake": "1000000", - "missedCount": "0", - "violationsCount": "0", - "freezeEndBlock": "0", - "votesCount": "22", - "createOperationsCount": "22" - } - ``` -
+ +```protobuf +enum OracleStatus { + Inactive = 0; + Active = 1; + Jailed = 2; + Freezed = 3; + Slashed = 4; +} + +message OracleIndex { + string chain = 1; + string account = 2; +} + +message Oracle { + OracleIndex index = 1; + OracleStatus status = 2; + string stake = 3; + uint64 missedCount = 4; + uint64 violationsCount = 5; + uint64 freezeEndBlock = 6; + uint64 votesCount = 7; + uint64 createOperationsCount = 8; +} +``` + +Example: + +```json +{ + "index": { + "chain": "Solana", + "account": "rarimo1g9p4ejp9p877j9vdnuyqtgqm4lhm4f6j7uaztx" + }, + "status": "Active", + "stake": "1000000", + "missedCount": "0", + "violationsCount": "0", + "freezeEndBlock": "0", + "votesCount": "22", + "createOperationsCount": "22" +} +``` ---- @@ -167,32 +177,35 @@ Definition: ### CreateTransferOperation **CreateTransferOperation** - crates Operation with type `TRANSFER` and `INITIALIZED` status. -Metadata should be provided in case of first NFT transfer. Tx, EventId, Sender can be specified in native for source chain format. +Metadata should be provided in case of first NFT transfer. Tx, EventId, Sender can be specified in native for source +chain format. Other data should be formatted into hex with `0x` prefix. - ```protobuf - message MsgCreateTransferOp { - string creator = 1; - // Information to identify transfer - string tx = 2; - string eventId = 3; - string sender = 4; - // Information about deposit - string receiver = 5; - string amount = 6; - string bundleData = 7;// hex-encoded - string bundleSalt = 8;// hex-encoded - // Information about current and target chains - rarimo.rarimocore.tokenmanager.OnChainItemIndex from = 9; - rarimo.rarimocore.tokenmanager.OnChainItemIndex to = 10; - rarimo.rarimocore.tokenmanager.ItemMetadata meta = 11; // Optional (if item currently does not exists) - } - ``` + +```protobuf +message MsgCreateTransferOp { + string creator = 1; + // Information to identify transfer + string tx = 2; + string eventId = 3; + string sender = 4; + // Information about deposit + string receiver = 5; + string amount = 6; + string bundleData = 7;// hex-encoded + string bundleSalt = 8;// hex-encoded + // Information about current and target chains + rarimo.rarimocore.tokenmanager.OnChainItemIndex from = 9; + rarimo.rarimocore.tokenmanager.OnChainItemIndex to = 10; + rarimo.rarimocore.tokenmanager.ItemMetadata meta = 11; // Optional (if item currently does not exists) +} +``` ### CreateIdentityDefaultTransferOperation -**CreateIdentityDefaultTransferOperation** - crates Operation with type `IDENTITY_DEFAULT_TRANSFER` and `INITIALIZED` status. +**CreateIdentityDefaultTransferOperation** - crates Operation with type `IDENTITY_DEFAULT_TRANSFER` and `INITIALIZED` +status. - ```protobuf +```protobuf message MsgCreateIdentityDefaultTransferOp { string creator = 1; // Hex 0x @@ -217,47 +230,52 @@ message MsgCreateIdentityDefaultTransferOp { string replacedStateHash = 17; string replacedGISTtHash = 18; } - ``` +``` ### Vote **Vote** - vote for operation. Vote power will be equal to the voter staked balance. After total voting power reaches required quorum operation status changes to `APPROVED` or `NOT_APPROVED`. - ```protobuf - message MsgVote{ - rarimo.rarimocore.oraclemanager.OracleIndex index = 1; - string operation = 2; - rarimo.rarimocore.rarimocore.VoteType vote = 3; - } - ``` + +```protobuf +message MsgVote{ + rarimo.rarimocore.oraclemanager.OracleIndex index = 1; + string operation = 2; + rarimo.rarimocore.rarimocore.VoteType vote = 3; +} +``` ### Stake -**Stake** - stake tokens to become active oracle. Also it is possible to re-activate unstaked oracle and stake more tokens use that message. - ```protobuf - message MsgStake { - rarimo.rarimocore.oraclemanager.OracleIndex index = 1; - string amount = 2; - } - ``` +**Stake** - stake tokens to become active oracle. Also it is possible to re-activate unstaked oracle and stake more +tokens use that message. + +```protobuf +message MsgStake { + rarimo.rarimocore.oraclemanager.OracleIndex index = 1; + string amount = 2; +} +``` ### Unstake **Unstake** - unstake all tokens and stop to be an active oracle - ```protobuf - message MsgUnstake { - rarimo.rarimocore.oraclemanager.OracleIndex index = 1; - } - ``` + +```protobuf +message MsgUnstake { + rarimo.rarimocore.oraclemanager.OracleIndex index = 1; +} +``` ### Unjail **Unjail** - unjail `Jailed` oracle - ```protobuf - message MsgUnjail{ - rarimo.rarimocore.oraclemanager.OracleIndex index = 1; - } - ``` + +```protobuf +message MsgUnjail{ + rarimo.rarimocore.oraclemanager.OracleIndex index = 1; +} +``` ---- @@ -266,23 +284,25 @@ required quorum operation status changes to `APPROVED` or `NOT_APPROVED`. ### OracleUnfreezeProposal **OracleUnfreezeProposal** - unfreeze slashed oracle proposal. - ```protobuf - message OracleUnfreezeProposal { - string title = 1; - string description = 2; - rarimo.rarimocore.oraclemanager.OracleIndex index = 3; - } - ``` + +```protobuf +message OracleUnfreezeProposal { + string title = 1; + string description = 2; + rarimo.rarimocore.oraclemanager.OracleIndex index = 3; +} +``` ### ChangeParamsProposal **ChangeParamsProposal** - changing of module params - ```protobuf + +```protobuf message ChangeParamsProposal { string title = 1; string description = 2; Params params = 3 [(gogoproto.nullable) = false]; } - ``` +``` ---- diff --git a/x/rarimocore/README.md b/x/rarimocore/README.md index 586a0a2c..feb6992b 100644 --- a/x/rarimocore/README.md +++ b/x/rarimocore/README.md @@ -7,15 +7,18 @@ title: x/rarimocore ## Abstract -The `rarimocore` cosmos module contains logic for all cross-chain operations, its votes, confirmations and signers management. +The `rarimocore` cosmos module contains logic for all cross-chain operations, its votes, confirmations and signers +management. -You can explore the messages and RPC server definition of the `rarimocore` module in the `rarimo-core/proto/rarimocore` package. +You can explore the messages and RPC server definition of the `rarimocore` module in the `rarimo-core/proto/rarimocore` +package. ---- ## Concepts The main flow consists of three steps: + 1. Any of Oracles creates the operation on the core 2. Oracles vote for the operation correctness, and after that operation defined as approved/not approved. 3. Signature producers sign the operation @@ -25,14 +28,16 @@ Also, the shorter flow can exist: when operation is created by governance or mod In such case operation can be already approved. ### Operation indexes + - Transfer operation: `HASH(tx, event, chain)` - Change parties: `HASH(new set, new key, signature)` - Fee contract management: `HASH(block height, chain, fee token contract, fee amount)` - Contract upgrade: `HASH(block, content [depends on chain])` -- Identity transfer: `HASH(source contract, id, state hash, state timestamps, GIST hash, GIST timestamps, replaced state hash)` +- Identity + transfer: `HASH(source contract, id, state hash, state timestamps, GIST hash, GIST timestamps, replaced state hash)` - Identity aggregated transfer: `HASH(GIST, timestamp, states root, contract address, chain)` -To add new operation check the following [manual](../../docs/common/core/001-adding-operation.md). +To add new operation check the following [manual](../../docs/common/core/001-adding-operation.md). ---- @@ -44,261 +49,262 @@ To add new operation check the following [manual](../../docs/common/core/001-add Note that public keys (parties and global) should be in uncompressed form without leading 0x04 (64 bytes format). Definition: - ```protobuf - enum PartyStatus { - Active = 0; - Frozen = 1; - Slashed = 2; - Inactive = 3; - } - - message Party { - // PublicKey in hex format - string pubKey = 1; - // Server address connect to - string address = 2; - // Rarimo core account - string account = 3; - PartyStatus status = 4; - uint64 violationsCount = 5; - uint64 freezeEndBlock = 6; - string delegator = 7; - // service information used in initial setup - string committedGlobalPublicKey = 8; - } - - // Params defines the parameters for the module. - message Params { - string keyECDSA = 1; - uint64 threshold = 2; - repeated Party parties = 3; - bool isUpdateRequired = 5; - string lastSignature = 6; - string stakeAmount = 7; - string stakeDenom = 8; - uint64 maxViolationsCount = 9; - uint64 freezeBlocksPeriod = 10; - } - ``` - -
- Example - - ```json + +```protobuf +enum PartyStatus { + Active = 0; + Frozen = 1; + Slashed = 2; + Inactive = 3; +} + +message Party { + // PublicKey in hex format + string pubKey = 1; + // Server address connect to + string address = 2; + // Rarimo core account + string account = 3; + PartyStatus status = 4; + uint64 violationsCount = 5; + uint64 freezeEndBlock = 6; + string delegator = 7; + // service information used in initial setup + string committedGlobalPublicKey = 8; +} + +// Params defines the parameters for the module. +message Params { + string keyECDSA = 1; + uint64 threshold = 2; + repeated Party parties = 3; + bool isUpdateRequired = 5; + string lastSignature = 6; + string stakeAmount = 7; + string stakeDenom = 8; + uint64 maxViolationsCount = 9; + uint64 freezeBlocksPeriod = 10; +} +``` + +Example: + +```json +{ + "keyECDSA": "0x928d7a512b18fcbfd51c1b050e2d498f962e2c244bb7495e253731cddcfd164ef32c213e3b4fd4185d1de33dd596061473392aa73b532906e553e543801c0f3a", + "threshold": "2", + "parties": [ + { + "pubKey": "0xb7e8d31ac044cae1ae0ad6f440c25bdf313828b3dd048bc290a8f839c41dd62b50f50693ac4c36ffea12b43e4b59c694a69f2e25a3a4b3135a444df6b5dd6423", + "address": "tss-1:9000", + "account": "rarimo1l2vdscjfm289mdxnlnvfwscku4w2l3ljt97kdq", + "status": "ACTIVE", + "violationsCount": 0, + "freezeEndBlock": 0, + "delegator": "", + "committedGlobalPublicKey": "" + }, { - "keyECDSA": "0x928d7a512b18fcbfd51c1b050e2d498f962e2c244bb7495e253731cddcfd164ef32c213e3b4fd4185d1de33dd596061473392aa73b532906e553e543801c0f3a", - "threshold": "2", - "parties": [ - { - "pubKey": "0xb7e8d31ac044cae1ae0ad6f440c25bdf313828b3dd048bc290a8f839c41dd62b50f50693ac4c36ffea12b43e4b59c694a69f2e25a3a4b3135a444df6b5dd6423", - "address": "tss-1:9000", - "account": "rarimo1l2vdscjfm289mdxnlnvfwscku4w2l3ljt97kdq", - "status": "ACTIVE", - "violationsCount": 0, - "freezeEndBlock": 0, - "delegator": "", - "committedGlobalPublicKey": "", - }, - { - "pubKey": "0x4b5139cecb56617c32133885bc7b93da9900e3bf6e5e6d7ce012780f668f1379f5f2fe1a9b40a36421104b6873c53f353aaaa1a696c19099022c290cbc6c8b89", - "address": "tss-2:9000", - "account": "rarimo1cqtx4qdtdemula69hpv9ksvg769u0tujgqqyhc", - "status": "ACTIVE", - "violationsCount": 0, - "freezeEndBlock": 0, - "delegator": "", - "committedGlobalPublicKey": "", - }, - { - "pubKey": "0xc674cc7a7ec0ceacc7723e7a807c09ffe44b84bbb45de1c586dbc3fcc3724c71bbd9dba4fcf977772128f9e8c4b2f6b345f3d8ad944e853dc352a6eb343d1775", - "address": "tss-3:9000", - "account": "rarimo13xrlm9cg8ugp327qr0a4k2r9fvkqrsvtm9pcsn", - "status": "ACTIVE", - "violationsCount": 0, - "freezeEndBlock": 0, - "delegator": "", - "committedGlobalPublicKey": "", - } - ], - "isUpdateRequired": false, - "lastSignature": "0x00", - "stakeAmount": "1000000", - "stakeDenom": "stake", - "maxViolationsCount": 10, - "freezeBlocksPeriod": 100, + "pubKey": "0x4b5139cecb56617c32133885bc7b93da9900e3bf6e5e6d7ce012780f668f1379f5f2fe1a9b40a36421104b6873c53f353aaaa1a696c19099022c290cbc6c8b89", + "address": "tss-2:9000", + "account": "rarimo1cqtx4qdtdemula69hpv9ksvg769u0tujgqqyhc", + "status": "ACTIVE", + "violationsCount": 0, + "freezeEndBlock": 0, + "delegator": "", + "committedGlobalPublicKey": "" + }, + { + "pubKey": "0xc674cc7a7ec0ceacc7723e7a807c09ffe44b84bbb45de1c586dbc3fcc3724c71bbd9dba4fcf977772128f9e8c4b2f6b345f3d8ad944e853dc352a6eb343d1775", + "address": "tss-3:9000", + "account": "rarimo13xrlm9cg8ugp327qr0a4k2r9fvkqrsvtm9pcsn", + "status": "ACTIVE", + "violationsCount": 0, + "freezeEndBlock": 0, + "delegator": "", + "committedGlobalPublicKey": "" } - ``` -
+ ], + "isUpdateRequired": false, + "lastSignature": "0x00", + "stakeAmount": "1000000", + "stakeDenom": "stake", + "maxViolationsCount": 10, + "freezeBlocksPeriod": 100 +} +``` ### Operation **Operation** - defines generic operation to be signed by core. Definition: - ```protobuf - enum OpType { - TRANSFER = 0; - CHANGE_PARTIES = 1; - FEE_TOKEN_MANAGEMENT = 2; - CONTRACT_UPGRADE = 3; - IDENTITY_DEFAULT_TRANSFER = 4; - IDENTITY_AGGREGATED_TRANSFER = 5; - } - - enum OpStatus { - INITIALIZED = 0; - APPROVED = 1; - NOT_APPROVED = 2; - SIGNED = 3; - } - - message Operation { - // Should be in a hex format 0x... - string index = 1; - opType operationType = 2; - // Corresponding to type details - google.protobuf.Any details = 3; - opStatus status = 4; - string creator = 5; - uint64 timestamp = 6; - } - ``` - -
- Example - - ```json - { - "index": "0x683f666c05682cdbf8ad0d2bd988515deca0dc82296d4366debfbff738f7eacb", - "operationType": "TRANSFER", - "details": { - "@type": "/rarimo.rarimocore.rarimocore.Transfer", - "origin": "0x683f666c05682cdbf8ad0d2bd988515deca0dc82296d4366debfbff738f7eacb", - "tx": "e2YTbRzKSPXHkesQhSaANDEGyHHqBfyytEoWCeBjJ9Ugzzrh37kvpc5MDMNHAbwL17eAVQnrMc48EpD2RYx2GeL", - "eventId": "0", - "sender": "FCpFKSEboCUGg1Qs8NFwH2suMAHYWvFUUiVWk8cKwNqf", - "receiver": "0xd30a6d9589a4ad1845f4cfb6cdafa47e2d444fcc568cef04525f1d700f4e53aa", - "amount": "1000", - "bundleData": "", - "bundleSalt": "", - "from": { - "chain": "Solana", - "address": "", - "tokenID": "" - }, - "to": { - "chain": "Solana", - "address": "", - "tokenID": "" - }, - "meta": null - }, - "status": "SIGNED", - "creator": "rarimo1g9p4ejp9p877j9vdnuyqtgqm4lhm4f6j7uaztx", - "timestamp": "113310" - } - ``` -
+ +```protobuf +enum OpType { + TRANSFER = 0; + CHANGE_PARTIES = 1; + FEE_TOKEN_MANAGEMENT = 2; + CONTRACT_UPGRADE = 3; + IDENTITY_DEFAULT_TRANSFER = 4; + IDENTITY_AGGREGATED_TRANSFER = 5; +} + +enum OpStatus { + INITIALIZED = 0; + APPROVED = 1; + NOT_APPROVED = 2; + SIGNED = 3; +} + +message Operation { + // Should be in a hex format 0x... + string index = 1; + opType operationType = 2; + // Corresponding to type details + google.protobuf.Any details = 3; + opStatus status = 4; + string creator = 5; + uint64 timestamp = 6; +} +``` + +Example: + +```json +{ + "index": "0x683f666c05682cdbf8ad0d2bd988515deca0dc82296d4366debfbff738f7eacb", + "operationType": "TRANSFER", + "details": { + "@type": "/rarimo.rarimocore.rarimocore.Transfer", + "origin": "0x683f666c05682cdbf8ad0d2bd988515deca0dc82296d4366debfbff738f7eacb", + "tx": "e2YTbRzKSPXHkesQhSaANDEGyHHqBfyytEoWCeBjJ9Ugzzrh37kvpc5MDMNHAbwL17eAVQnrMc48EpD2RYx2GeL", + "eventId": "0", + "sender": "FCpFKSEboCUGg1Qs8NFwH2suMAHYWvFUUiVWk8cKwNqf", + "receiver": "0xd30a6d9589a4ad1845f4cfb6cdafa47e2d444fcc568cef04525f1d700f4e53aa", + "amount": "1000", + "bundleData": "", + "bundleSalt": "", + "from": { + "chain": "Solana", + "address": "", + "tokenID": "" + }, + "to": { + "chain": "Solana", + "address": "", + "tokenID": "" + }, + "meta": null + }, + "status": "SIGNED", + "creator": "rarimo1g9p4ejp9p877j9vdnuyqtgqm4lhm4f6j7uaztx", + "timestamp": "113310" +} +``` ### Confirmation **Confirmation** - defines tss signature for some set of operations. Definition: - ```protobuf - message Confirmation { - // hex-encoded - string root = 1; - // hex-encoded - repeated string indexes = 2; - // hex-encoded - string signatureECDSA = 3; - string creator = 4; - } - ``` - -
- Example - - ```json - { - "root": "0x17831935b02ca1784e920245c2ea4f6d5dd6298b1df4e3c870e5f6f45d2b0797", - "indexes": [ - "0x836638ffdc89588a635c24921f1b524d118e9e75c97d38b675620c4211493d7f" - ], - "signatureECDSA": "0x8bf642743d6ca2361d503c7accdfdd269ff043a070beb22904a5a9c4442c1aa20ae3252198d60dedf8316908408099022c16c1a79823ccd3c49cdab84e473b7a00", - "creator": "rarimo1yxzygxdk3eujpudr3ynux4gkg7r6ss6csqf9ew" - } - ``` -
+ +```protobuf +message Confirmation { + // hex-encoded + string root = 1; + // hex-encoded + repeated string indexes = 2; + // hex-encoded + string signatureECDSA = 3; + string creator = 4; +} +``` + +Example: + +```json +{ + "root": "0x17831935b02ca1784e920245c2ea4f6d5dd6298b1df4e3c870e5f6f45d2b0797", + "indexes": [ + "0x836638ffdc89588a635c24921f1b524d118e9e75c97d38b675620c4211493d7f" + ], + "signatureECDSA": "0x8bf642743d6ca2361d503c7accdfdd269ff043a070beb22904a5a9c4442c1aa20ae3252198d60dedf8316908408099022c16c1a79823ccd3c49cdab84e473b7a00", + "creator": "rarimo1yxzygxdk3eujpudr3ynux4gkg7r6ss6csqf9ew" +} +``` ### Vote **Vote** - defines validator votes for operation validity. Definition: - ```protobuf - enum VoteType { - YES = 0; - NO = 1; - } - - message VoteIndex { - string operation = 1; - string validator = 2; - } - - message Vote { - VoteIndex index = 1; - VoteType vote = 2; - } - ``` - -
- Example - - ```json - { - "index": { - "operation": "0x683f666c05682cdbf8ad0d2bd988515deca0dc82296d4366debfbff738f7eacb", - "validator": "rarimo1eqmyvqge5mu7cfv4gjy8y7smfxhq5r0ctljf0n" - }, - "vote": "YES" - } - ``` -
+ +```protobuf +enum VoteType { + YES = 0; + NO = 1; +} + +message VoteIndex { + string operation = 1; + string validator = 2; +} + +message Vote { + VoteIndex index = 1; + VoteType vote = 2; +} +``` + +Example: + +```json +{ + "index": { + "operation": "0x683f666c05682cdbf8ad0d2bd988515deca0dc82296d4366debfbff738f7eacb", + "validator": "rarimo1eqmyvqge5mu7cfv4gjy8y7smfxhq5r0ctljf0n" + }, + "vote": "YES" +} +``` + +Example: ### Violation report -**ViolationReport** - stored reports from TSS about other parties violations. Used to calculate violations amount and exclude from parties set upon reaching the configured aount. +**ViolationReport** - stored reports from TSS about other parties violations. Used to calculate violations amount and +exclude from parties set upon reaching the configured aount. Definition: - ```protobuf - enum ViolationType { - Offline = 0; - Spam = 1; - Other = 3; - } - - message ViolationReportIndex { - string sessionId = 1; - string offender = 2; - ViolationType violationType = 3; - string sender = 4; - } - - message ViolationReport { - ViolationReportIndex index = 1; - // Optional message - string msg = 3; - } - ``` + +```protobuf +enum ViolationType { + Offline = 0; + Spam = 1; + Other = 3; +} + +message ViolationReportIndex { + string sessionId = 1; + string offender = 2; + ViolationType violationType = 3; + string sender = 4; +} + +message ViolationReport { + ViolationReportIndex index = 1; + // Optional message + string msg = 3; +} +``` ---- ## Keepers -The `rarimocore` module only exposes one keeper, which can be used to create operations, access TSS parties information in params, access and create votes. +The `rarimocore` module only exposes one keeper, which can be used to create operations, access TSS parties information +in params, access and create votes. Some of useful Keeper methods: @@ -310,9 +316,11 @@ Definition: `CreateTransferOperation(ctx sdk.Context, creator string, transfer *types.Transfer, approved bool) error` Flow: + - Get source network from `tokenmanager` module. Check that bridge transfers are acceptable for that network. - Create operation entry and check that operation does not exist. -- Only not approved operation can be replaced. If operation already exists and has to be replaced then we have to clear all existing votes. +- Only not approved operation can be replaced. If operation already exists and has to be replaced then we have to clear + all existing votes. - If approve is required then will call `ApproveOperation`. ### ApproveOperation @@ -325,6 +333,7 @@ Definition: Flow: The method is designed to execute some special logic for operation approvals. Currently, only for transfer operation such logic exists: + - Get `CollectionData` for source token - Get `OnChainItem` for source token - If `OnChainItem` does not exist then create `Item` (also does not exist), create `OnChainItem`, set seed if provided. @@ -340,6 +349,7 @@ Definition: `CreateVote(ctx sdk.Context, vote types.Vote) (bool, error)` Flow: + - Check that operation exists - Check that vote does not exist - Check operation status (should be `INITIALIZED`) @@ -353,22 +363,27 @@ Definition: `CreateIdentityDefaultTransferOperation(ctx sdk.Context, creator string, transfer *types.IdentityDefaultTransfer) error` Flow: + - Get source network from `tokenmanager` module. Check that bridge transfers are acceptable for that network. - Create operation entry and check that operation does not exist. -- Only not approved operation can be replaced. If operation already exists and need to be replaced then we have to clear all existing votes. +- Only not approved operation can be replaced. If operation already exists and need to be replaced then we have to clear + all existing votes. ### CreateFeeTokenManagementOperation -**CreateFeeTokenManagementOperation** - used by `tokenmanager` module to create fee management operation after proposal acceptance. +**CreateFeeTokenManagementOperation** - used by `tokenmanager` module to create fee management operation after proposal +acceptance. Definition: `CreateFeeTokenManagementOperation(ctx sdk.Context, op *types.FeeTokenManagement) error` Flow: + - Create operation entry and check that operation does not exist. - Approve operation Also, use + - `CreateWithdrawFeeOperation(ctx sdk.Context, token tokentypes.FeeToken, chain string, receiver string, nonce string) error` - `CreateUpdateFeeTokenOperation(ctx sdk.Context, token tokentypes.FeeToken, chain string, nonce string) error` - `CreateRemoveFeeTokenOperation(ctx sdk.Context, token tokentypes.FeeToken, chain string, nonce string) error` @@ -381,21 +396,25 @@ Also, use ### CreateChangePartiesOperation **CreateChangePartiesOperation** - creates new operation with type `CHANGE_PARTIES` and `APPROVED` status. - Used by TSS producers to reshare keys when parties set has been changed. - Signature field contains the signature of new public key by old public key and will be used to change keys on the bridge contracts. - ```protobuf - message MsgCreateChangePartiesOp { - string creator = 1; - repeated Party newSet = 2; - string newPublicKey = 3; - string signature = 4; - } - ``` +Used by TSS producers to reshare keys when parties set has been changed. +Signature field contains the signature of new public key by old public key and will be used to change keys on the bridge +contracts. + +```protobuf +message MsgCreateChangePartiesOp { + string creator = 1; + repeated Party newSet = 2; + string newPublicKey = 3; + string signature = 4; +} +``` ### CreateConfirmation -**CreateConfirmation** - creates the confirmation for set of operations. After confirmation created user can use provided -signature and merkle tree to execute event unlocking on destination chain. Confirmation can be created only for operation with `APPROVED` status. +**CreateConfirmation** - creates the confirmation for set of operations. After confirmation created user can use +provided +signature and merkle tree to execute event unlocking on destination chain. Confirmation can be created only for +operation with `APPROVED` status. After hash and signature verification operation status will be changed to `SIGNED`. - Verify signature for provided tree root corresponds to the stored in params public key @@ -408,38 +427,41 @@ After hash and signature verification operation status will be changed to `SIGNE Apply operation is designed to execute special functional for any operation after is becomes signed. Also, ApplyOperation method changes the operation status to `SIGNED` - ```protobuf - message MsgCreateConfirmation { - string creator = 1; - // hex-encoded - string root = 2; - repeated string indexes = 3; - // hex-encoded - string signatureECDSA = 4; - } - ``` +```protobuf +message MsgCreateConfirmation { + string creator = 1; + // hex-encoded + string root = 2; + repeated string indexes = 3; + // hex-encoded + string signatureECDSA = 4; +} +``` ### SetupInitial -**SetupInitial** - used only in setup phase (when ECDSA key in params is empty and update flag is true). After threshold keys generation TSS parties submits +**SetupInitial** - used only in setup phase (when ECDSA key in params is empty and update flag is true). After threshold +keys generation TSS parties submits `MsgSetupInitial` to confirm successful keys generation and provide new party public key data. - ```protobuf - message MsgSetupInitial { - string creator = 1; - string partyPublicKey = 2; - string newPublicKey = 3; - } - ``` + +```protobuf + message MsgSetupInitial { + string creator = 1; + string partyPublicKey = 2; + string newPublicKey = 3; +} +``` ### ChangePartyAddress **ChangePartyAddress** - changes party address. Only party account can execute. Change will be applied immediately. - ```protobuf - message MsgChangePartyAddress { - string creator = 1; - string newAddress = 2; - } - ``` + +```protobuf +message MsgChangePartyAddress { + string creator = 1; + string newAddress = 2; +} +``` ### Stake @@ -449,14 +471,14 @@ Also, ApplyOperation method changes the operation status to `SIGNED` - Transfer coins from account to module - Add inactive party to the list and set `UpdateIsRequired` flag. - ```protobuf - message MsgStake { - string creator = 1; - string account = 2; - string address = 3; - string trialPublicKey = 4; - } - ``` +```protobuf +message MsgStake { + string creator = 1; + string account = 2; + string address = 3; + string trialPublicKey = 4; +} +``` ### Unstake @@ -467,12 +489,12 @@ Also, ApplyOperation method changes the operation status to `SIGNED` - Transfer coins from module account to party or delegator (depends on msg signer) - Remove party from list and set `UpdateIsRequired` flag. - ```protobuf - message MsgUnstake { - string creator = 1; - string account = 2; - } - ``` +```protobuf + message MsgUnstake { + string creator = 1; + string account = 2; +} +``` ### CreateViolationReport @@ -481,19 +503,21 @@ Also, ApplyOperation method changes the operation status to `SIGNED` - Check that sender and offender is active parties - Check that violation has not been created yet - Save violation report -- Iterate over existing reports, increment party violations if there are more than threshold violations for same session. -- If party violations reaches `maxViolationsCount` (in params) then change party status to `Frozen` and set `UpdateIsRequired` flag. - - ```protobuf - message MsgCreateViolationReport { - string creator = 1; - string sessionId = 2; - rarimo.rarimocore.rarimocore.ViolationType violationType = 3; - string offender = 4; - // Optional message - string msg = 5; - } - ``` +- Iterate over existing reports, increment party violations if there are more than threshold violations for same + session. +- If party violations reaches `maxViolationsCount` (in params) then change party status to `Frozen` and + set `UpdateIsRequired` flag. + +```protobuf + message MsgCreateViolationReport { + string creator = 1; + string sessionId = 2; + rarimo.rarimocore.rarimocore.ViolationType violationType = 3; + string offender = 4; + // Optional message + string msg = 5; +} +``` ---- @@ -501,47 +525,54 @@ Also, ApplyOperation method changes the operation status to `SIGNED` ### UnfreezeSignerPartyProposal -**UnfreezeSignerPartyProposal** - if party reaches ```maxViolationsCount``` is becomes freezed and there will be some time (```freezeBlocksPeriod```) when unfreeze proposal can be created. If after ```freezeBlocksPeriod``` party is still freezed it will be slashed forever. - ```protobuf - message UnfreezeSignerPartyProposal { - string title = 1; - string description = 2; - string account = 3; - } - ``` +**UnfreezeSignerPartyProposal** - if party reaches ```maxViolationsCount``` is becomes freezed and there will be some +time (```freezeBlocksPeriod```) when unfreeze proposal can be created. If after ```freezeBlocksPeriod``` party is still +freezed it will be slashed forever. + +```protobuf +message UnfreezeSignerPartyProposal { + string title = 1; + string description = 2; + string account = 3; +} +``` ### ReshareKeysProposal -**ReshareKeysProposal** - will set `isUpdateRequired=true` and launch key resharing if any of parties lost his secret key data. - ```protobuf - message ReshareKeysProposal { - string title = 1; - string description = 2; - } - ``` +**ReshareKeysProposal** - will set `isUpdateRequired=true` and launch key resharing if any of parties lost his secret +key data. + +```protobuf +message ReshareKeysProposal { + string title = 1; + string description = 2; +} +``` ### SlashProposal **SlashProposal** - proposal to slash a party immediately. - ```protobuf - message SlashProposal { - string title = 1; - string description = 2; - string party = 3; - } - ``` + +```protobuf +message SlashProposal { + string title = 1; + string description = 2; + string party = 3; +} +``` ### DropPartiesProposal **DropPartiesProposal** - in some cases we will need to drop all parties and regenerate keys again. - Using that proposal you can unstake all parties (that is active/inactive or freezed) and clear parties set. - After the new parties should use ```Stake``` operation and ```SetupInitial``` operation to generate new parties set. Also changing bridge contracts will be also required because we can not provide signature for changing public key. - - ```protobuf - message DropPartiesProposal { - string title = 1; - string description = 2; - } - ``` +Using that proposal you can unstake all parties (that is active/inactive or freezed) and clear parties set. +After the new parties should use ```Stake``` operation and ```SetupInitial``` operation to generate new parties set. +Also changing bridge contracts will be also required because we can not provide signature for changing public key. + +```protobuf +message DropPartiesProposal { + string title = 1; + string description = 2; +} +``` ---- diff --git a/x/tokenmanager/README.md b/x/tokenmanager/README.md index 8920e3be..5a0723ec 100644 --- a/x/tokenmanager/README.md +++ b/x/tokenmanager/README.md @@ -11,13 +11,15 @@ The `tokenamanager` module is responsible for storing information about all supp ## Concepts -For FT and Native tokens such an information will be strongly predefined. NFT collection can contain huge amount of tokens under it, and also they can be minted in future. -So we can not define all tokens in core during initialization or token add operation. That is why collections flow was created. +For FT and Native tokens such an information will be strongly predefined. NFT collection can contain huge amount of +tokens under it, and also they can be minted in future. +So we can not define all tokens in core during initialization or token add operation. That is why collections flow was +created. Using `tokenmanager` `Collection` and `CollectionData` we can define collection global and chain information regardless of the number of tokens in collection or their metadata. Token information (`Item` and `OnChainItem`) will be set up during the first token transfer. -During the first transfer oracles should fill the metadata field in `MsgCreateTransferOp` and provide all required token information to create `Item` and `OnChainItem`. - +During the first transfer oracles should fill the metadata field in `MsgCreateTransferOp` and provide all required token +information to create `Item` and `OnChainItem`. ## State @@ -26,133 +28,132 @@ During the first transfer oracles should fill the metadata field in `MsgCreateTr **Params** - defines supported networks and their bridge contracts Definition: - ```protobuf - enum NetworkType { - EVM = 0; - Solana = 1; - Near = 2; - Other = 3; - } - - enum NetworkParamType { - BRIDGE = 0; - FEE = 1; - IDENTITY = 2; - } - - message Network { - // network name - string name = 1; - NetworkType type = 2; - repeated NetworkParams params = 3 [(gogoproto.nullable) = false]; - } - - message NetworkParams { - NetworkParamType type = 1; - // Corresponding to type details - google.protobuf.Any details = 2; - } - - message BridgeNetworkParams { - string contract = 1; - } - message FeeNetworkParams { - string contract = 1; - repeated FeeToken feeTokens = 2; - } - - message IdentityNetworkParams { - string contract = 1; - } - - message FeeToken { - // contract address hex - string contract = 1; - string amount = 2; - } - - // Params defines the parameters for the module. - message Params { - repeated Network networks = 1; - } - ``` - -
- Example - - ```json +```protobuf +enum NetworkType { + EVM = 0; + Solana = 1; + Near = 2; + Other = 3; +} + +enum NetworkParamType { + BRIDGE = 0; + FEE = 1; + IDENTITY = 2; +} + +message Network { + // network name + string name = 1; + NetworkType type = 2; + repeated NetworkParams params = 3 [(gogoproto.nullable) = false]; +} + +message NetworkParams { + NetworkParamType type = 1; + // Corresponding to type details + google.protobuf.Any details = 2; +} + +message BridgeNetworkParams { + string contract = 1; +} + +message FeeNetworkParams { + string contract = 1; + repeated FeeToken feeTokens = 2; +} + +message IdentityNetworkParams { + string contract = 1; +} + +message FeeToken { + // contract address hex + string contract = 1; + string amount = 2; +} + +// Params defines the parameters for the module. +message Params { + repeated Network networks = 1; +} +``` + +Example: + +```json +{ + "networks": [ { - "networks": [ - { - "name":"Solana", - "type":"Solana", - "params":[ - { - "type":"BRIDGE", - "details":{ - "@type":"/rarimo.rarimocore.tokenmanager.BridgeNetworkParams", - "contract":"0x6e632137764e7ba6b053ba055a0e63b5151d5866f846fc5c23302517d8b778a8" - } - }, - { - "type":"FEE", - "details":{ - "@type":"/rarimo.rarimocore.tokenmanager.FeeNetworkParams", - "contract":"0x00", - "feeTokens":[ - { - "contract":"", - "amount":"1" - } - ] - } - } - ] + "name": "Solana", + "type": "Solana", + "params": [ + { + "type": "BRIDGE", + "details": { + "@type": "/rarimo.rarimocore.tokenmanager.BridgeNetworkParams", + "contract": "0x6e632137764e7ba6b053ba055a0e63b5151d5866f846fc5c23302517d8b778a8" + } + }, + { + "type": "FEE", + "details": { + "@type": "/rarimo.rarimocore.tokenmanager.FeeNetworkParams", + "contract": "0x00", + "feeTokens": [ + { + "contract": "", + "amount": "1" + } + ] } - ] + } + ] } - ``` -
+ ] +} +``` ### Collection **Collection** - the high level concept of token that is supported on Rarimo bridge. Definition: - ```protobuf - message CollectionMetadata { - string name = 1; - string symbol = 2; - string metadataURI = 3; - } - - message CollectionDataIndex { - // Chain name - string chain = 1; - // Collection contract address - string address = 2; - } - - message Collection { - string index = 1; - CollectionMetadata meta = 2; - repeated CollectionDataIndex data = 3; - } - ``` - -
- Example - ```json - { - "index": "usdt", - "meta": { - "name": "Tether USD", - "symbol": "USDT", - "metadataURI": "" - }, - "data": [ +```protobuf +message CollectionMetadata { + string name = 1; + string symbol = 2; + string metadataURI = 3; +} + +message CollectionDataIndex { + // Chain name + string chain = 1; + // Collection contract address + string address = 2; +} + +message Collection { + string index = 1; + CollectionMetadata meta = 2; + repeated CollectionDataIndex data = 3; +} +``` + +Example: + +```json +{ + "index": "usdt", + "meta": { + "name": "Tether USD", + "symbol": "USDT", + "metadataURI": "" + }, + "data": [ { "chain": "Solana", "address": "0xc4192d3818061c9d9333b6e658422b095cc2417dfe313f7286f96108d543253d" @@ -165,108 +166,107 @@ Definition: "chain": "Goerli", "address": "0x2f362dF82622120f7181e432446E7665f51fFb03" } - ] - } - ``` -
+ ] +} +``` ### CollectionData -**CollectionData** - defines collection data on the certain chain. Indexed by chain|address and contains id of the collection. +**CollectionData** - defines collection data on the certain chain. Indexed by chain|address and contains id of the +collection. Definition: - ```protobuf - message CollectionData { - CollectionDataIndex index = 1; - string collection = 2; - Type tokenType = 3; - bool wrapped = 4; - uint32 decimals = 5; - } - ``` - -
- Example - ```json - [ - { - "index": { +```protobuf +message CollectionData { + CollectionDataIndex index = 1; + string collection = 2; + Type tokenType = 3; + bool wrapped = 4; + uint32 decimals = 5; +} +``` + +Example: + +```json +[ + { + "index": { "chain": "Goerli", "address": "0x2f362dF82622120f7181e432446E7665f51fFb03" }, - "collection": "usdt", - "tokenType": "ERC20", - "wrapped": true, - "decimals": 18 - }, - { - "index": { + "collection": "usdt", + "tokenType": "ERC20", + "wrapped": true, + "decimals": 18 + }, + { + "index": { "chain": "Near", "address": "0x757364742e726172696d6f2e746573746e6574" }, - "collection": "usdt", - "tokenType": "NEAR_FT", - "wrapped": true, - "decimals": 18 - }, - { - "index": { + "collection": "usdt", + "tokenType": "NEAR_FT", + "wrapped": true, + "decimals": 18 + }, + { + "index": { "chain": "Solana", "address": "0xc4192d3818061c9d9333b6e658422b095cc2417dfe313f7286f96108d543253d" }, - "collection": "usdt", - "tokenType": "METAPLEX_FT", - "wrapped": true, - "decimals": 9 - } - ] - ``` -
+ "collection": "usdt", + "tokenType": "METAPLEX_FT", + "wrapped": true, + "decimals": 9 + } +] +``` ### Item **Item** - defines one simple token across all chains. Contains all metadata required to perform transfers. Definition: - ```protobuf - message ItemMetadata { - string imageUri = 1; - // Hash of the token image. Encoded into hex string. (optional) - string imageHash = 2; - // Seed is used to generate PDA address for Solana - string seed = 3; - string uri = 4; - } - - message OnChainItemIndex { - string chain = 1; - string address = 2; - string tokenID = 3; - } - - message Item { - string index = 1; - string collection = 2; - ItemMetadata meta = 3; - repeated OnChainItemIndex onChain = 4; - } - ``` - -
- Example - ```json - { - "index": "usdt", - "collection": "usdt", - "meta": { - "imageUri": "", - "imageHash": "", - "seed": "", - "uri": "" - }, - "onChain": [ +```protobuf +message ItemMetadata { + string imageUri = 1; + // Hash of the token image. Encoded into hex string. (optional) + string imageHash = 2; + // Seed is used to generate PDA address for Solana + string seed = 3; + string uri = 4; +} + +message OnChainItemIndex { + string chain = 1; + string address = 2; + string tokenID = 3; +} + +message Item { + string index = 1; + string collection = 2; + ItemMetadata meta = 3; + repeated OnChainItemIndex onChain = 4; +} +``` + +Example: + +```json +{ + "index": "usdt", + "collection": "usdt", + "meta": { + "imageUri": "", + "imageHash": "", + "seed": "", + "uri": "" + }, + "onChain": [ { "chain": "Solana", "address": "0xc4192d3818061c9d9333b6e658422b095cc2417dfe313f7286f96108d543253d", @@ -282,62 +282,60 @@ Definition: "address": "0x2f362dF82622120f7181e432446E7665f51fFb03", "tokenID": "" } - ] - } - ``` -
+ ] +} +``` ### OnChainItem **OnChainItem** - defines one simple token on the certain chain. Indexed by `chain|address|tokenId`. Definition: - ```protobuf - message OnChainItem { - OnChainItemIndex index = 1; - string item = 2; - } - ``` -
- Example +```protobuf +message OnChainItem { + OnChainItemIndex index = 1; + string item = 2; +} +``` - ```json - [ - { - "index": { +Example: + +```json +[ + { + "index": { "chain": "Goerli", "address": "0x2f362dF82622120f7181e432446E7665f51fFb03", "tokenID": "" }, - "item": "usdt" - }, - { - "index": { + "item": "usdt" + }, + { + "index": { "chain": "Near", "address": "0x757364742e726172696d6f2e746573746e6574", "tokenID": "" }, - "item": "usdt" - }, - { - "index": { + "item": "usdt" + }, + { + "index": { "chain": "Solana", "address": "0xc4192d3818061c9d9333b6e658422b095cc2417dfe313f7286f96108d543253d", "tokenID": "" }, - "item": "usdt" - } - ] - ``` -
- + "item": "usdt" + } +] +``` ---- ## Keepers -The `tokenmanager` module only exposes one keeper, which can be used to access information about supported tokens to transfer and supported network params. +The `tokenmanager` module only exposes one keeper, which can be used to access information about supported tokens to +transfer and supported network params. ---- @@ -347,101 +345,110 @@ The `tokenmanager` module only exposes one keeper, which can be used to access i ### SetNetworkProposal **SetNetworkProposal** - creating or updating existing network params. - ```protobuf - message SetNetworkProposal { - string title = 1; - string description = 2; - NetworkParams networkParams = 3; - } - ``` + +```protobuf +message SetNetworkProposal { + string title = 1; + string description = 2; + NetworkParams networkParams = 3; +} +``` ### UpdateTokenItemProposal **UpdateTokenItemProposal** - updating token item params (metadata) - ```protobuf - message UpdateTokenItemProposal { - string title = 1; - string description = 2; - repeated Item item = 3; - } - ``` +```protobuf +message UpdateTokenItemProposal { + string title = 1; + string description = 2; + + repeated Item item = 3; +} +``` ### RemoveTokenItemProposal **RemoveTokenItemProposal** - removing token item from core. - ```protobuf - message RemoveTokenItemProposal { - string title = 1; - string description = 2; - repeated string index = 3; - } - ``` +```protobuf +message RemoveTokenItemProposal { + string title = 1; + string description = 2; + + repeated string index = 3; +} +``` ### CreateCollectionProposal -**CreateCollectionProposal** - adding new collection. CollectionData should be provided. Items and OnChainItems can be optionally provided. - ```protobuf - message CreateCollectionProposal { - string title = 1; - string description = 2; - - string index = 3; - CollectionMetadata metadata = 4; - // All supported networks described - repeated CollectionData data = 5; - repeated Item item = 6; - repeated OnChainItem onChainItem = 7; - } - ``` +**CreateCollectionProposal** - adding new collection. CollectionData should be provided. Items and OnChainItems can be +optionally provided. + +```protobuf +message CreateCollectionProposal { + string title = 1; + string description = 2; + + string index = 3; + CollectionMetadata metadata = 4; + // All supported networks described + repeated CollectionData data = 5; + repeated Item item = 6; + repeated OnChainItem onChainItem = 7; +} +``` ### UpdateCollectionDataProposal **UpdateCollectionDataProposal** - updating collection data information. - ```protobuf - message UpdateCollectionDataProposal { - string title = 1; - string description = 2; - repeated CollectionData data = 3; - } - ``` +```protobuf +message UpdateCollectionDataProposal { + string title = 1; + string description = 2; + + repeated CollectionData data = 3; +} +``` ### AddCollectionDataProposal **AddCollectionDataProposal** - adding collection data (which means support of new chain for collection) - ```protobuf - message AddCollectionDataProposal { - string title = 1; - string description = 2; - repeated CollectionData data = 3; - } - ``` +```protobuf +message AddCollectionDataProposal { + string title = 1; + string description = 2; + + repeated CollectionData data = 3; +} +``` ### RemoveCollectionDataProposal **RemoveCollectionDataProposal** - removing collection data (which means disabling of certain chain for collection) - ```protobuf - message RemoveCollectionDataProposal { - string title = 1; - string description = 2; - repeated CollectionDataIndex index = 3; - } - ``` +```protobuf +message RemoveCollectionDataProposal { + string title = 1; + string description = 2; + + repeated CollectionDataIndex index = 3; +} +``` ### RemoveCollectionProposal **RemoveCollectionProposal** - removing the hole collection - ```protobuf - message RemoveCollectionProposal { - string title = 1; - string description = 2; - string index = 3; - } - ``` +```protobuf +message RemoveCollectionProposal { + string title = 1; + string description = 2; + + string index = 3; +} +``` ---- \ No newline at end of file