Question about which block wins

on bitcointalk jl777 asks:

I have a question about the consensus rules.

Main Chain Protocol
The protocol for determining which competing block chain wins as main chain has been
switched over to use consumed coin age. Here every transaction in a block contributes its
consumed coin age to the score of the block. The block chain with highest total consumed
coin age is chosen as main chain.

From the above it indicates that the coinage for the entire block is used to determine which block wins (contingent on its passing all the other requirements).

However in the code, it looks like it is using the longest chain wins. While that would eventually reach consensus, I was wondering if there was a specific reason the blocks’ coinage isnt used as a tiebreaker for two competing blocks found at the same time. maybe it opens an attack where a large coinage can be spent?

James

maybe someone knows? :slight_smile:

I believe this post from 2014 (and subsequent parts of the thread after that specific post) addresses this already.

https://www.peercointalk.org/index.php?topic=2976.msg27789#msg27789

Back in 2014 there were many discussions about how it would be possible to attack Peercoin and how this project would never last.

Somehow it is 2016 now, and the chain is still running nicely. :slight_smile:

It uses the proof-of-stake difficulty as the score of the block, see CBlockIndex::GetBlockTrust().

Since difficulty changes gradually, it appears that longer fork would win in general, disregarding the proof-of-work blocks on both forks.

The description in paper may not be accurate, this part of the protocol is introduced in v0.2 to improve blockchain security if I remember correctly.

[quote=“Sunny King, post:3, topic:3888”]It uses the proof-of-stake difficulty as the score of the block, see CBlockIndex::GetBlockTrust().

Since difficulty changes gradually, it appears that longer fork would win in general, disregarding the proof-of-work blocks on both forks.

The description in paper may not be accurate, this part of the protocol is introduced in v0.2 to improve blockchain security if I remember correctly.[/quote]
Yes, that is what I saw.

At any given height, the PoS difficulty is the same for any block that has a kernel that is below the required threshold. So, regardless of the coinage of the unspent that is the kernel, or the entire block’s coinage, all blocks found are treated equally.

Then the network propagation of these blocks would most strongly influence which block will be extended. I think a first seen rule is implicit, as once a node sees a valid block it will start trying to extend that one. I could not find anything in the code that uses coinage to prioritize a new block at the same height.

So, this would give a large advantage to a node that blasts his kernel to as many other nodes as possible. It also means that there can be two (or more) active chaintips. I raised this issue in https://bitcointalk.org/index.php?topic=355644.0 and it seems that this is an area that is clearly unclear…

In the context of PoS staking, this would mean that the smallest coinage that can be a kernel should be used. I dont think the miner is doing that now.

The best answer so far to why all winning blocks are treated as the same (other than it being much simpler to code) appears to be that making it random as to which of the tied winning block is extended makes it less predictable for an attacker. However, I think we can properly assume an attacker will devote more resources to propagating his block, so the first seen rule appears to make it much easier for an attacker to propagate his block and there is not much randomness to which tied block will win.

I agree that it increases security to not use the coinage (of kernel or block) for chainweight as that would provide a nearly deterministic trigger for an attacker’s reorg. And also, any not so active whale would inadvertently reorg many blocks if he ever generated a block but had bad connectivity for a while.

I think a tiebreaker only between identical length chains at the height where it forks would not increase the attack surface and in almost all cases prevent any forks beyond a depth of 1. Those being nearly impossible to prevent due to the simple fact of variable propagation times.

So the pseudo-code to resolve forks would be:

if ( chain_length(newchain) > chain_length(mainchain) )
   mainchain = newchain;
else if ( chain_length(newchain) == chain_length(mainchain) )
{
       forkheight = first_different_block(newchain,mainchain);
       if ( tiebreaker(newchain[forkheight],mainchain[forkheight]) > 0 )
          mainchain = newchain;
}

With the above, the behavior is the same in all cases except when there are more than 1 chains as long as the mainchain. And in that case, all the nodes would select the same block. There appear to be strong advantages to not letting the miner be able to figure out if his block would be the winner.

Tier Nolan wrote:
For deterministic mining, you could use something like

weight_block_n = [sum(all blocks in the tie) + hash_block_n] mod Target

Pick the block with the most weight.

This makes it so that a miner can’t determine if they will win a tie, in advance of the 2nd block being found. This keeps the incentive to broadcast as quickly as possible.

But I am still not clear what the best method to use.

James

Not sure I would go with it is working nicely. I can;t seem to get my wallet to reconnect to what is the mainchain. It connects to various peers who all have different heights and never gets to the mainchain…

21:10:47 getpeerinfo

[
{
“addr” : “142.4.218.174:9901”,
“services” : “00000001”,
“lastsend” : 1462248579,
“lastrecv” : 1462248446,
“conntime” : 1462238722,
“version” : 60006,
“subver” : “/Satoshi:0.6.3/Peercoin:0.5.3(v0.5.3ppc-beta)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 234750,
“banscore” : 0
},
{
“addr” : “95.31.245.215:9901”,
“services” : “00000001”,
“lastsend” : 1462248579,
“lastrecv” : 1462248565,
“conntime” : 1462238740,
“version” : 60004,
“subver” : “/Satoshi:0.6.3/Peercoin:0.4.0(v0.4.0ppc-beta)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 233848,
“banscore” : 0
},
{
“addr” : “114.55.38.142:9901”,
“services” : “00000001”,
“lastsend” : 1462248579,
“lastrecv” : 1462248579,
“conntime” : 1462238746,
“version” : 60006,
“subver” : “/Satoshi:0.6.3/Peercoin:0.5.2(v0.5.2ppc-beta)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 234695,
“banscore” : 0
},
{
“addr” : “93.80.182.24:9901”,
“services” : “00000001”,
“lastsend” : 1462248581,
“lastrecv” : 1462248243,
“conntime” : 1462238758,
“version” : 60006,
“subver” : “/Satoshi:0.6.3/Peercoin:0.5.0/Peerunity:0.2.1(v0.2.1)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 234750,
“banscore” : 0
},
{
“addr” : “212.83.172.152:9901”,
“services” : “00000001”,
“lastsend” : 1462248579,
“lastrecv” : 1462248446,
“conntime” : 1462238758,
“version” : 60006,
“subver” : “/Satoshi:0.6.3/Peercoin:0.5.3(v0.5.3ppc-beta)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 234695,
“banscore” : 0
},
{
“addr” : “94.143.245.5:9901”,
“services” : “00000001”,
“lastsend” : 1462248578,
“lastrecv” : 1462248578,
“conntime” : 1462238783,
“version” : 60006,
“subver” : “/Satoshi:0.6.3/Peercoin:0.5.3(v0.5.3ppc-beta)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 234695,
“banscore” : 0
},
{
“addr” : “86.2.16.66:9901”,
“services” : “00000001”,
“lastsend” : 1462248579,
“lastrecv” : 1462248476,
“conntime” : 1462238872,
“version” : 60006,
“subver” : “/Satoshi:0.6.3/Peercoin:0.5.0/Peerunity:0.2.0(v0.2.0)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 234702,
“banscore” : 0
},
{
“addr” : “73.3.210.99:9901”,
“services” : “00000001”,
“lastsend” : 1462248580,
“lastrecv” : 1462247520,
“conntime” : 1462247517,
“version” : 60004,
“subver” : “/Satoshi:0.6.3/Peercoin:0.4.0/Peerunity:0.1.3(v0.1.3-RC1-2-gb53729b)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 233813,
“banscore” : 0
}
]

