I recently started mining burstcoin as the proof of capacity system seemed rather novel and unique. However, both pointing my capacity at a pool and trying to solo mine I was surprised by how often forks and orphans seemed to occur compared to other coins that I’ve mined and so I looked into the code to see if I could find anything that might make these events occur more often than expected.

There is one thing which I think I’ve found that could explain some of this, but thinking about it more there are potentially worse consequences than just pools and miners thinking they’ve found blocks that are then overtaken.

Sorry for the length and explaining some basic concepts – I expect you’ll be familiar with these, it was more to solidify my understanding and explain my assumptions as I’m new to burstcoin.

The Problem

When miners produce blocks they do so by building on top of the generation signature for that block and the block beforehand. The new generation signature is made from hashing the previous gensig and the id of the generator of the previous block with no data that makes up the current block.

This allows a miner, upon finding a deadline that they can use to make a block, to produce many permutations of the same block with different contents. A malicious miner could connect to many peers on the network and send each peer a different version of the block, both taking up resources as each peer will verify and broadcast each version of the block and also deliberately increasing the fork risk as if pools and miners start building on different blocks and find very similar deadlines.

The problem described above, while frustrating and potentially detrimental to the amount of resources needed to run a node on the network, wouldn’t fundamentally affect the ability of network participants to transact and, after forks are resolved, miners will still receive the income for finding the lowest deadline. As such this alone isn’t enough to justify changing the consensus rules in my opinion.

There is another consequence of the generation signature only including this limited amount of information: a minor potential for double spends. Right now, the contents of the block are signed by the miner and include a hash of the transactions in the previous block. As long as different miners find blocks there is no problem, it isn’t possible to broadcast a (valid) chain with different transactions in all but the latest block. A problem occurs though when one miner or pool finds more than one block in a row: they can resign all the blocks they find sequentially and as such remove a transaction even with several confirmations. Given the size pools have reached in the past (based upon https://forums.burst-team.us/topic/3965/burst-ninja-is-getting-too-big and other forum threads) this seems like a very real risk and would significantly increase the number of confirmations needed, basically to the point that more than one miner has mined a block. This wouldn’t be perfect though as a miner with a large amount of the hash rate could simply mine under different accounts to hide the proportion that they have.

Note that even 10% of the hash rate could potentially allow for a successful double spend based upon 4 confirmations. As such I think making a change to prevent miners from rewriting their own transaction history is worth the large cost of performing a flag day upgrade of the software.

Proposed fix

This change includes a hash of the transactions in the block as part of the generation signature. This is done by selecting transactions for inclusion as soon as mining begins on a new block rather than once a deadline has been found.

With this change in place it is no longer possible to modify the contents of a block – changing a transaction would change the generation signature and make the deadline found no longer valid. This successfully mitigates both the block flood and double spending attacks described above as both depend upon changing the contents of a block after a deadline has been found.

Alternatives

Rather than changing how the generation signature is computed it would be possible to change how the deadline is computed. My understanding of the latter is that it would require most, if not all, mining software to be upgraded whereas the generation signature is already fetched from a burstcoin wallet using getMiningInfo and so the change as proposed would only require wallets to upgrade by the flag day, a much easier and feasible task.

Advantages of this approach

  • Fixes block flood and double spend attacks by malicious miners with significant minorities of the network capacity
  • Can be done with only wallet upgrades, current pool, plotting and miner software will still work correctly.
  • Brings burstcoin in line with how most other coins build their blockchains – the transaction hash is including the bitcoin block header, for example.

There is one other advantage that I’m less confident about as I’m still developing my understanding of how the burstcoin mining process works. I think this change makes it hard to perform a double spend even with 51% of the network capacity as I’ll explain below.

On a proof of work based coin, finding a block is effectively a race and if you have 51% of the hashrate you can pick an arbitrary block in the past that you wish to rewrite the blockchain up to and, given enough time, you will always win the race to find the longest chain, therefore rewriting the history as you please. Burstcoin, with proof of capacity, is different: finding a block is more like a lottery than a race. With 51% of the hashrate you’ll expect to have the winning deadline 51% of the time, but for the other 49% of the time you might lose by quite a large margin and no amount of additional time (bar regenerating all the plots, which is infeasible simply to find another block). As such, if a miner with 51% tries to rewrite history, the further back they wish to rewrite the more blocks in a row they must find a low deadline for, but as this is only expected 51% of the time they won’t get very far.

Note that I’m not saying that confirmations are not required to have confidence of a double spend – that remains the case. However, in the event of a miner with 51% (which would still be bad and a serious cause for concern), the number of blocks they could rewrite would be rather limited.

Note that I’ve only done some very cursory analysis of the probabilities behind this (and my probability is very rusty), but everything seems to line up that with even 90% of the capacity a malicious miner to rewrite the last 4 blocks with a 65% success rate, dropping steeply the more confirmations there are. This is much better than a PoW coin where 51% will rewrite history given enough time every time.

Disadvantages of this approach

This is a hard fork. It will require all wallets to upgrade. There was no way I could think of that changing the generation signature could be done any other way. However, I think the potential advantages (even excluding the speculative increased difficulty of double spends with a majority capacity) are well worth doing this and I’m sure all miners will appreciate less risks of forks and all users, especially those running businesses such as exchanges, would rather it isn’t possible to double spend with a minority of the hash rate.

I picked a rather arbitrary number for the actual fork block that was about 2 weeks in the future when I originally wrote this (since then I’ve tried to do more analysis and testing to ensure this change is correct and addressing real issues), this should of course be changed to something that would be feasible to do the upgrade by – however I would recommend some haste to this due to the potential risks present from denial of service block floods and double spends in the time before a fork would come into effect. However, as there are easier DOS attacks possible right now (e.g. DDOS pool servers) and since the fall of ninja.pool I don’t think any pools currently have too large a share there is no reason to panic.

(And my apologies for proposing such a drastic change as my first PR, I really wasn’t expecting to find something like this on my first read through the codebase!)

Source: https://github.com/burst-team/burstcoin/pull/6

Subscribe

Subscribe now to our newsletter

Leave a Reply

Your email address will not be published. Required fields are marked *

*
*