<p><strong>Update 12/13/2021:</strong></p>
<p>My first question on Cardano Stack Exchange was <a href="https://cardano.stackexchange.com/questions/4089/what-is-the-penalty-for-running-2-block-producer-nodes">What is the Penalty for Running 2 Block Producer Nodes?</a> Which I was told, &quot;Network can penalize.&quot; But I never received an answer as to what that penalty was, which I believe is because there is <em>not a penalty.</em></p>
<p>With that said, I believe your question is a result of a pool running 2 block producing nodes with the same keys. When one of these pools is elected slot leader and creates a block they actually create 2 blocks. 1 of these 2 blocks will be orphaned, but damage could be done to other pools before that happens (like your case, I believe). With the 2 blocks propagating, it is possible that a pool, let's call it  pool A, creates their next block on the losing, bad block. If this happens, pool A is going to have their block orphaned when the chain is rolled back to fix the duplicate block issue. This is what I believe happened to you.</p>
<p>With that said, your comment about disconnecting the relays from your BP for 30 seconds still wouldn't work to cause this. If you wanted to cause this you would have to run 2 block producer nodes. Which I do not recommend, and as a community, we should figure out how we are going to penalize these pools.</p>
<p>Here is a reference: <a href="https://www.reddit.com/r/CardanoStakePools/comments/rdzbhq/two_years_after_reporting_a_problem_with_cardano/" rel="nofollow noreferrer">https://www.reddit.com/r/CardanoStakePools/comments/rdzbhq/two_years_after_reporting_a_problem_with_cardano/</a></p>
<p><strong>Original Answer:</strong></p>
<p>I believe this happened because you lost a slot leader battle. So basically the other pool you were competing with had a better overall propagation time and that is why your block was orphaned. From your point of view, it looks like your block had the better propagation time but that is because you are looking at the nodes you are connected to.</p>
<p>As far as waiting 30 seconds to try to cause a DoS attack, it wouldn't work and you would just orphan your block. This is because even if there isn't another slot leader to take that block, another block will be created in 20 seconds that will create the new longest chain.</p>
<p>I hope this is helpful!</p>