00:51:14
getpeerinfo
00:51:14
[
{
“addr” : “219.82.21.7:9901”,
“services” : “00000001”,
“lastsend” : 1462250517,
“lastrecv” : 1462250526,
“conntime” : 1462250513,
“version” : 60004,
“subver” : “/Satoshi:0.6.3/Peercoin:0.4.0/Peerunity:0.1.3(v0.1.3-RC1-2-gb53729b)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 233917,
“banscore” : 0
},
{
“addr” : “64.15.77.36:9901”,
“services” : “00000001”,
“lastsend” : 1462250626,
“lastrecv” : 1462250516,
“conntime” : 1462250514,
“version” : 60004,
“subver” : “/Satoshi:0.6.3/Peercoin:0.4.0(v0.4.0ppc-beta)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 114993,
“banscore” : 0
},
{
“addr” : “192.0.204.166:9901”,
“services” : “00000001”,
“lastsend” : 1462250518,
“lastrecv” : 1462250618,
“conntime” : 1462250514,
“version” : 60006,
“subver” : “/Satoshi:0.6.3/Peercoin:0.5.0/Peerunity:0.2.0(v0.2.0)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 234712,
“banscore” : 0
},
{
“addr” : “107.170.209.76:9901”,
“services” : “00000001”,
“lastsend” : 1462250870,
“lastrecv” : 1462250858,
“conntime” : 1462250515,
“version” : 60006,
“subver” : “/Satoshi:0.6.3/Peercoin:0.5.3(v0.5.3ppc-beta)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 234768,
“banscore” : 0
},
{
“addr” : “198.245.63.205:9901”,
“services” : “00000001”,
“lastsend” : 1462250864,
“lastrecv” : 1462250858,
“conntime” : 1462250538,
“version” : 60006,
“subver” : “/Satoshi:0.6.3/Peercoin:0.5.2(v0.5.2ppc-beta)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 234768,
“banscore” : 0
},
{
“addr” : “83.84.24.180:9901”,
“services” : “00000001”,
“lastsend” : 1462250626,
“lastrecv” : 1462250637,
“conntime” : 1462250538,
“version” : 60006,
“subver” : “/Satoshi:0.6.3/Peercoin:0.5.0/Peerunity:0.2.0(v0.2.0)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 205559,
“banscore” : 0
},
{
“addr” : “188.165.254.191:9901”,
“services” : “00000001”,
“lastsend” : 1462250626,
“lastrecv” : 1462250633,
“conntime” : 1462250539,
“version” : 60004,
“subver” : “/Satoshi:0.6.3/Peercoin:0.4.0(v0.4.0.0-g4f3f5d8-beta)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 233848,
“banscore” : 0
},
{
“addr” : “176.9.113.75:9901”,
“services” : “00000001”,
“lastsend” : 1462250870,
“lastrecv” : 1462250869,
“conntime” : 1462250557,
“version” : 60006,
“subver” : “/Satoshi:0.6.3/Peercoin:0.5.0/Peerunity:0.2.0(v0.2.0)/”,
“inbound” : false,
“releasetime” : 0,
“height” : 234768,
“banscore” : 0
}
]

Obviously, there are too many bad versions on the networks:
Peercoin:0.4.0(v0.4.0ppc-beta)
Peercoin:0.5.2(v0.5.2ppc-beta)
Peerunity:0.2.0(v0.2.0)
Peercoin:0.4.0/Peerunity:0.1.3(v0.1.3-RC1-2-gb53729b)
Peercoin:0.5.0/Peerunity:0.2.0(v0.2.0)/

Our main task is still to ask Peercoiners to upgrade their wallets.

My two nodes are stuck on different block numbers: 234679 and 234699
I think the ppc network is broken right now. I decided to stop my pool until situation is solved.

We are trying to get our pool up, but have downloaded the blockchain 5 times now and it keep stopping short of the current block. very frustrating, all of my pool members have gone elsewhere, going to be hard to get them back… :frowning:

You have these issues due to bad connectivity to other nodes on the correct chain. Network connectivity will improve as more nodes update their software and get on the correct chain. On https://bitinfocharts.com/ppcoin/nodes-active/ you can get IP addresses for Peercoin 0.5.3 and Peerunity 0.2.1 nodes. Add ten of them to ppcoin.conf, with addnode= in front of the IP, to get good network connectivity. Put this node on the top line in your ppcoin.conf: addnode=178.248.97.26 I know for a fact that it is synced and will stay online. Now delete everything in your datadir except wallet.dat and ppcoin.conf before you start the client. After this you should not have any issues.

