diff options
author | Paul Sztorc <psztorc01@gmail.com> | 2018-02-10 17:23:31 -0500 |
---|---|---|
committer | Paul Sztorc <psztorc01@gmail.com> | 2018-02-10 17:23:31 -0500 |
commit | 70f0ed6c39bec8d50ae29a2b2b562b44d84df5b7 (patch) | |
tree | b1dd025eb5ae1f7024e94f08b1ebfe0cfb69bb4f | |
parent | 68918ad24a568a302bf6e54932a38d3b73ec3d65 (diff) |
switch to mediawiki format
-rw-r--r-- | bip-blind-merged-mining.mediawiki (renamed from bip-blind-merged-mining.md) | 113 |
1 files changed, 57 insertions, 56 deletions
diff --git a/bip-blind-merged-mining.md b/bip-blind-merged-mining.mediawiki index f203e40..3aaf81b 100644 --- a/bip-blind-merged-mining.md +++ b/bip-blind-merged-mining.mediawiki @@ -1,12 +1,5 @@ - Drivechain Documentation -- Blind Merged Mining BIP - Paul Sztorc - November 17, 2017 - Document 3 of 3 - v4.1 - -Header -======= +<pre> BIP: ???? Layer: Consensus (soft fork) @@ -21,40 +14,43 @@ Header Created: 2017-10-24 License: BSD-2-Clause +</pre> + + +==Abstract== -Abstract -========== Blind Merged Mining (BMM) is a way of mining special extension blocks, ie "sidechains". It produces strong guarantees that the block is valid, for *any* arbitrary set of rules; and yet it does so without requiring miners to actually do any validation on the block whatsoever. BMM actually is a process that spans two or more chains. For an explanation of the "whole picture", please see [this post](http://www.truthcoin.info/blog/blind-merged-mining/). Here we focus on the modifications to mainchain Bitcoin. To support BMM, the mainchain is asked to accomplish two goals: -1. Track a set of ordered hashes (the merged-mining). -2. Allow miners to "sell" the act of finding a sidechain block (through the use of a new extended serialization transaction type). + +# Track a set of ordered hashes (the merged-mining). +# Allow miners to "sell" the act of finding a sidechain block (through the use of a new extended serialization transaction type). These goals are accomplished by forcing nodes to validate two new messages (M7, M8), and track data in one new database (D3). -Motivation -============ +==Motivation== + Regular "Merged-Mining" (MM) allows miners to reuse their hashing work to secure other chains (for example, as in Namecoin). However, traditional MM has two drawbacks: -1. Miners must run a full node of the other chain. (This is because [while miners can effortlessly create the block] miners will not create a valid payment to themselves, unless the block that they MM is a valid one. Therefore, miners must assemble a *valid* block first, then MM it.) -2. Miners are paid on the other chain, not on the regular BTC mainchain. For example, miners who MM Namecoin will earn NMC (and they will need to sell the NMC for BTC, before selling the BTC in order to pay for electricity). +# Miners must run a full node of the other chain. (This is because [while miners can effortlessly create the block] miners will not create a valid payment to themselves, unless the block that they MM is a valid one. Therefore, miners must assemble a *valid* block first, then MM it.) +# Miners are paid on the other chain, not on the regular BTC mainchain. For example, miners who MM Namecoin will earn NMC (and they will need to sell the NMC for BTC, before selling the BTC in order to pay for electricity). Blind Merged-Mining (BMM) attempts to address those shortcomings. -Specification -============ +==Specification== + Note: This document uses the notation side:\* and main:\* in front of otherwise-ambiguous words (such as "block", "node", or "chain"), to distinguish the mainchain version from its sidechain counterpart. As stated above, we have two goals: [1] create and monitor an alt-chain (defined only by a deterministic list of hashes), and [2] allow miners to "sell" the act of finding a sidechain block (through the use of a new extended serialization transaction type). -### Sidechain Critical Data ("Sidechain Mini-Header") +=== Sidechain Critical Data ("Sidechain Mini-Header") === Specifically, per side:block per side:chain, we track the following 35 bytes of information: @@ -66,9 +62,9 @@ The **ChainIndex** indicates which sidechain this critical data is relevant to. Where does this data come from, and how does it get around? -#### Creating / Broadcasting This Data +==== Creating / Broadcasting This Data ==== -##### Creation +===== Creation ===== By the time Blind Merged Mining can take place, the ChainIndex is globally known (it is the "Account Number" in D1 [see previous BIP], and "nSidechain" in the code). Each sidechain, when activated by soft fork, will take one of the 0-255 available indexes. @@ -76,17 +72,17 @@ The other two items, sideHeaderHash and prevBlockRef, are created by sidechain n The final item, prevBlockRef, is a little more complicated. It is an integer that counts the number of "skips" one must take in the side:chain in order to find the current side:block's parent block. In practice, this value will usually be zero. It will only be a value other than zero, in cases where invalid sidechain blocks have been mined, or when a side:node intentionally wants to orphan some side:blocks (if a side:node wants to orphan the most-recent N blocks, the value of the current block will be equal to N ; in the block after that it will be back to zero). -![dots-image](/bip-blind-merged-mining/bmm-dots-examples.png?raw=true) +<img src="bip-blind-merged-mining/bmm-dots-examples.png?raw=true" align="middle"></img> Since the hashes themselves are already ordered by the mainchain, tracing the blockchain's path by index (prevBlockRef) will be the same as tracing it by identifying a list of hashes. In other words, the ordering given via each side:block's "prevBlockRef" will be isomorphic to an ordering given by each side:block's "prevSideHeaderHash" ... if "prevSideHeaderHash is defined to be the sidechain's equivalent of the mainchain's "prevBlockHash". It will be possible to freely convert from one to the other. See M8 to learn more about how these hashes are requested by sidechain block creators to be included in the mainchain. Now that we know what our critical data is, and how it is made, how is this data broadcast and stored? -##### Broadcast +===== Broadcast ===== Mainchain nodes are going to need this data later, so it must be easy to find. We will put it into the coinbase via OP RETURN. -#### M7 -- "Blind-Mine the Sidechain(s)" +==== M7 -- "Blind-Mine the Sidechain(s)" ==== Thus, (for n sidechains) we have a coinbase output with: @@ -103,7 +99,7 @@ Each 37-byte chunk is then parsed to obtain the data outlined above (in "Descrip We are left with, at most, one (h*, prevBlockRef) pair per sidechain per block. This data is added directly to D3, a new database. -#### D3 -- "RecentSidechains_DB" +==== D3 -- "RecentSidechains_DB" ==== To suit our purposes, the mainchain full nodes will need to keep track of the most recent 8000 (h\*, prevBlockRef) pairs. @@ -112,6 +108,7 @@ To suit our purposes, the mainchain full nodes will need to keep track of the mo Therefore, D3 would look something like this: +<pre> BlockHeight CB_Index SC_1 Blks_Atop_1 SC 2 Blks_Atop_2 SC 3 Blks_Atop_3 --------- ------ ------ --------- ------ --------- ------ --------- 1. 401,005 2 (h*, 0) 7985 (h*, 0) 1 (h*, 0) 0 @@ -121,6 +118,7 @@ Therefore, D3 would look something like this: ... ... ) 7999. 409,003 3 (h*, 0) 1 (h*, 0) 0 (h*, 0) 1 8000. 409,004 2 (h*, 0) 0 (h*, 1) 0 (h*, 0) 0 +</pre> When new sidechains (or "hashrate escrows") are soft-forked into existence, a new column is added to D3 (to contain any BMMing that might be done on it). @@ -130,38 +128,38 @@ For each sidechain we also track the field "Blocks Atop". This is the number of D3 also contains a column (not shown) for each sidechain containing "prevSideBlockHash". This value is is either derived from prevBlockRef; or else it is given explicitly (in which case it is the converse: prevBlockRef is derived from prevSideBlockHash). -#### Coinbase Cache +==== Coinbase Cache ==== As mentioned above, M7s cause data to be added to D3. Recent D3 data is tracked by all mainchain nodes for a period of time. To efficiently keep track of the above data, without having to constantly load and process entire blocks from disk, we temporarily cache enough coinbases in the chain index to maintain D3. -### M8 -- Paying miners to include BMM data in their coinbase outputs +=== M8 -- Paying miners to include BMM data in their coinbase outputs === This section introduces a new type of transaction, which allows sidechain block creators to request, and pay for, a critical hash to be included in a specific block by mainchain miners. See [the Blind Merged Mining spec](http://www.truthcoin.info/blog/blind-merged-mining/). This txn allows miners to "sell" the act of mining a sidechain block. By taking advantage of this option, miners earn tx fees for mining sidechains...truly "for free". They do not even need to run sidechain nodes, and the tx-fees they earn are in mainchain BTC. As a result, sidechains affect all miners equally and do not affect the mining ecosystem. M8 will ultimately come in two versions. The second version will be specialized for use in the Lightning Network and must use the full 32-byte prevBlockHash (ironically, this larger transaction is cheaper for the Bitcoin network to process, as it is completely off-chain). The first version of M8, in contrast, cannot be used inside the Lightning Network, but is slightly more space-efficient (using the 2 prevBlockRef bytes to maintain chain order). It is important to make both options available to the user, because some side:nodes may be unwilling or unable to open a payment channels with each main:miner. However, in the long run we expect the lightning version to be preferred. -#### Setup +==== Setup ==== We define **"Mary"** as a mainchain miner, and **"Simon"** as a sidechain node. The goal is to construct a payment from Simon to Mary, such that: -1. If the critical data conditions are met, **Mary** can claim the outputs of the transaction with finality. -2. If the critical data conditions are not met, the outputs become immediately available again to **Simon**. +# If the critical data conditions are met, **Mary** can claim the outputs of the transaction with finality. +# If the critical data conditions are not met, the outputs become immediately available again to **Simon**. -#### Goals (this is rather philosophical, and skippable) +==== Goals (this is rather philosophical, and skippable) ==== -##### Immediate Expiration ("Fill-or-Kill") +===== Immediate Expiration ("Fill-or-Kill") ===== We would like to make special guarantees to the counterparties of this transaction. Specifically, instead of Simon making a "payment" to Mary, we prefer that Simon give Mary an "offer" (which she can either accept or decline). Crucially, we want Simon to safely make many offers to several different Mary's, in realtime (ie, quickly and off-chain). However, we ultimately want only one offer to be accepted, at most. In other words, we want Simon's offers to *immediately expire*. If only one offer can become a bona fide transaction, then Simon will feel comfortable making offers all day long. Because all of the Simons are making many offers, the Marys collectively gain access to a large set of offers to choose from. -##### Forward Progress (The Need for a "Ratchet") +===== Forward Progress (The Need for a "Ratchet") ===== The "ratchet" concept is an attempt to harmonize incentives among the main and side chain(s). We need to ensure that a sidechain is making "forward progress", without tracking too much about the sidechain such that we burden Bitcoin (see [1] and [2]) all while still allowing the sidechain to reorganize [3]. @@ -174,8 +172,8 @@ The ratchet system must keep track of sidechain "mini-headers" (see Sidechain Cr Simon's offer to Mary to include a critical hash in exchange for payment must be *atomic*. The "ratchet" concept helps to construct a very tight connection between two things: -1. The sidechain-block-generator "Simon" paying himself the side:block's side:tx-fees (which he receives in 100 sidechain blocks (blocks atop) hence). -2. "Simon" making a mainchain main:btc payment to a mainchain miner "Mary". +# The sidechain-block-generator "Simon" paying himself the side:block's side:tx-fees (which he receives in 100 sidechain blocks (blocks atop) hence). +# "Simon" making a mainchain main:btc payment to a mainchain miner "Mary". Either both of the two should succeed, or else both should jointly fail. @@ -184,13 +182,13 @@ However, absent our intervention, there are cases in which [2, the payment to Ma To address these potential issues, we utilize the concept of "Blocks_Atop" (the "side:confirmations") that we mentioned earlier. As previously mentioned, Mary will not be able to spend Simon's M8 payment until satisfying the critical data requirements as well as the blocks atop (side:confirmations) requirement. -#### M8 -- The two forms of M8 transactions +==== M8 -- The two forms of M8 transactions ==== As previously mentioned, M8 can take two forms. The first does not require the Lightning Network, but it does have new requirements for Immediate Expiration (see above). The second inherits Immediate Expiration from the Lightning Network itself, but requires extra preparation and a different/larger message. Both forms require that certain Critical Data will be committed to within the coinbase of the block that the transaction is included in. For the non Lightning version, we have created a new extended serialization transaction type (very similar to how segwit handles witness data (the witness stack)). -##### M8_V1 - No Lightning Network +===== M8_V1 - No Lightning Network ===== M8_V1 does not require the Lightning network but does have new requirements for validation. @@ -207,26 +205,25 @@ In the first version of M8, we need to introduce the concept of Immediate Expira We do this by imposing validity-rules on the txn itself: -1. The txn's content, when examined, must match part of the main:block's content. Specifically, the (ChainIndex, h\*) pair of the txn, must match one of the (ChainIndex, h\*) pairs in the M7 of this main:block. -2. Only one payment per sidechain per main:block is valid. In other words, if 400 people all try to bm-mine the sidechain with ChainIndex==4, then not only is it the case that only one side_4:block can be found, but it is also the case that only the corresponding M8 txn can be included (out of all of the 400 M8s which are for ChainIndex==4). -3. Simon's txns must only be valid for the current block; afterward, they immediately expire. This is because Simon's intended prevBlockRef & side:block contents will most likely change from one main:block to the next. +# The txn's content, when examined, must match part of the main:block's content. Specifically, the (ChainIndex, h\*) pair of the txn, must match one of the (ChainIndex, h\*) pairs in the M7 of this main:block. +# Only one payment per sidechain per main:block is valid. In other words, if 400 people all try to bm-mine the sidechain with ChainIndex==4, then not only is it the case that only one side_4:block can be found, but it is also the case that only the corresponding M8 txn can be included (out of all of the 400 M8s which are for ChainIndex==4). +# Simon's txns must only be valid for the current block; afterward, they immediately expire. This is because Simon's intended prevBlockRef & side:block contents will most likely change from one main:block to the next. To impose new requirements on the transaction level (not the block level nor the TxOutput level), we borrow the "flag" trick from SegWit style transactions. If the flag is present, the transaction is examined for extra data, and if this data does not pass certain requirements, the transaction is invalid. With SegWit, this extra data is the signatures, and the extra requirements are the signatures' locations and validity. In the BMM-transactions, the extra data is the (ChainIndex, h\*) pair, which must meet the first two requirements (above) as well as the main:blocknumber, which must meet the third requirement (above). To impose new requirements at the transaction level, we borrow the dummy vin & "flag" trick from SegWit style transactions. If the flag is set to 2 (0010), the transaction contains Critical Data and requires that our new validation rules be met in order for the txn to be valid in a block. Unless all of the requirements for sidechain critical data transactions are met by the block it is included in, the transaction is invalid. With SegWit, this extra data is the segwit signature stack, and the extra requirements are the signatures' locations and validity. In the sidechain BMM critical data transactions, the extra data is the (ChainIndex, h\*) pair, which must meet the first two requirements (above) as well as the main:blocknumber, which must meet the third requirement (above). Note The main:blocknumber does not take up any additional space compared to a normal txn, as we reuse the locktime field for our purposes. +<img src="bip-blind-merged-mining/witness-vs-critical.png?raw=true" align="middle"></img> -![extra-data-image](/bip-blind-merged-mining/witness-vs-critical.png?raw=true) - This txn structure conserves main:blockspace, because it is the easiest way to refer to a previous sidechain block in 4 bytes, (prevBlockRef + FoK_nLockTime). Instead, we would need to use at least 32 bytes (prevSideBlockHash). These types of transactions have slightly different mempool behavior, and should probably be kept in a second mempool. These txns are received, checked immediately, and if valid they are evaluated for inclusion in a block. If they are not able to be included in the specific requested block (if the block height requested has been surpassed by the chain tip), they are discarded. In fact, after any main:block is found, everything in this "second mempool" can be discarded as new payments will be created immediately for the next block height. (This includes cases where the blockchain reorganizes.) There is no re-evaluation of the txns in this mempool ever -- they are evaluated once and then either included or discarded. To be clear, when the transaction is received we are able to evaluate its validity, and do not need to rescan these transactions again. Interestingly, these payments (M8) will *always* be directed to miners from non-miners. Therefore, non-mining nodes do not need to keep them in any mempool at all. Non-miner nodes can just wait for a block to be found, and check the txn then. These transactions more resemble a stock market's pit trades (in contrast, regular Bitcoin txns remind me more of paper checks). -##### M8_V2 With Lightning +===== M8_V2 With Lightning ===== M8_V2 requires having a LN-channel open with a miner. This may not always be practical (or even possible), especially today. @@ -242,7 +239,7 @@ A M8_V1 TxOut is expected to contain: Notice that, in M8_V1, Simon could reuse the same h\* all he wanted, because only one M8_V1 could be included per main:block per sidechain. However, on the LN no such rule can be enforced, as the goal is to push everything off-chain and include *zero* M8s. So, we will never know what the M8s were or how many had an effect on anything. -Therefore, Simon will need to ensure that he **gives each Mary a different h\***. Simon can easily do this, as he controls the side:block's contents and can simply increment a nonce -- this changes the side:block, and changes its hash (ie, changes h\*). +Therefore, Simon will need to ensure that he '''gives each Mary a different h\*'''. Simon can easily do this, as he controls the side:block's contents and can simply increment a nonce -- this changes the side:block, and changes its hash (ie, changes h\*). With a unique h\* per Mary, and at most 1 h\* making it into a block (per sidechain), we can guarantee that only one of the M8_V2's critical data can be committed to in a single main:block. By giving each miner (who Simon has a payment channel open with) a different h*, Simon can figure out which miner followed through with the commit, and know that only one such commit went through. Furthermore, if this Simon's requested critical data is not found in a block, none of the M8_V2 payments will be spendable by the Mary(s), because none of the h\* in question have ever made it into D3 (which is always on-chain) and no blocks atop will be accumulated. @@ -250,6 +247,7 @@ That's probably confusing, so here is an example, in which: Simon starts with 13 We start with (I): +<pre> Simon 13 in, Mary 40 in ; 53 in total Simon's version [signed by Mary] 13 ; to Simon if TimeLock=over; OR to Mary if SimonSig @@ -257,10 +255,12 @@ We start with (I): Mary's version [signed by Simon] 40 ; to me if TimeLock=over; OR to Simon if MarySig 13 ; to Simon +</pre> And both parties move, from there to "M8_V2" (II): +<pre> Simon 13 in, Mary 40 in ; 53 in total Simon's version [signed by Mary] 6 ; to Simon if TimeLock=over; OR to Mary if SimonSig @@ -270,9 +270,12 @@ And both parties move, from there to "M8_V2" (II): 40 ; to Mary if TimeLock=over; OR to Simon if MarySig 6 ; to Simon 7 ; to Mary if critical data requirements met; OR to Simon if LongTimeLock=over +</pre> + From here, if the h\* side:block in question is BMMed, they can proceed to (III): +<pre> Simon 13 in, Mary 40 in ; 53 in total Simon's version [signed by Mary] 6 ; to Simon if TimeLock=over; OR to Mary if SimonSig @@ -280,6 +283,7 @@ From here, if the h\* side:block in question is BMMed, they can proceed to (III) Mary's version [signed by Simon] 47 ; to me if TimeLock=over; OR to Simon if MarySig 6 ; to Simon +</pre> Although, if Simon proceeds immediately, he removes the protection of the 'ratchet'. Ie, Simon removes Mary's incentive to care about blocks being built on this side:block. If Simon's side:block is orphaned, he loses his 7 BTC. Simon can either play it safe, and wait the full 100 side:blocks before moving on (ie, moving on to the third LN txn, above); or else Simon can take the risk if he feels comfortable with it. @@ -288,28 +292,27 @@ If the h\* side:block is not found, then (II) and (III) are basically equivalent -Deployment -=========== +==Deployment== This BIP will be deployed by "version bits" BIP9 with the name "blindmm" and using bit 4. -``` +<pre> // Deployment of Drivechains (BIPX, BIPY) consensus.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS].bit = 4; consensus.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS].nStartTime = 1515974401; // January 15th, 2018. consensus.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS].nTimeout = 1547510401; // January 15th, 2019. -``` +</pre> -Reference Implementation -========================== + +==Reference Implementation== See: https://github.com/drivechain-project/bitcoin/tree/mainchainBMM Also, for interest, see an example sidechain here: https://github.com/drivechain-project/bitcoin/tree/sidechainBMM -References -============ +==References== + * http://www.drivechain.info/literature/index.html * http://www.truthcoin.info/blog/blind-merged-mining/ @@ -317,13 +320,11 @@ References * http://www.truthcoin.info/images/bmm-outline.txt -Thanks -========= +==Thanks== Thanks to everyone who contributed to the discussion, especially: ZmnSCPxj, Adam Back, Peter Todd, Dan Anderson, Sergio Demian Lerner, Matt Corallo, Sjors Provoost, Tier Nolan, Erik Aronesty, Jason Dreyzehner, Joe Miyamoto, Ben Goldhaber. -Copyright -========== +==Copyright== This BIP is licensed under the BSD 2-clause license. |