CC BY-SA 4.0
2021-12-07T21:13:24.373Z
No evidence of slot battle.  cncli validate says my block is orphaned.  Also the logs do not show another block for the same slot as my slot.  Instead the logs show that this earlier block arrived 30 seconds late which was 2 seconds after my block was minted.  Then the node switched tip to this earlier block, invalidated my block causing it to be orphaned.
74d4
CC BY-SA 4.0
2021-12-07T23:58:14.333Z
Can you share the specific slot, block and logs you are looking at?
Jacob - SNOWY Pool
CC BY-SA 4.0
2021-12-11T21:09:11.740Z
The logic in my question post seems correct.  Watch the NerdOut video by Andrew Westberg: https://youtu.be/4j_SymkuxfU
74d4
CC BY-SA 4.0
2021-12-13T23:33:10.970Z
Re: Update 12/13/2021: I have checked the cncli database on my node and there was only 1 block produced by the previous block producer which was delayed 30 seconds.  My block producer produced its block when it should have (and I do only run 1).  The previous block producer's block arrived 30 seconds late which happened to be 2 seconds after my block was produced with the same block number.  Because this delayed block was for an earlier slot all the nodes in the network switched tip to this delayed block and invalidated my block.
74d4
CC BY-SA 4.0
2021-12-13T23:41:12.717Z
Think about the logic:  If two blocks are produced with the same block number by two different stake pools the nodes will accept only the block for the earlier slot.  Therefore if a block producer deliberately delays his block this will invalidate a future block produced by another node.  Two blocks can't have the same block number in the chain (and there will be conflicting transactions).  The nodes will accept only the first block (the one for the earlier slot).
74d4
CC BY-SA 4.0
2021-12-14T00:24:27.123Z
"To determine which chain to adopt, each party collects all valid chains and applies the Chain Selection Rule." "... Chain Selection Rule: pick the longest chain as long as it grows more quickly (is denser) in the slots following the last common block to both competing chains." So in the case of waiting 30 seconds, another pool will create a block and have 10 seconds to be denser. Link: https://developers.cardano.org/docs/stake-pool-course/introduction-to-cardano/
Jacob - SNOWY Pool
CC BY-SA 4.0
2021-12-14T00:41:30.263Z
"The previous block producer's block arrived 30 seconds late which happened to be 2 seconds after my block was produced with the same block number. Because this delayed block was for an earlier slot all the nodes in the network switched tip to this delayed block and invalidated my block." It arrived late to you but that doesn't necessarily mean it was late, it just means that you created a block 2 seconds after theirs but didn't know it for 30 seconds (yours was also propagating). Not trying to argue with you, just trying to help :). Was hoping someone else would answer (why I added a bounty).
Jacob - SNOWY Pool
CC BY-SA 4.0
2021-12-16T05:27:15.300Z
I appreciate the discussion.  I run relays on opposite sides of the world and all received this block approx 30 seconds late.  All relays part-take in topology updates via api.clio.one and have 20-24 outgoing connections and 10-20 incoming connections.  I was watching the logs at the time my node produced its block.  The block was produced and then 2 seconds later I saw the logs about switching tip and immediately investigated WTF just happened.  There didn't appear to be any time for a longest chain determination.  The nodes just switched tip to this delayed block (same block No) immediately.
74d4
CC BY-SA 4.0
2021-12-17T08:20:34.847Z
I updated the question with logs and data from cncli database.
74d4
CC BY-SA 4.0
2021-12-07T15:30:35.057Z
2021-12-13T15:29:20.420Z
2021-12-13T15:29:20.420Z
Jacob - SNOWY Pool
<p>I just analysed the reasons for why my pool minted an orphaned block.</p>
<p>Here is the sequence of events:</p>
<p>My pool minted block No=1 in its allocated slot=28 at T=28.050 seconds.  This block propagated across the network and was received by other, not directly connected, relays within 1 second (ie. by T=29 seconds).</p>
<p>My pool and other relays received block No=0 which was generated in slot=0 at T=30s.  This block is 30 seconds delayed; it arrived 30 seconds after it was produced at T=30.  However, this block predates my block and contains transactions which my block included.  This results in the cardano node switching tip to this block No=0 and invalidating my block.</p>
<p>So here is the problem:</p>
<p>Lets say I wanted to increase my stake pool rewards.</p>
<p>Every time my pool is due to mint a block I could disconnect my relays from the block producer.  Then wait for the block to be minted and wait another 30 seconds or more.  Then connect my relays to the block producer.  The relays would then pull the freshly minted block and other connected nodes would in turn pull the minted block and it would propagate across the network.  The net result is a block delayed by 30 seconds or more.</p>
<p>Any other pools that mint a block during this 30 second or more window of time will get their blocks invalidated.</p>
<p>Thus selfish mining / denial of service on Cardano ??????????</p>
<p>Addition: 2012-12-17:<br />
Timestamp seconds are actual values and last 2 digits of block and slot numbers are also actual values.<br />
Logs:</p>
<pre><code>...  
xx:xx:45 cardano-node: TraceNodeIsLeader  
xx:xx:45 cardano-node: block String &quot;yyyy&quot; Number 48 blockPrev &quot;wwww&quot;  
xx:xx:45 cardano-node: Chain extended, new tip:yyyy at slot 74  
xx:xx:45 cardano-node: TraceAdoptedBlock  
xx:xx:45 cncli-sync: block 48 of 48, 100.00% synced  
xx:xx:46 cardano-node: TraceNodeNotLeader  
xx:xx:47 cardano-node: TraceNodeNotLeader  
xx:xx:47 cardano-node: BlockFetchDecision SlotNo 45 blockPointHash = zzzz  
xx:xx:47 cardano-node: Block fits onto some fork: xxxx at slot 45  
xx:xx:47 cncli-sync rollback to slot 19  
xx:xx:47 cardano-node: Valid candidate xxxx at slot 45  
xx:xx:47 cardano-node: Switched to a fork, new tip xxxx at slot 45  
xx:xx:47 cardano-node: Ignoring block already in DB: xxxx at slot 45  
xx:xx:47 cncli-sync block 48 of 48, 100.00% synced  
xx:xx:48 cardano-node: TraceNodeNotLeader  
xx:xx:49 cardano-node: TraceNodeNotLeader  
...  
</code></pre>
<p>Note that my block was produced at time = 45 seconds for slot = 74.  The delayed block was produced 29 seconds before this (at time = 16 seconds) for slot = 45 but was received at time = 47 seconds.<br />
Upon receiving this delayed block, the cardano-node rolls back to the block prior to this delayed block (block at slot = 19) and then adds the delayed block for slot = 45.<br />
Now my block for slot 74 is invalid - presumably because it contains transactions that were in the delayed block and it has the same block number of 48.</p>
<p>Note: Cardano slots occur every 1 second.</p>
<p>Immediately after seeing these logs I did the following cncli query:</p>
<pre><code>cncli validate --db db/cncli.db --hash yyyy
</code></pre>
<blockquote>
<p>{<br />
&quot;status&quot;: &quot;orphaned&quot;,<br />
&quot;block_number&quot;: &quot;48&quot;,<br />
&quot;slot_number&quot;: &quot;74&quot;,<br />
&quot;pool_id&quot;: &quot;blahblah&quot;,<br />
&quot;hash&quot;: &quot;xxxx&quot;,<br />
&quot;prev_hash&quot;: &quot;wwww&quot;,<br />
&quot;leader_vrf&quot;: &quot;blahblah&quot;<br />
}</p>
</blockquote>
<p>My block is orphaned!</p>
<p>cncli database records:</p>
<pre><code>select id, block_number, slot_number, hash, orphaned from chain where block_number &gt; 40 and block_number &lt; 52;
</code></pre>
<pre><code>id|block_number|slot_number|hash|orphaned
35|          46|         xx|vvvv|0
36|          47|         19|wwww|0
37|          48|         74|yyyy|1
38|          48|         45|xxxx|0
39|          49|         xx|zzzz|0
40|          50|         xx|aaaa|0
41|          51|         xx|bbbb|0
</code></pre>

