Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(p2p): dsq updates #121

Merged
merged 4 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 40 additions & 31 deletions docs/guide/dash-features-coinjoin.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ Protocol version 70213 added a 5th denomination (0.001 DASH).

**Creating Collaterals**

Collaterals are used to pay CoinJoin fees, but are kept separate from the denominations to maximize privacy. Since protocol version 70213, the minimum collateral fee is 1/10 of the smallest denomination for all sessions regardless of denomination. In Dash Core, collaterals are created with enough value to pay 4 collateral fees (4 x 0.001 DASH). ([Dash Core Reference](https://github.com/dashpay/dash/blob/v0.15.0.0/src/privatesend/privatesend.h#L459))
Collaterals are used to pay CoinJoin fees, but are kept separate from the denominations to maximize privacy. Since protocol version 70213, the minimum collateral fee is 1/10 of the smallest denomination for all sessions regardless of denomination. In Dash Core, collaterals are created with enough value to pay 4 collateral fees (4 x 0.001 DASH). ([Dash Core Reference](https://github.com/dashpay/dash/blob/v21.1.x/src/coinjoin/common.h#L109))

In protocol version 70208, collateral inputs can be anything from 2x the minimum collateral amount to the maximum collateral amount (currently defined as 4x the minimum collateral). In protocol versions > 70208, Dash Core can use any [input](../resources/glossary.md#input) from 1x the minimum collateral amount to the maximum collateral amount.
In protocol versions > 70208, Dash Core can use any [input](../resources/glossary.md#input) from 1x the minimum collateral amount to the maximum collateral amount.

[Example Testnet collateral creation transaction](https://testnet-insight.dashevo.org/insight/tx/8f9b15973983876f7ce4eb2c32b09690dfb0432d2caf6c6df516196a8d17689f)

Expand All @@ -52,24 +52,33 @@ In protocol version 70208, collateral inputs can be anything from 2x the minimum

This phase involves exchanging a sequence of messages with a [masternode](../resources/glossary.md#masternode) so it can construct a denominate transaction with inputs from the clients in its pool.

*Data Flow*
### Data Flow

:::{attention}
Since protocol version 70234 (Dash Core 22.0.0), the [`dsq`
message](../reference/p2p-network-privatesend-messages.md#dsq) is broadcast using the inventory
system instead of being relayed to all connected peers. This reduces the bandwidth needs for all
nodes, especially highly connected masternodes.
:::

| | **Clients** | **Direction** | **Masternode** | **Description** |
| --- | --- | :---: | --- | --- |
| 0 | | | | Client determines whether to join an existing pool or create a new one |
| 1 | [`dsa` message](../reference/p2p-network-privatesend-messages.md#dsa) | → | | Client asks to join pool or have the masternode create a new one
| 2 | | ← | [`dssu` message](../reference/p2p-network-privatesend-messages.md#dssu) | Masternode provides a pool status update (Typical - State: `POOL_STATE_QUEUE`, Message: `MSG_NOERR`)
| 3 | | ← | [`dsq` message](../reference/p2p-network-privatesend-messages.md#dsq) | Masternode notifies clients when it is ready to receive inputs
| 4 | [`dsi` message](../reference/p2p-network-privatesend-messages.md#dsi) | → | | Upon receiving a [`dsq` message](../reference/p2p-network-privatesend-messages.md#dsq) with the Ready bit set, clients each provide a list of their inputs (unsigned), collateral, and a list of outputs where funds should be sent
| 5 | | ← | [`dssu` message](../reference/p2p-network-privatesend-messages.md#dssu) | Masternode provides a pool status update (typical - State: `POOL_STATE_ACCEPTING_ENTRIES`, Message: `MSG_ENTRIES_ADDED`)
| 6 | | ← | [`dsf` message](../reference/p2p-network-privatesend-messages.md#dsf) | Masternode sends the final transaction containing all clients inputs (unsigned) and all client outputs to each client for verification
| 7 | | ← | [`dssu` message](../reference/p2p-network-privatesend-messages.md#dssu) | Masternode provides a pool status update (Typical - State: `POOL_STATE_SIGNING`, Message: `MSG_NOERR`)
| 8 | [`dss` message](../reference/p2p-network-privatesend-messages.md#dss) | → | | After verifying the final transaction, clients each sign their own inputs with the `SIGHASH_ALL \| SIGHASH_ANYONECANPAY` signature type and send them back
| 9 | | ← | [`dsc` message](../reference/p2p-network-privatesend-messages.md#dsc) | Masternode verifies the signed inputs, creates a [`dstx` message](../reference/p2p-network-privatesend-messages.md#dstx) to broadcast the transaction, and notifies clients that the denominate transaction is complete (Typical - Message: `MSG_SUCCESS`)
| 10 | | ← | [`inv` message](../reference/p2p-network-data-messages.md#inv) | Masternode broadcasts a `dstx` inventory message
| 11 | [`getdata` message](../reference/p2p-network-data-messages.md#getdata) (dstx) | → | | (Optional)

**Additional notes**
| 3 | | ← | [`inv` message](../reference/p2p-network-data-messages.md#inv) (dsq) | Masternode notifies clients when it is ready to receive inputs by sending a `dsq` inventory message
| 4 | [`getdata` message](../reference/p2p-network-data-messages.md#getdata) (dsq) | → | | Client requests a [`dsq` message](../reference/p2p-network-privatesend-messages.md#dsq)
| 5 | | ← | [`dsq` message](../reference/p2p-network-privatesend-messages.md#dsq) | Masternode responds with the requested [`dsq` message](../reference/p2p-network-privatesend-messages.md#dsq)
| 6 | [`dsi` message](../reference/p2p-network-privatesend-messages.md#dsi) | → | | Upon receiving a [`dsq` message](../reference/p2p-network-privatesend-messages.md#dsq) with the Ready bit set, clients each provide a list of their inputs (unsigned), collateral, and a list of outputs where funds should be sent
| 7 | | ← | [`dssu` message](../reference/p2p-network-privatesend-messages.md#dssu) | Masternode provides a pool status update (typical - State: `POOL_STATE_ACCEPTING_ENTRIES`, Message: `MSG_ENTRIES_ADDED`)
| 8 | | ← | [`dsf` message](../reference/p2p-network-privatesend-messages.md#dsf) | Masternode sends the final transaction containing all clients inputs (unsigned) and all client outputs to each client for verification
| 9 | | ← | [`dssu` message](../reference/p2p-network-privatesend-messages.md#dssu) | Masternode provides a pool status update (Typical - State: `POOL_STATE_SIGNING`, Message: `MSG_NOERR`)
| 10 | [`dss` message](../reference/p2p-network-privatesend-messages.md#dss) | → | | After verifying the final transaction, clients each sign their own inputs with the `SIGHASH_ALL \| SIGHASH_ANYONECANPAY` signature type and send them back
| 11 | | ← | [`dsc` message](../reference/p2p-network-privatesend-messages.md#dsc) | Masternode verifies the signed inputs, creates a [`dstx` message](../reference/p2p-network-privatesend-messages.md#dstx) to broadcast the transaction, and notifies clients that the denominate transaction is complete (Typical - Message: `MSG_SUCCESS`)
| 12 | | ← | [`inv` message](../reference/p2p-network-data-messages.md#inv) | Masternode broadcasts a `dstx` inventory message
| 13 | [`getdata` message](../reference/p2p-network-data-messages.md#getdata) (dstx) | → | | (Optional)

### Additional notes

_**Step 0 - Pool Selection**_

Expand All @@ -82,34 +91,34 @@ _**Step 1 - Pool Request**_
* This transaction uses a collateral [input](../resources/glossary.md#input) created in the [Wallet Preparation](#wallet-preparation) phase
* The collateral is a signed [transaction](../resources/glossary.md#transaction) that pays the collateral back to a client [address](../resources/glossary.md#address) minus a fee of 0.001 DASH

_**Step 3 - Queue**_

* A masternode broadcasts [`dsq` messages](../reference/p2p-network-privatesend-messages.md#dsq) when it starts a new queue. These message are relayed by all [peers](../resources/glossary.md#peer).
* As of protocol version 70214, sessions have a variable number of participants defined by the range `nPoolMinParticipants` ([3](https://github.com/dashpay/dash/blob/v0.15.0.0/src/chainparams.cpp#L360)) to `nPoolMaxParticipants` ([5](https://github.com/dashpay/dash/blob/v0.15.0.0/src/chainparams.cpp#L361)). Prior protocol version sessions always contained exactly 3 participants. Spork 22 introduced in Dash Core 0.16.0 expanded the maximum number of participants to 20 and also reduced the minimum number of participants to 2 for testnet/devnet/regtest networks. The spork was removed in Dash Core 0.17.0 which made the change permanent.
* The masternode sends a [`dsq` message](../reference/p2p-network-privatesend-messages.md#dsq) with the ready bit set once it has received valid [`dsa` messages](../reference/p2p-network-privatesend-messages.md#dsa) from either:
1. The maximum number of clients (20)
2. Greater than the minimum number of clients (3) and the timeout has been reached ([30 seconds](https://github.com/dashpay/dash/blob/v0.16.x/src/privatesend/privatesend.h#L23))
_**Steps 3-5 - Queue**_

:::{attention}
Clients must respond to the Queue ready within 30 seconds or risk forfeiting the collateral they provided in the [`dsa` message](../reference/p2p-network-privatesend-messages.md#dsa) (Step 1) ([Dash Core Reference](https://github.com/dashpay/dash/blob/v0.16.x/src/privatesend/privatesend.h#L23))
Clients must respond to the Queue ready within 30 seconds or risk forfeiting the collateral they provided in the [`dsa` message](../reference/p2p-network-privatesend-messages.md#dsa) (Step 1) ([Dash Core Reference](https://github.com/dashpay/dash/blob/v21.1.x/src/coinjoin/coinjoin.h#L43))
:::

_**Step 4 - Inputs**_
* When a masternode starts a new queue, it broadcasts an inventory message notifying all [peers](../resources/glossary.md#peer) of an available [`dsq` message](../reference/p2p-network-privatesend-messages.md#dsq). Interested clients can then request the full `dsq` message. Prior to protocol version 70234, `dsq` messages were directly relayed to all peers.
* Sessions have a variable number of participants defined by the range `nPoolMinParticipants` ([3](https://github.com/dashpay/dash/blob/v21.1.x/src/chainparams.cpp#L298) for mainnet, 2 for other networks) to `nPoolMaxParticipants` ([20](https://github.com/dashpay/dash/blob/v21.1.x/src/chainparams.cpp#L299)).
* The masternode sends an inventory message for a [`dsq` message](../reference/p2p-network-privatesend-messages.md#dsq) with the ready bit set once it has received valid [`dsa` messages](../reference/p2p-network-privatesend-messages.md#dsa) from either:
1. The maximum number of clients
2. Greater than the minimum number of clients and the timeout has been reached ([30 seconds](https://github.com/dashpay/dash/blob/v21.1.x/src/coinjoin/coinjoin.h#L43))

_**Step 6 - Inputs**_

* The collateral transaction can be the same in the [`dsi` message](../reference/p2p-network-privatesend-messages.md#dsi) as the one in the [`dsa` message](../reference/p2p-network-privatesend-messages.md#dsa) (Step 1) as long as it has not been spent
* Each client can provide up to 9 (`COINJOIN_ENTRY_MAX_SIZE`) inputs (and an equal number of outputs) to be used ([Dash Core Reference](https://github.com/dashpay/dash/blob/v0.15.0.0/src/privatesend/privatesend.h#L29))
* Each client can provide up to 9 (`COINJOIN_ENTRY_MAX_SIZE`) inputs (and an equal number of outputs) to be used ([Dash Core Reference](https://github.com/dashpay/dash/blob/v21.1.x/src/coinjoin/coinjoin.h#L46))
* This is the only message in the process that contains enough information to link a wallet's CoinJoin inputs with its outputs
* This message is sent directly between a client and the masternode processing the session (not relayed across the Dash network) so no other clients see it

_**Step 6 - Final Transaction (unsigned)**_
_**Step 8 - Final Transaction (unsigned)**_

* Once the masternode has received valid [`dsi` messages](../reference/p2p-network-privatesend-messages.md#dsi) from all clients, it creates the final transaction and sends a [`dsf` message](../reference/p2p-network-privatesend-messages.md#dsf)
* Inputs/outputs are ordered deterministically as defined by [BIP-69](https://github.com/dashevo/bips/blob/master/bip-0069.mediawiki#Abstract) to avoid leaking any data ([Dash Core Reference](https://github.com/dashpay/dash/blob/v0.15.0.0/src/privatesend/privatesend-server.cpp#L271-L272))
* Clients must sign their inputs to the Final Transaction within 15 seconds or risk forfeiting the collateral they provided in the [`dsi` message](../reference/p2p-network-privatesend-messages.md#dsi) (Step 4) ([Dash Core Reference](https://github.com/dashpay/dash/blob/v0.15.0.0/src/privatesend/privatesend.h#L24))
* Inputs/outputs are ordered deterministically as defined by [BIP-69](https://github.com/dashevo/bips/blob/master/bip-0069.mediawiki#Abstract) to avoid leaking any data ([Dash Core Reference](https://github.com/dashpay/dash/blob/v21.1.x/src/coinjoin/server.cpp#L301-L302))
* Clients must sign their inputs to the Final Transaction within 15 seconds or risk forfeiting the collateral they provided in the [`dsi` message](../reference/p2p-network-privatesend-messages.md#dsi) (Step 4) ([Dash Core Reference](https://github.com/dashpay/dash/blob/v21.1.x/src/coinjoin/coinjoin.h#L44))

_**Step 10 - Final Transaction broadcast**_
_**Step 12 - Final Transaction broadcast**_

* Prior to protocol version 70213, masternodes could only send a single un-mined [`dstx` message](../reference/p2p-network-privatesend-messages.md#dstx) at a time. As of protocol version 70213, up to 5 (`MASTERNODE_MAX_MIXING_TXES`) un-mined [`dstx` messages](../reference/p2p-network-privatesend-messages.md#dstx) per masternode are allowed. ([Dash Core Reference](https://github.com/dashpay/dash/blob/v0.15.0.0/src/masternode/masternode-meta.h#L16))
As of protocol version 70213, up to 5 (`MASTERNODE_MAX_MIXING_TXES`) un-mined [`dstx` messages](../reference/p2p-network-privatesend-messages.md#dstx) per masternode are allowed. ([Dash Core Reference](https://github.com/dashpay/dash/blob/v21.1.x/src/masternode/meta.h#L21))

_**General**_

Expand All @@ -119,8 +128,8 @@ _**General**_

**Processing Fees**

* If processing completes successfully, Dash Core charges the collateral randomly in 1/10 denominate transactions to pay miners ([Dash Core Reference](https://github.com/dashpay/dash/blob/v0.17.0.0/src/coinjoin/coinjoin-server.cpp#L427-L444))
* Clients that abuse the system by failing to respond to [`dsq` messages](../reference/p2p-network-privatesend-messages.md#dsq) or [`dsf` messages](../reference/p2p-network-privatesend-messages.md#dsf) within the timeout periods may forfeit their collateral. Dash Core charges the abuse fee in 1/3 cases ([Dash Core Reference](https://github.com/dashpay/dash/blob/v0.17.0.0/src/coinjoin/coinjoin-server.cpp#L357-L374))
* If processing completes successfully, Dash Core charges the collateral randomly in 1/10 denominate transactions to pay miners ([Dash Core Reference](https://github.com/dashpay/dash/blob/v21.1.x/src/coinjoin/server.cpp#L432-449))
* Clients that abuse the system by failing to respond to [`dsq` messages](../reference/p2p-network-privatesend-messages.md#dsq) or [`dsf` messages](../reference/p2p-network-privatesend-messages.md#dsf) within the timeout periods may forfeit their collateral. Dash Core charges the abuse fee in 1/3 cases ([Dash Core Reference](https://github.com/dashpay/dash/blob/v21.1.x/src/coinjoin/server.cpp#L363-L381))

**Sending Fees**

Expand Down
1 change: 1 addition & 0 deletions docs/reference/p2p-network-data-messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ The currently-available type identifiers are:
| 28 | MSG_QUORUM_RECOVERED_SIG | The hash is a long-living masternode quorum recovered signature. <br><br>**Note**: Only relayed to other masternodes in the same quorum and nodes that have sent a [`qwatch` message](../reference/p2p-network-quorum-messages.md#qwatch) as of Dash Core 0.17.0<br>_Added in 0.14.0_
| 29 | MSG_CLSIG | The hash is a ChainLock signature.<br>_Added in 0.14.0_
| 31 | MSG_ISDLOCK | The hash is an LLMQ-based deterministic InstantSend lock ([DIP22](https://github.com/dashpay/dips/blob/master/dip-0022.md)).<br>_Added in 18.0_
| 32 | MSG_DSQ | The hash of a CoinJoin [dsq message](./p2p-network-privatesend-messages.md#dsq).<br>**Added in 22.0.0**

**Deprecated Type Identifiers**

Expand Down
9 changes: 8 additions & 1 deletion docs/reference/p2p-network-privatesend-messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,13 @@ User outputs

## dsq

:::{attention}
Since protocol version 70234 (Dash Core 22.0.0), the [`dsq`
message](../reference/p2p-network-privatesend-messages.md#dsq) is broadcast using the inventory
system instead of being relayed to all connected peers. This reduces the bandwidth needs for all
nodes, especially highly connected masternodes.
:::

The [`dsq` message](../reference/p2p-network-privatesend-messages.md#dsq) provides [nodes](../resources/glossary.md#node) with queue details and notifies them when to sign final transaction messages.

If the message indicates the queue is not ready, the node verifies the message is valid. It also verifies that the [masternode](../resources/glossary.md#masternode) is not flooding the [network](../resources/glossary.md#network) with [`dsq` messages](../reference/p2p-network-privatesend-messages.md#dsq) in an attempt to dominate the queuing process. It then relays the message to its connected [peers](../resources/glossary.md#peer).
Expand All @@ -319,7 +326,7 @@ If the message indicates the queue is ready, the node responds with a [`dsi` mes
| 1 | fReady | bool | Required | Indicates if the pool is ready to be executed
| 97 | vchSig | char[] | Required | BLS Signature of this message by masternode verifiable via pubKeyMasternode (Length (1 byte) + Signature (96 bytes))<br>**Note**: serialized using the basic BLS scheme after Dash 19.0 activation

Denominations (per [`src/coinjoin.cpp`](https://github.com/dashpay/dash/blob/v0.16.x/src/privatesend/privatesend.cpp#L316-L336))
Denominations (per [`src/coinjoin/common.h`](https://github.com/dashpay/dash/blob/v21.0.x/src/coinjoin/common.h#L38-L44))

| Value | Denomination
|------|--------------
Expand Down