# 21 - LLMQ DKG Data Sharing
  DIP: 0021
  Title: LLMQ DKG Data Sharing
  Author(s): dustinface
  Special-Thanks:
  Comments-Summary: No comments yet.
  Status: Proposed
  Type: Standard
  Created: 2021-03-08
  License: MIT License
# Table of Contents 1. [Abstract](#abstract) 1. [Motivation](#motivation) 1. [Prior Work](#prior-work) 1. [Specification](#specification) 1. [Processing and Usage](#processing-and-usage) 1. [Reference Implementation](#reference-implementation) 1. [Copyright](#copyright) # Abstract This document introduces two new P2P messages called `QGETDATA` and `QDATA`. The `QGETDATA` message allows masternodes to request `QDATA` messages containing various data payloads, such as quorum verification vectors or distributed key generation (DKG) contributions, from members of a Long Living Masternode Quorum (LLMQ). # Motivation There are the following two problems which can be solved with the proposed P2P messages: 1. In Tenderdash a validator-set is represented by an LLMQ. In order to change the validator-set from _LLMQx_ to _LLMQy_, _LLMQx_ must include all required data (including public key shares) of _LLMQy_ in the Tenderdash block which proposes/executes the validator-set rotation. This means that for validator-set rotation in Tenderdash to work, all members of _LLMQx_ must have the quorum verification vector of _LLMQy_ (which currently isn’t the case) so they can calculate the public key shares for all LLMQy members. 2. If a member of _LLMQx_ needs to reindex or wipe the data directory (e.g. due to unexpected issues during an upgrade or unexpected file corruption), it currently loses all the information it requires to participate in _LLMQx_ signing sessions. This information includes the quorum verification vector and its own DKG secret key share. Currently there is no mechanism for masternodes to recover this data from other members. # Prior work * [DIP-0006: Long-Living Masternode Quorums](https://github.com/dashpay/dips/blob/master/dip-0006.md) # Specification Two new messages are defined: `QGETDATA` and `QDATA`. The two new P2P messages will only be available for masternodes, must be ignored by non-masternode connections and must be rate limited to prevent potential DoS attacks. Masternodes will only be allowed to request DKG data with `QGETDATA` from each member once every 5 minutes. Any incorrect usage of these messages should result in a connection ban score increase of: * 10 - For duplicate/invalid/malformed messages * 25 - For exceeding the rate limit threshold These messages will be available upon activation of protocol version 70219. ## P2P - QGETDATA The `QGETDATA` message is used to request a `QDATA` message from another masternode. The following table defines its available parameters: ### Payload description | Field | Type | Size | Description | | - | - | - | - | | quorumType | uint8 | 1 byte | Type of the quorum to request data from. | | quorumHash | uint256 | 32 bytes | Hash of the quorum to request data from. | | dataMask | uint16 | 2 bytes | Defines which data to request, see [Available data flags](#available-data-flags). | | protxHash | uint256 | 32 bytes | (_Optional_) Protx hash. See _0x0002_ in [Available data flags](#available-data-flags). | Where `quorumHash` and `quorumType` define from which quorum the data defined by `dataMask` gets requested. ## P2P - QDATA The `QDATA` message is the response to `QGETDATA` messages. It should be ignored and result in a small ban-score increase if it has not been requested. The following table describes its possible payload: ### Payload description | Field | Type | Size | Description | | - | - | - | - | | quorumType | uint8 | 1 byte | Type of the quorum the data is about. | quorumHash | uint256 | 32 bytes | Hash of the quorum the data is about. | dataMask | uint16 | 2 bytes | See [Available data flags](#available-data-flags). This value should be equal to the `dataMask` value of the requesting `QGETDATA` message. | protxHash | uint256 | 32 bytes | This is the protx hash of the member which can decrypt the data in `data_0002`. Included if _0x0002_ is set in `dataMask`. | error | uint8 | 1 byte | See [Possible error codes](#possible-error-codes) | data_0001 | BLSVerificationVector | Variable | Included if _0x0001_ is set in `dataMask`. See [Available data flags](#available-data-flags). | data_0002 | std::vector<CBLSIESEncryptedObject<CBLSSecretKey>> | Variable | Included if _0x0002_ is set in `dataMask`. See [Available data flags](#available-data-flags). ## Available data flags | Flag | Description | Response | | - | - | - | | _0x0001_ | Request the quorum verification vector of the LLMQ. | The quorum verification vector of the LLMQ.

**Type**: _std::vector<CBLSPublicKey>_

**Size**: <quorum_threshold> * 48 bytes

**Max. size**: ~16,320 bytes | _0x0002_ | Request all encrypted DKG contributions directed to the member with the protx hash provided in the _protxHash_ field. | Set of secret keys encrypted with the operator key of the requesting masternode.

**Type**: std::vector<CBLSIESEncryptedObject<CBLSSecretKey>>

**Size**: * 112 bytes

**Max. Size**: 44,800 bytes ## Possible error codes | Value | Name | Description | | - | - | - | | _0x00_ | _NONE_ | No error, this value indicates the `QGETDATA` request was processed successfully. | _0x01_ | _QUORUM_TYPE_INVALID_ | The quorum type provided in the `quorumType` field is invalid. | _0x02_ | _QUORUM_BLOCK_NOT_FOUND_ | The hash provided in the `quorumHash` field wasn’t found in the active chain. | _0x03_ | _QUORUM_NOT_FOUND_ | The quorum (combination of `quorumType` and `quorumHash`) wasn’t found in the active chain. | _0x04_ | _MASTERNODE_IS_NO_MEMBER_ | The masternode with the protx-hash provided in the `protxHash` field is not a valid member of the requested quorum. | _0x05_ | _QUORUM_VERIFICATION_VECTOR_MISSING_ | The quorum verification vector for the requested quorum is missing on the node servicing the request. | _0x06_ | _ENCRYPTED_CONTRIBUTIONS_MISSING_ | The encrypted DKG contributions for the requested member are missing on the node servicing the request. # Processing and usage For each `QDATA` message received, the receiving masternode must validate and store the related data. The following table shows the steps required depending on the _dataType_ received: | dataType | Validate and process the data | Usage | | - | - | - | | _0x0001_ | Calculate the hash of the received quorum verification vector. The calculated hash must match `quorumvvecHash` from the mined commitment of the LLMQ the data has been requested for. | Mainly used to make the quorum verification vector of other LLMQs available on platform validators. Another use case is described in “Usage” of the flag _0x0002_ below. | 0x0002 | Decrypt all the contributions with the operator key, aggregate them to the secret key share and make sure its public key matches the public key share calculated with the quorum verification vector for the masternode’s `protxHash`. | This can be wrapped into a workflow where a masternode which is a member of one or more quorums has lost its LLMQ DKG data. By requesting _0x0002_ it can recover its secret key share. When combined with _0x0001_, it can recover itself as a valid member of the LLMQ by just asking other LLMQ-Members for the required data after a re-sync/re-index. # Reference implementation * [Implement P2P messages QGETDATA <-> QDATA](https://github.com/dashpay/dash/pull/3953) * [Implement DKG data recovery / quorum verification vector sync](https://github.com/dashpay/dash/pull/3964) * [Add "mode" to -llmq-qvvec-sync parameter](https://github.com/dashpay/dash/pull/4030) # Copyright Copyright (c) 2021 Dash Core Group, Inc. [Licensed under the MIT License](https://opensource.org/licenses/MIT)