CC BY-SA 4.0
2021-12-11T22:55:59.730Z
Related? https://www.reddit.com/r/cardano/comments/re2e1b/two_years_after_reporting_a_problem_with_cardano/?utm_medium=android_app&utm_source=share
Jacob - SNOWY Pool
<stake-pool><minting><rewards><block-production><attacks>
Selfish mining / denial of service on Cardano?
# Selfish mining / denial of service on Cardano?

(Asked by: username_0 on 2021-12-07)

I just analysed the reasons for why my pool minted an orphaned block.
Here is the sequence of events:
My pool minted block No=1 in its allocated slot=28 at T=28.050 seconds.  This block propagated across the network and was received by other, not directly connected, relays within 1 second (ie. by T=29 seconds).
My pool and other relays received block No=0 which was generated in slot=0 at T=30s.  This block is 30 seconds delayed; it arrived 30 seconds after it was produced at T=30.  However, this block predates my block and contains transactions which my block included.  This results in the cardano node switching tip to this block No=0 and invalidating my block.
So here is the problem:
Lets say I wanted to increase my stake pool rewards.
Every time my pool is due to mint a block I could disconnect my relays from the block producer.  Then wait for the block to be minted and wait another 30 seconds or more.  Then connect my relays to the block producer.  The relays would then pull the freshly minted block and other connected nodes would in turn pull the minted block and it would propagate across the network.  The net result is a block delayed by 30 seconds or more.
Any other pools that mint a block during this 30 second or more window of time will get their blocks invalidated.
Thus selfish mining / denial of service on Cardano ??????????
Addition: 2012-12-17:
Timestamp seconds are actual values and last 2 digits of block and slot numbers are also actual values.
Logs:
...  
xx:xx:45 cardano-node: TraceNodeIsLeader  
xx:xx:45 cardano-node: block String "yyyy" Number 48 blockPrev "wwww"  
xx:xx:45 cardano-node: Chain extended, new tip:yyyy at slot 74  
xx:xx:45 cardano-node: TraceAdoptedBlock  
xx:xx:45 cncli-sync: block 48 of 48, 100.00% synced  
xx:xx:46 cardano-node: TraceNodeNotLeader  
xx:xx:47 cardano-node: TraceNodeNotLeader  
xx:xx:47 cardano-node: BlockFetchDecision SlotNo 45 blockPointHash = zzzz  
xx:xx:47 cardano-node: Block fits onto some fork: xxxx at slot 45  
xx:xx:47 cncli-sync rollback to slot 19  
xx:xx:47 cardano-node: Valid candidate xxxx at slot 45  
xx:xx:47 cardano-node: Switched to a fork, new tip xxxx at slot 45  
xx:xx:47 cardano-node: Ignoring block already in DB: xxxx at slot 45  
xx:xx:47 cncli-sync block 48 of 48, 100.00% synced  
xx:xx:48 cardano-node: TraceNodeNotLeader  
xx:xx:49 cardano-node: TraceNodeNotLeader  
...  

