bitshares1-core icon indicating copy to clipboard operation
bitshares1-core copied to clipboard

Allow delegates to create transactions that do not meet the relay fee

Open vikramrajkumar opened this issue 11 years ago • 10 comments

vikramrajkumar avatar Sep 26 '14 22:09 vikramrajkumar

There should be some anti-spam limitation on the total size of the free transactions and the number that can be included in a block. Otherwise a malicious delegate could spam the network with giant blocks of useless free transactions.

drltc avatar Oct 23 '14 19:10 drltc

The motivation for this is that delegates are the only first-class employees of the company and are responsible for such roles as frequently updating price feeds, which cuts into their income.

We also want to avoid hardcoding as many parameters into the consensus protocol as possible, because hardforks are then required to calibrate. Rather, we want to use humans as the control system so that if a delegate begins abusing the network, it is up to subsequent delegates to choose whether they want to build off the abusive delegate's blocks or not. How to expose these decisions to delegates in a user-friendly way is an open question.

It is also the expectation that poor or abusive employees will ultimately be voted out.

vikramrajkumar avatar Oct 23 '14 19:10 vikramrajkumar

You are right though that we probably shouldn't expose the ability for delegates to easily apply such fee-less transactions without exposing some tunable limits on block acceptance that would only be relevant for block producers.

vikramrajkumar avatar Oct 23 '14 19:10 vikramrajkumar

We can just have delegates by default not produce on top of a block that contains more than N free transactions. Then changing N will not be a hard fork, it will only require the delegates to change their behavior.

drltc avatar Oct 23 '14 19:10 drltc

Number of transactions is irrelevant, though. Transactions can be arbitrarily complex, and only the signing delegate is allowed to do free transactions, so all operations would be from the same user (the delegate) hence he could simply aggregate all of his operations into one transaction.

We could limit the size or operation count of a free transaction (then we'd have to limit transaction count too, though), but again, we could just leave it be and let users vote out abusive delegates.

nathanielhourt avatar Oct 23 '14 20:10 nathanielhourt

The main issue here is that we want to consider what would happen if one rogue delegate fed all the other delegates a block that will e.g. require a billion database lookups to verify.

In that case, the rogue delegate would effectively have the power to halt the network for however long it takes the legitimate delegates to process the block. If the rogue delegate can make blocks that take an arbitrarily large amount of CPU time, memory or I/O to validate, then a rogue delegate will be able to halt the network for arbitrarily long periods of time.

Bottom line is, there needs to be a limit on the resources the legitimate delegates will spend on a block, even if that block has already been accepted by a delegate.

Anything else would leave the door open to this DoS attack. Exactly what needs to be limited does depend on some implementation details.

drltc avatar Nov 10 '14 17:11 drltc

@vikramrajkumar can comment, but I believe in that instance, the next delegate would simply produce a block as though the rogue delegate had not produced one, right? Or would the non-preemptability stuff prevent that?

nathanielhourt avatar Nov 10 '14 17:11 nathanielhourt

Clearly, the correct behavior is that the next delegate should produce a block as though the rogue delegate had not produced one.

The question is whether the existing code actually has this behavior.

If the validation code runs in the same OS-level thread as the block production code and uses FC's cooperative multitasking functionality, then it would fail -- the validation computation would stop production of new blocks unless there are frequent yields in the validation computation code.

drltc avatar Nov 10 '14 17:11 drltc

In the current implementation, the delegate block production code runs in the same thread as the block processing code, and the block processing code does not (and, without a lot of effort, cannot) yield.

Only nodes that are directly connected to the block producer will be stuck processing the block. It won't propagate until those nodes validate the block, so any delegates not directly connected to the attacker would still be able to produce blocks, so they could generate a longer fork and win. The block would still cause some disruption as it made its way around the network.

There is a BTS_BLOCKCHAIN_MAX_BLOCK_SIZE constant; no well-behaving delegate will generate a block larger than that. If we can check the block size early in block validation, we'd just need to make you can't craft small transactions that take a long time to process.

emfrias avatar Nov 10 '14 17:11 emfrias

Also see: https://bitsharestalk.org/index.php?topic=9456.msg122849#msg122849

vikramrajkumar avatar Dec 13 '14 09:12 vikramrajkumar