From 5a4cfba25a8da592c50e9b03bf270464457d1bf3 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Tue, 21 May 2019 18:09:31 +0200 Subject: [PATCH] Multiple updates to DIP8 (#44) * Update DIP8 to use "blockHeight" instead of prevBlockHash in request ids This prevents conflicting CLSIGs on temporary chain splits. The code was already using the block height, but the DIP was never updated. * Add "Used LLMQ type" section to DIP8 * Describe safe transactions in DIP8 * Update dip-0008.md * Review suggestions from thephez --- dip-0008.md | 69 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/dip-0008.md b/dip-0008.md index ce3dbd1..dddf135 100644 --- a/dip-0008.md +++ b/dip-0008.md @@ -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) @@ -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 @@ -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 @@ -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 | @@ -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