Note that my block was produced at time = 45 seconds for slot = 74.  The delayed block was produced 29 seconds before this (at time = 16 seconds) for slot = 45 but was received at time = 47 seconds.
Upon receiving this delayed block, the cardano-node rolls back to the block prior to this delayed block (block at slot = 19) and then adds the delayed block for slot = 45.
Now my block for slot 74 is invalid - presumably because it contains transactions that were in the delayed block and it has the same block number of 48.
Note: Cardano slots occur every 1 second.
Immediately after seeing these logs I did the following cncli query:
cncli validate --db db/cncli.db --hash yyyy


{
"status": "orphaned",
"block_number": "48",
"slot_number": "74",
"pool_id": "blahblah",
"hash": "xxxx",
"prev_hash": "wwww",
"leader_vrf": "blahblah"
}

My block is orphaned!
cncli database records:
select id, block_number, slot_number, hash, orphaned from chain where block_number > 40 and block_number < 52;

id|block_number|slot_number|hash|orphaned
35|          46|         xx|vvvv|0
36|          47|         19|wwww|0
37|          48|         74|yyyy|1
38|          48|         45|xxxx|0
39|          49|         xx|zzzz|0
40|          50|         xx|aaaa|0
41|          51|         xx|bbbb|0

**Tags:** stake-pool, minting, rewards, block-production, attacks
> **Comments:**
> **username_1**: Related? https://www.reddit.com/r/cardano/comments/re2e1b/two_years_after_reporting_a_problem_with_cardano/?utm_medium=android_app&utm_source=share  

---

## 1 answers

### Answer by username_1 on 2021-12-07. Score: 4

**Update 12/13/2021:**