1 Like

I have updated my Peerunity and downloaded a fresh blockchain, successfully as far as I am aware. Prior to downloading, I deleted everything except wallet.dat

Regarding ppcoin.conf, I did not have such a file - should I have done?

[quote=“RobertLloyd, post:10, topic:3888”]I have updated my Peerunity and downloaded a fresh blockchain, successfully as far as I am aware. Prior to downloading, I deleted everything except wallet.dat

Regarding ppcoin.conf, I did not have such a file - should I have done?[/quote]

If you don’t get any checkpoint warnings you are good. The ppcoin.conf file you can make by renaming a .txt file. You don’t need to think about this since you seem to be up and running on the correct chain.

[quote=“jl777, post:4, topic:3888”][quote=“Sunny King, post:3, topic:3888”]It uses the proof-of-stake difficulty as the score of the block, see CBlockIndex::GetBlockTrust().

Since difficulty changes gradually, it appears that longer fork would win in general, disregarding the proof-of-work blocks on both forks.

The description in paper may not be accurate, this part of the protocol is introduced in v0.2 to improve blockchain security if I remember correctly.[/quote]
Yes, that is what I saw.

At any given height, the PoS difficulty is the same for any block that has a kernel that is below the required threshold. So, regardless of the coinage of the unspent that is the kernel, or the entire block’s coinage, all blocks found are treated equally.

Then the network propagation of these blocks would most strongly influence which block will be extended. I think a first seen rule is implicit, as once a node sees a valid block it will start trying to extend that one. I could not find anything in the code that uses coinage to prioritize a new block at the same height.

So, this would give a large advantage to a node that blasts his kernel to as many other nodes as possible. It also means that there can be two (or more) active chaintips. I raised this issue in https://bitcointalk.org/index.php?topic=355644.0 and it seems that this is an area that is clearly unclear…

In the context of PoS staking, this would mean that the smallest coinage that can be a kernel should be used. I dont think the miner is doing that now.

The best answer so far to why all winning blocks are treated as the same (other than it being much simpler to code) appears to be that making it random as to which of the tied winning block is extended makes it less predictable for an attacker. However, I think we can properly assume an attacker will devote more resources to propagating his block, so the first seen rule appears to make it much easier for an attacker to propagate his block and there is not much randomness to which tied block will win.

I agree that it increases security to not use the coinage (of kernel or block) for chainweight as that would provide a nearly deterministic trigger for an attacker’s reorg. And also, any not so active whale would inadvertently reorg many blocks if he ever generated a block but had bad connectivity for a while.

I think a tiebreaker only between identical length chains at the height where it forks would not increase the attack surface and in almost all cases prevent any forks beyond a depth of 1. Those being nearly impossible to prevent due to the simple fact of variable propagation times.

So the pseudo-code to resolve forks would be:

if ( chain_length(newchain) > chain_length(mainchain) )
   mainchain = newchain;
else if ( chain_length(newchain) == chain_length(mainchain) )
{
       forkheight = first_different_block(newchain,mainchain);
       if ( tiebreaker(newchain[forkheight],mainchain[forkheight]) > 0 )
          mainchain = newchain;
}

With the above, the behavior is the same in all cases except when there are more than 1 chains as long as the mainchain. And in that case, all the nodes would select the same block. There appear to be strong advantages to not letting the miner be able to figure out if his block would be the winner.

Tier Nolan wrote:
For deterministic mining, you could use something like

weight_block_n = [sum(all blocks in the tie) + hash_block_n] mod Target

Pick the block with the most weight.

This makes it so that a miner can’t determine if they will win a tie, in advance of the 2nd block being found. This keeps the incentive to broadcast as quickly as possible.

But I am still not clear what the best method to use.

James[/quote]

after the hectic days trying to get this thread back on topic :slight_smile:

bump

Gracias, thank you Sandakersmann. that solution works :D.

1 Like