Subject: Re: [bitcoin-dev] BIP: OP_BRIBVERIFY - the op code needed for Blind Merge Mined drivechains

From: Chris Stewart <[email-masked]>
Date: Tue, 4 Jul 2017 10:06:06 -0500

Hi ZmnSCPxj,

In my scheme, if you read carefully through the pseudocode, a block list
> node is valid only if its block is valid.
>

It seems this is a contradiction against the "blind" part of blind merge
mining. How can a bitcoin blockchain node enforce this without tracking the
sidechain?

Basically, in my scheme, the OP_RETURN data *is* the sidechain block
> headers stored on the mainchain.  To save space, the sidechain block
> headers are reduced to only the previous-block-header commitment and the
> current-block-data commitment.  All of the other data you would want to put
> in the block header (e.g. UTXO set commitment, signalling bits,
> time-of-day...) would be part of the current-block-data instead of the
> block header.  Thus if the current-block-data is invalid the sidechain
> block header is invalid and another sidechain block header based on the
> previous block header will be searched for.

It seems both of our schemes need to include 2 32 bit hashes in the
blockchain. Your scheme needs a previous block header hash and the current
block header hash, while mine includes the current block header hash
twice.  We can just commit to all that information via the block header
hash and if a sidechain node lies to us will we are doing IBD the hashes
won't match with what was included in the bitcoin blockchain.

I'll follow your discussion with Paul about sidechain reorgs, but I think
his proposal is more desirable -- it follows what actually happens in the
bitcoin mining process where we *can* have chain splits when miners
simultaneously find a block. Other miners will pick one of the two blocks
to mine on top of and eventually one chain will become longer than the
other. Therefore that chain will have it's block's orphaned and the
miners/nodes following the dead chain will reorg on top of the longest
chain.

In Paul's scheme, we replace PoW with a bribe. At the conceptual level
these are somewhat similar. In PoW a miner is willing to pay a certain
amount of money (on electricity) to try to find a bitcoin block. With
OP_BRIBEVERIFY a sidechain miner is willing pay a certain amount of money
to find a block.

In PoW, there is nothing at the software level that says a miner cannot
just decide to build on a old block. I could decide to build on the genesis
block if I wanted to. Obviously this is a stupid idea as I'll never
overtake the bitcoin blockchain with 8 years of PoW behind it -- but it
doesn't mean I couldn't try if I wanted too. Your scheme from what I
understand prevents this from happening -- and I don't think that is
desirable. You might be able to make an argument that a rich attacker can
*stall* mining progress on the drivechain, but I think the same argument
can be made with a rich miner on the bitcoin blockchain as well. I think
miners have threatened to do that if BIP148 caused a chain split.

Can you link to the aforementioned pseudocode? I must have missed it on the
mailing list.

-Chris

On Tue, Jul 4, 2017 at 2:21 AM, ZmnSCPxj <[email-masked]> wrote:

> Good morning Paul, Chris, and CryptAxe,
>
> @Paul
>
> >> >Your way is actually very similar to mine. Mine _forces_ the bribe to
> be
> >> >in the earliest txn (the coinbase) and to only occur once. Yours
> doesn"t
> >> >do anything to refund the briber, if the sidechain (but not the
> >> >mainchain) reorganizes (as it can easily do, if an older sidechain
> >> >parent is extended while the mainchain proceeds normally). This creates
> >> >additional risk.
> >>
> >> I don"t understand this part. In my scheme, a sidechain cannot
> >> reorganize unless the mainchain reorganizes, since the consensus loop
> >> only cares about matching the current block; it ignores splits and
> >> does not consider them valid.
> >
> >If I"ve understood you correctly, you have said that each OP Return
> >links the (ex)-latest block to a brand new block, and that whichever
> >message of this kind comes first (in the mainchain) wins and the rest
> >are discarded.
> >
> >So what if I had a sidechain represented by a jumble of capital letters,
> >discarded entries as lowercase letters.
> >
> >Mainchain Block #200001: [0 --> Q], [0 -->v], [0 -->s], [0 -->b],
> >Mainchain Block #200002: [Q --> H], [Q --> z],
> >Mainchain Block #200003: [H --> F]
> >Mainchain Block #200004: [F --> J], [F -->w]
> >Mainchain Block #200005: [H --> P], [J -->x]
> >Mainchain Block #200006: [P --> D]
> >
> >Isn"t the chain {{ Q --> H --> F --> J }} now starting to reorg, with a
> >competing chain {{ Q --> H --> P --> D }} ?
>
> No, because at block #20005, the topmost sidechain block is J, not H, and
> the H->P will not be considered as valid -- only the J->x is valid, even
> though H->P comes first.
>
> Please see the pseudocode I sent before in detail and consider how it will
> work with your given mainchain blocks example.
>
>
> >> But I suppose you are considering something like the Ethereum
> >> mutability feature, which I do not think is something you would want
> >> in a sidechain.
> >
> >What I do want to do, is retain the existing model to some extent.
> >Specifically, to the degree where sidechains could salvage some bad
> >situations (eg value overflow incident, or March 2013 incident).
>
> I suppose some kinds of mutability are desirable.  In my model, a
> sidechain reorg can be forced if the sidechain code is forked to
> specifically force some previously-valid block to become invalid, by
> developer fiat.  In the example you gave, basically, if you want to reorg
> from Q->H->F->J to Q->H->P->D then you would fork the sidechain consensus
> code to declare that block F is invalid.
>
> I am hesitant to make mutability something that is easy to force, however.
>
> >> >I think mine is also much more space-efficient. Even if ours each had
> >> >exactly one h* per sidechain per block, it seems that I only require
> one
> >> >hash to be communicated (plus an indicator byte, and a ~2 byte counter
> >> >for the ratchet), whereas you require two. Since its overhead per
> >> >sidechain per block, it actually might really add up.
> >>
> >> Do you not provide a single sidechain"s h* twice in the block? Once
> >> in the coinbase and once in the briber"s separate transaction?
> >
> >That is a good point. Technically, we do include it twice, but the
> >second instance (briber-transaction) can be "shuffled" out if the
> >counterparties are part of the same Lightning Network (which I expect to
> >the be the case, in equilibrium).
>
> Payments on LN are finalized when the payee provides a preimage for a
> hashlock, whether by chain or by LN.  Although I suppose you can use a
> bribelocked timelocked contract instead of a hashlocked timelocked
> contract.  I suppose it would be almost the same, except the bribelock is
> provided off-chain as a proof of existence in a mainblock coinbase.
>
> In addition, it may be possible to create a payment channel specifically
> between a sidechain operator and a mainchain miner.
>
> >> In my scheme at least there is no indicator byte -- the "previous
> >> block" hash is the indicator of which sidechain it is extending. From
> >> your other emails on this list, it seems the ratchet is for
> >> withdrawals from sidechain to mainchain? If so, should it not only
> >> appear in only some of the sidechains (the ones which are currently
> >> doing some withdrawal?)?
> >
> >No, sorry. There are many tangled issues (Drivechain (total system);
> >side-to-main withdrawals (OP CountACKs); individual Drivechains
> >themselves; Blind Merged Mining (OP BribeVerify)). The ratchet is not
> >about withdrawals, it is exclusively about Blind Merged Mining, and
> >making a better OP BribeVerify that offers better guarantees to both
> sides.
>
> Can you describe the ratchet better?  I am sorry but when I first heard of
> "blind" merge mining, the first thing that came to mind was the use of
> OP_RETURN.  This is truly blind as the mainchain miner is given what is
> effectively a blob of data, and the mainchain miner cannot expect any kind
> of format from OP_RETURN.  This has the tremendous advantage of not even
> requiring a softfork.
>
>
> @Chris
>
> >What if a attacker pays a large fee to have his *invalid* block hash
> included in the bitcoin mainchain? Would this block *have* to be included
> in the sidechain's blockchain forever since *it was* included in bitcoin
> blockchain?
>
> In my scheme, if you read carefully through the pseudocode, a block list
> node is valid only if its block is valid.
>
> Basically, in my scheme, the OP_RETURN data *is* the sidechain block
> headers stored on the mainchain.  To save space, the sidechain block
> headers are reduced to only the previous-block-header commitment and the
> current-block-data commitment.  All of the other data you would want to put
> in the block header (e.g. UTXO set commitment, signalling bits,
> time-of-day...) would be part of the current-block-data instead of the
> block header.  Thus if the current-block-data is invalid the sidechain
> block header is invalid and another sidechain block header based on the
> previous block header will be searched for.
>
> My understanding is that your attack scenario is not helped by
> OP_BRIBEVERIFY alone, as a rich sidechain attacker can provide a bigger
> bribe to an invalid h* especially since the mainchain miner will not even
> check the h*, just insert it into the coinbase.
>
> >Maybe I am missing something here, but why we do *explicitly* commit to
> the previous block hash? Isn't it implicitly committed to via
> SHA256(SHA256())?
>
> In order to eliminate having to specify a sidechain index, and to remove
> sidechain indexes altogether.  Instead the sidechain is identified by its
> topmost block header hash.
>
>
> @CryptAxe
>
> >The ratchet system is actually what links the h* data from bribes to
> sidechain blocks. h*'s (which are sidechain block hashes) are added to the
> ratchet system if they move the sidechain forward or start a split like I
> mentioned before. Then a sidechain can request of their local mainchain
> node to verify the headers they have downloaded from sidechain peers and
> form the side chain.
>
> I see.  However, then, I propose that my OP_RETURN scheme is superior as
> the sidechain block headers are indeed visible directly on the mainchain,
> and the mainchain node does not even need to be "local", but can be sourced
> anywhere, without requiring a ratchet structure (whose purpose I still have
> not managed to grok).
>
> Regards,
> ZmnSCPxj
>
>