My first question on Cardano Stack Exchange was [What is the Penalty for Running 2 Block Producer Nodes?](https://cardano.stackexchange.com/questions/4089/what-is-the-penalty-for-running-2-block-producer-nodes) Which I was told, "Network can penalize." But I never received an answer as to what that penalty was, which I believe is because there is *not a penalty.*

With that said, I believe your question is a result of a pool running 2 block producing nodes with the same keys. When one of these pools is elected slot leader and creates a block they actually create 2 blocks. 1 of these 2 blocks will be orphaned, but damage could be done to other pools before that happens (like your case, I believe). With the 2 blocks propagating, it is possible that a pool, let's call it pool A, creates their next block on the losing, bad block. If this happens, pool A is going to have their block orphaned when the chain is rolled back to fix the duplicate block issue. This is what I believe happened to you.

With that said, your comment about disconnecting the relays from your BP for 30 seconds still wouldn't work to cause this. If you wanted to cause this you would have to run 2 block producer nodes. Which I do not recommend, and as a community, we should figure out how we are going to penalize these pools.

Here is a reference: <https://www.reddit.com/r/CardanoStakePools/comments/rdzbhq/two_years_after_reporting_a_problem_with_cardano/>

**Original Answer:**

I believe this happened because you lost a slot leader battle. So basically the other pool you were competing with had a better overall propagation time and that is why your block was orphaned. From your point of view, it looks like your block had the better propagation time but that is because you are looking at the nodes you are connected to.

As far as waiting 30 seconds to try to cause a DoS attack, it wouldn't work and you would just orphan your block. This is because even if there isn't another slot leader to take that block, another block will be created in 20 seconds that will create the new longest chain.

I hope this is helpful!

> **Comments:**
> **username_0**: No evidence of slot battle.  cncli validate says my block is orphaned.  Also the logs do not show another block for the same slot as my slot.  Instead the logs show that this earlier block arrived 30 seconds late which was 2 seconds after my block was minted.  Then the node switched tip to this earlier block, invalidated my block causing it to be orphaned.  
> **username_1**: Can you share the specific slot, block and logs you are looking at?  
> **username_0**: The logic in my question post seems correct.  Watch the NerdOut video by Andrew Westberg: https://youtu.be/4j_SymkuxfU  
> **username_0**: Re: Update 12/13/2021: I have checked the cncli database on my node and there was only 1 block produced by the previous block producer which was delayed 30 seconds.  My block producer produced its block when it should have (and I do only run 1).  The previous block producer's block arrived 30 seconds late which happened to be 2 seconds after my block was produced with the same block number.  Because this delayed block was for an earlier slot all the nodes in the network switched tip to this delayed block and invalidated my block.  
> **username_0**: Think about the logic:  If two blocks are produced with the same block number by two different stake pools the nodes will accept only the block for the earlier slot.  Therefore if a block producer deliberately delays his block this will invalidate a future block produced by another node.  Two blocks can't have the same block number in the chain (and there will be conflicting transactions).  The nodes will accept only the first block (the one for the earlier slot).  
> **username_1**: "To determine which chain to adopt, each party collects all valid chains and applies the Chain Selection Rule." "... Chain Selection Rule: pick the longest chain as long as it grows more quickly (is denser) in the slots following the last common block to both competing chains." So in the case of waiting 30 seconds, another pool will create a block and have 10 seconds to be denser. Link: https://developers.cardano.org/docs/stake-pool-course/introduction-to-cardano/  
> **username_1**: "The previous block producer's block arrived 30 seconds late which happened to be 2 seconds after my block was produced with the same block number. Because this delayed block was for an earlier slot all the nodes in the network switched tip to this delayed block and invalidated my block." It arrived late to you but that doesn't necessarily mean it was late, it just means that you created a block 2 seconds after theirs but didn't know it for 30 seconds (yours was also propagating). Not trying to argue with you, just trying to help :). Was hoping someone else would answer (why I added a bounty).  
> **username_0**: I appreciate the discussion.  I run relays on opposite sides of the world and all received this block approx 30 seconds late.  All relays part-take in topology updates via api.clio.one and have 20-24 outgoing connections and 10-20 incoming connections.  I was watching the logs at the time my node produced its block.  The block was produced and then 2 seconds later I saw the logs about switching tip and immediately investigated WTF just happened.  There didn't appear to be any time for a longest chain determination.  The nodes just switched tip to this delayed block (same block No) immediately.  
> **username_0**: I updated the question with logs and data from cncli database.  

---

