Pool deliberately (?) producing empty blocks

A few months ago a raised a concern (on Telegram) that pools might deliberately start producing small or empty blocks to obtain faster block production. This because propagation times of bigger blocks are on average more than one second now and chances of height battles, and losing them, are becoming higher.

I asked this question an on SPO call and the answer was that they were aware of this problem, but it doesn’t have an easy solution (which is understandable). For now we would have to rely on community action as a counter measure. When I raised the question, I thought this would need some code alteration, but NASEC pointed out that it can easily be achieved by setting mempool size to zero.

And at least one pool has done this: pool.pm


Whoa, that sounds dangerously broken.

As for solutions: Scale the block rewards with transactions in the block? Yeah, then you could get minimal or no rewards just because there are no transactions available at the time of your scheduled block. But then again, in the future, when reserve is empty and rewards have to be paid by fees, that might even be the sensible thing to do.


That’s a too invasive change in how Cardano works imho. But I think block explorers and wallets should flag those pools. But the thing is, delegators don’t lose rewards because of this, on the contrary, less chances to be part in a height battle means less chances of losing rewards because of a ghosted block…

Other pools could decide not to connect to this pool, which will it make it more difficult for this pool to propagate its blocks, but this will only work if a big majority does this because if some relays still connect to this pool, it will eventually propagate anyway. Delisting this pool from topology updater would help a little, but this might be dangerous and controversial (and won’t work after p2p is turned on anyway).

A more extreme measure is that enough pools start using a modified version of the node so that it doesn’t forge blocks anymore based on that pool’s block, but that will be more difficult and dangerous (you can’t just ignore the blocks, because someone else could already built on them). This will cause height battles though if the next slot leader doesn’t play along, so you’re risking your own blocks to get ghosted…


I agree we need to rely on the community shifting delegation away from bad actors.

I think these would make things worse because you only need one pool to pull the block so this would just increase propagation times resulting in more forks. More forks means reduced chain security, increased transaction finality time, and more collateral damage in terms of orphaned blocks for other pools.

Furthermore there is an assumption that they are a bad actor if the block is empty. Firstly this will occasionally produce false positives. But it is also easy for the bad actors to thwart this detection by putting in just 1 transaction, or 2 or 3. They could even just filter out script transactions taking more time. It will still save time with less transactions, but now some sort of quantitative or qualitative judgement needs to be made to determine if they are a bad actor or not.

I think the proper fix for this will be “input endorsers” because this will separate the dual purpose of blocks. Namely to:

  1. Contain transactions
  2. Certify previous blocks

I haven’t seen any IOG design for input endorsers yet, but I believe this separation will remove the incentives around timing of when blocks arrive. I think it will eliminate “propagation delay” battles. (There will still be “same slot” battles.)

As a side note:
This strategy of producing empty blocks for fast propagation only addresses half of the cause of their “propagation delay” orphans. It addresses the half caused by other pools not receiving their block in time. But it doesn’t address the half caused by other pools producing a block before theirs that they haven’t received yet. In both cases a fork 1 block high is resolved based on a VRF comparison independent of the delay (even 30 seconds or more).

Please also see my other post about bad operators:

These bad actors are easy to identify with certainty and it would be easy to implement delegation ranking punishments for them.

Topology updater is pure code-based. No artificial blocks. I prepared some blacklisting functionality, because I expected to need it, but so far everything was tolerable.

I honestly don’t expect delegators moving away will happen, as long as these tiny blocks get full rewards on less (~2.5%) lost slot battle.

So instead of calculating block rewards based on their payload (a good idea imo but if it is “too invasive”), a solution could be to increase block rewards generally by ~10% and then skip rewards for the smallest blocks produced in this epoch. This creates an incentive for every operator to collaborate as best as possible. And a strong incentive for delegators to move away in case

1 Like

Your proposal (as well as mine, unfortunately) could lead to a small incentive for pools that are scheduled to produce a block to hold transactions back from propagating, so that they can include them in their block to come. Not sure if that can be a big problem.

1 Like

Depends where this TX is “injected”
Only if this malicious operator is the first and only node receiving the TX from the submitting user, he would be able to keep it secret and out of other blocks. In such a case the user will note these pools bad performance and switch to other tx submission api/services.


What are input endorsers? Sorry, if I just missed the explanation.

Talking about block battles: Maybe, a not too invasive solution would be too generally decide block battles on the size of the transactions in both combattants (maybe even total size across different heights). That could be an incentive to include as much transaction content as possible for the case that a battle ensues.

Because of propagation times longer than 1 sec, forks will happen anyway, they’re just part of the protocol. The reason they produce empty blocks is just to reduce the chances of a fork. But if everyone start doing this, we’ll end up with a ghost network… So we’ll have to live with forks anyway…

Correct, you’ll have to be careful not to punish the false positives, so determining if it’s deliberately won’t be easy. But in this case it’s clear I think…

I also did mention adding less tx or only simple tx in my concerns a few months ago. The former could be achieved by just setting the mempool to a lower not zero value (if the SPO in question was ‘smarter’ he would’ve done this and there was a higher chance he might got away with it). The latter can only be done by changing the code I think, hence more difficult to achieve.

Yes, this might be a solution, we’ll have to wait on more details on that.

Are you considering using it in this particular case?

Not sure I would like this, if your elected slot is close to another and usage is low, you’ll also lose rewards.

Another possible solution is just increasing slot time to e.g. 4 sec (instead of 1 sec) and adapting target density so that the target number of blocks in an epoch stays the same. This will cause more forks however, but trying to ‘cheat’ will be a lot more difficult. I thought someone of IOG said that the slot time of 1 sec isn’t set in stone, so this will be a possibility. But I think they won’t change that now, maybe together with input endorsers.

All that said, I don’t expect much action of IOG for now. They look at network health as a whole and this malicious behavior of one pool won’t have much influence on the network. Only if a lot more pools started to exhibit this behavior and it becomes a bigger problem, they will see what they can do.

I thought about this too, but then you have an incentive to e.g. add some dummy tx of your own that you don’t propagate (their fees will be much lower than the block rewards for now). So I don’t think it’ll work.


I have a similar idea and currently collect data to propose something, without running into more forks due to higher collision probability. This then would also avoid the close blocks with no TX to add.

Also to say: long term it will affect all pools the same with such bad luck (no TXs on short following slot)
But a conscious empty block producer will be affected way more.


Apparently input endorsers will be a solution to this problem: