Skip to content
Merged
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
69 changes: 55 additions & 14 deletions dip-0008.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
1. [Abstract](#abstract)
1. [Motivation](#motivation)
1. [Prior Work](#prior-work)
1. [Used LLMQ type](#used-llmq-type)
1. [Safe transactions](#safe-transactions)
1. [Signing attempts](#signing-attempts)
1. [Finalization of signed blocks](#finalization-of-signed-blocks)
1. [Handling of signed blocks](#handling-of-signed-blocks)
Expand Down Expand Up @@ -88,14 +90,56 @@ when receiving funds and removing the possibility of 51% mining attacks.
- [DIP 006: Long Living Masternode Quorums](https://github.com/dashpay/dips/blob/master/dip-0006.md)
- [DIP 007: LLMQ Signing Requests / Sessions](https://github.com/dashpay/dips/blob/master/dip-0007.md)

## Used LLMQ type

All signing sessions/requests involved in ChainLocks must use the LLMQ_400_60 LLMQ type.

## Safe transactions

In general, all valid blocks could also be considered for ChainLocks. There is a small
risk of confirmed transactions conflicting with InstantSend locks. To resolve these conflicts,
ChainLocks need to be prioritized over InstantSend locks when conflicts arise.

As such conflict resolution is quite severe and in some sense voids all the security gained
by InstantSend, it is desirable to reduce the probability of such conflicts to practically zero.

This can be achieved by a change in block template generation. Miners are encouraged to only
include “safe” transactions in blocks. A transaction is considered safe if it is InstantSend
locked or locally known for at least 10 minutes without a conflicting InstantSend lock
appearing in the meantime. The default implementation for block template generation
(as found in Dash Core) will be changed to honor this.

At the same time, masternodes should only try to sign/lock blocks which include only "safe"
transactions. This means that ChainLocks will only be created when the whole block
is considered "safe". Consequently, the probability of a conflicting InstantSend lock
appearing after the creation of the ChainLock is practically zero.

This assumes that [DIP-0010 LLMQ based InstantSend](https://github.com/dashpay/dips/blob/master/dip-0010.md)
is already implemented as it changes InstantSend behaviour to try to lock all transactions
instead of just a few selected ones.

DIP-0010 also implements "retroactive signing of transactions", which guarantees that transactions
are InstantSend locked in a retroactive way if they were unknown before appearing in a
mined block. This prevents blocks which contain unlocked transactions from suppressing
ChainLocks, as it allows the ChainLocks system to sign blocks retroactively as well.

## Signing attempts

When a new valid block is received by a masternode, it must invoke the [DIP007
Each masternode should periodically try to sign the current chain tip. When the tip already has a valid
ChainLock, this can be skipped.

Before actually signing the tip, each masternode should check if all transactions contained in all blocks
between the last ChainLocked block and the current chain tip are "safe" (see previous section). This check
should be limited to a depth of 6 blocks in case there is no known previous ChainLock or if the previous
ChainLock is deeper than 6 blocks.

When these checks pass, each masternode must invoke the [DIP0007
`SignIfMember` operation](https://github.com/dashpay/dips/blob/master/dip-0007.md#void-signifmemberuint256-id-uint256-msghash-int-activellmqs).

The request id for the operation is `hash(prevBlockHash, attemptNum)` and the
The request id for the operation is `hash("clsig-attempt", blockHeight, attemptNum)` and the
message hash is the hash of the new block (`newBlockHash`). The first time this
is attempted, `attemptNum` must be set to `0`.
is attempted, `attemptNum` must be set to `0`. "clsig-attempt" is a static string that
must be prepended by its length (13, as a compactSize uint).

In most cases, the majority of the LLMQ will sign the same message hash in the
first attempt and thus find consensus. This can be checked with the [DIP007
Expand All @@ -122,10 +166,10 @@ consensus has been reached.
## Finalization of signed blocks

After a signing attempt has succeeded, another LLMQ must sign the successful
attempt. This is only performed once for each `prevBlockHash` and thus either
attempt. This is only performed once for each `blockHeight` and thus either
succeeds or fails without performing additional attempts.

The request id is `prevBlockHash` and the message hash is the block hash of the
The request id is `hash("clsig", blockHeight)` and the message hash is the block hash of the
previously successful attempt.

After a LLMQ member has successfully recovered the final ChainLocks
Expand All @@ -134,7 +178,7 @@ message is called `CLSIG` and has the following structure:

| Field | Type | Size | Description |
|--|--|--|--|
| prevBlockHash | uint256 | 32 | Hash of the previous block |
| height | int32 | 4 | Height of the signed block |
| blockHash | uint256 | 32 | Hash of the signed block from the successful attempt |
| sig | BLSSig | 96 | Recovered signature |

Expand All @@ -143,14 +187,11 @@ This message is propagated through the inventory system.
Upon receipt, each node must perform the following verification before
announcing it to other nodes:

1. `prevBlockHash` must refer to a block that is part of any locally known
chain
2. Based on the deterministic masternode list at the chain height of
`prevBlockHash`, a quorum must be selected that was active at the time this
block was mined
3. The signature must verify against the quorum public key and
`hash(llmqType, quorumHash, prevBlockHash, blockHash)`. `llmqType` and `quorumHash`
must be taken from the quorum selected in 2.
1. Based on the deterministic masternode list at the given height, a quorum must be
selected that was active at the time this block was mined
2. The signature must verify against the quorum public key and
`hash(llmqType, quorumHash, hash(height), blockHash)`. `llmqType` and `quorumHash`
must be taken from the quorum selected in 2.


## Handling of signed blocks
Expand Down