• Forum has been upgraded, all links, images, etc are as they were. Please see Official Announcements for more information

Darkcoin is more centralized than we think?

Evil-Knievel

New member
Hi,

I am a holder of several thousand DRK, and I have taken some time to dig deeper into the DRK source code.
First of all, I have found the DOS attack on the masternodes list by sending TxVin's with varying nSequence number which allowed me to include as many entries as I wanted into the masternode list. Luckily this was quickly fixed.

But what I have found, is a lot more critical in my opinion.

The fact, that we have many distributed master nodes, does not imply full decentralization.

In fact, the masternode payments system works like this.
All masternodes periodically send their pings, to keep their position in the masternode list.
Then some "magical entity" elects the payee's which means the masternodes that will be payed in the next block. This is performed 10 Blocks in advance.

The fun thing is, that this election can ONLY BE DONE by the magical entity. If this entity vanished, no masternode payments will work anymore. More critically, this magical entity seems to be controlled by the developers of darkcoin.

More precisely, the "election of the winner" is signed in the function:
bool CMasternodePayments::Sign(CMasternodePaymentWinner& winner)
using the strMasterPrivKey.

The signature of such election/consensus votings must come from the
HARDCODED PUBKEY:

const std::string CSyncCheckpoint::strMainPubKey = "04bcba2b149fe9d54f218208dd02aecd7b2245ef21c937207966f0814365b4d1c5d521d001f2df294bafb0fbe5ee4c3290b0c25bff8fdd886b6e3e9317758a7d75";



Now my question is, who is controlling this PublicKey, why is the whole system depending on the presence of the entity controlling the pubkey? How are you planning to AVOID THE CENTRALIZATION?
 
Hi,

I am a holder of several thousand DRK, and I have taken some time to dig deeper into the DRK source code.
First of all, I have found the DOS attack on the masternodes list by sending TxVin's with varying nSequence number which allowed me to include as many entries as I wanted into the masternode list. Luckily this was quickly fixed.

But what I have found, is a lot more critical in my opinion.

The fact, that we have many distributed master nodes, does not imply full decentralization.

In fact, the masternode payments system works like this.
All masternodes periodically send their pings, to keep their position in the masternode list.
Then some "magical entity" elects the payee's which means the masternodes that will be payed in the next block. This is performed 10 Blocks in advance.

The fun thing is, that this election can ONLY BE DONE by the magical entity. If this entity vanished, no masternode payments will work anymore. More critically, this magical entity seems to be controlled by the developers of darkcoin.

More precisely, the "election of the winner" is signed in the function:
bool CMasternodePayments::Sign(CMasternodePaymentWinner& winner)
using the strMasterPrivKey.

The signature of such election/consensus votings must come from the
HARDCODED PUBKEY:

const std::string CSyncCheckpoint::strMainPubKey = "04bcba2b149fe9d54f218208dd02aecd7b2245ef21c937207966f0814365b4d1c5d521d001f2df294bafb0fbe5ee4c3290b0c25bff8fdd886b6e3e9317758a7d75";



Now my question is, who is controlling this PublicKey, why is the whole system depending on the presence of the entity controlling the pubkey? How are you planning to AVOID THE CENTRALIZATION?
I think the answer to your question is here: https://darkcointalk.org/threads/v0-15-testing.2611/page-28#post-25405

And here: https://darkcointalk.org/threads/v0-15-testing.2611/page-28#post-25407
 
Thank you for the pointer.
I will get a steaming cup of coffee and read the complete thread right now.
At the first glance, this looks like one of the major issues to me.
 
This is just a temporary solution to ensure equal payments to masternode owners until a new voting system is implemented, and was publicly presented in Onyx Release's announcement post (see reference nodes).
Also, they have nothing to do with the network's security, and putting them down would simply re-establish random payments to masternode owners.
 
This is just a temporary solution to ensure equal payments to masternode owners until a new voting system is implemented, and was publicly presented in Onyx Release's announcement post (see reference nodes).
Also, they have nothing to do with the network's security, and putting them down would simply re-establish random payments to masternode owners.
This... +1

@OP Evan already explained that these nodes are ONLY for ensuring even payments (payments are random if the node is down or compromised) and controlling them gives you NO advantage over the network. Furthermore this will be improved later.

The discovery here is an issue that has already been thoroughly discussed and put to bed.
 
Thank you for the pointer.
I will get a steaming cup of coffee and read the complete thread right now.
At the first glance, this looks like one of the major issues to me.
No problem. I thought it'd be best to point to the source rather than from hearsay. It's all in that testing thread. Happy reading! :)
 
The fun thing is, that this election can ONLY BE DONE by the magical entity. If this entity vanished, no masternode payments will work anymore. More critically, this magical entity seems to be controlled by the developers of darkcoin.

As others already pointed out, this was already discussed and is a temporary solution.

If the entities (there are several) vanished the network would simply fall-back to the random payment distribution we have now.
You're completely right with your second conclusion, when this goes active the developers could in fact influence who's paid how often and who's not.

This unnecessary centralization is a concern I and several others have already communicated and it will certainly be addressed in the future.
 
You're completely right with your second conclusion, when this goes active the developers could in fact influence who's paid how often and who's not.
Very right, though I'd like to point out the fact that masternode payments, just like any transaction, are publicly visible. And Darksend or not, masternode owners will always be able to know how much they should have been paid based on the number of generated blocks, and what they actually receive.
The developers going rogue on masternode payments would simply make masternode owners dump their holdings and kill the coin's reputation and value.
I think we can fairly admit that there would be so many better options for the devs to scam everyone and causing the coin's death themselves :')

Still, don't take me wrong, I also believe that any form of centralisation should not be kept in the long haul, but this one is not critical with respect to the network's security, and is planned to be addressed in the future, so I think it can be kept aside for now regarding the current agenda and InstantX in the works!
 
I will get a steaming cup of coffee and read the complete thread right now.
Hey Knievel, your hack has already earned yourself just short of half a masternode up to now. If, while drinking your coffee, you can think of an easy-to-implement solution that gets rid of the temporary reference node without resorting to solutions Evan already mentioned while still assuring that the system stays

- Non-exploitable masternode payments (Currently miners can pay their own masternode every single time)
- Completely deterministic round-robin
- 100% compatible with proof-of-service ,

then I'm quite convinced the community will raise the remaining half of the masternode as a reward.

I know you're not doing it for the money, but just trying to give your reading effort more purpose :)
 
Last edited by a moderator:
Hey Knievel, your hack has already earned yourself just short of half a masternode up to now. If, while drinking your coffee, you can think of an easy-to-implement solution that gets rid of the temporary reference node without resorting to solutions Evan already mentioned while still assuring that the system stays

- Non-exploitable masternode payments (Currently miners can pay their own masternode every single time)
- Completely deterministic round-robin
- 100% compatible with proof-of-service ,

then I'm quite convinced the community will raise the remaining half of the masternode as a reward.

I know you're not doing it for the money, but just trying to give your reading effort more purpose :)
He did not claim to be XwzmEE1cJ6HG84CgJvAt7ADmJ - Evil-Knievels' hack was different and had no negative effects but a bloated masternode list.
 
I have found a bug in the "centralized masternode winner" Algorithm by the way.
Included CTxIn are just checked for having 1000 DRK, but not if they are already spent or not.

This would allow the Uber-Node to include Winning-Masternodes which no longer have a valid TxIn.
 
I have found a bug in the "centralized masternode winner" Algorithm by the way.
Included CTxIn are just checked for having 1000 DRK, but not if they are already spent or not.

This would allow the Uber-Node to include Winning-Masternodes which no longer have a valid TxIn.
Please report to Evan: [email protected]

Thank you.
 
Did that,
for transparency reasons, here the relevant code part which clearly allows spent TxIn for the Block Payees.
I originally thought that we all can submit the consensus vote, so I was sending around many 1000 DRK transactions to have enough inputs for winning every vote. Then I realized I need the Ubernode-Privkey ;-)

However, this should be fixed.

bool CMasternodePayments::GetBlockPayee(int nBlockHeight, CScript& payee)
{
BOOST_FOREACH(CMasternodePaymentWinner& winner, vWinning){
if(winner.nBlockHeight == nBlockHeight) {

CTransaction tx;
uint256 hash;
if(GetTransaction(winner.vin.prevout.hash, tx, hash, true)){
BOOST_FOREACH(CTxOut out, tx.vout){
if(out.nValue == 1000*COIN){
payee = out.scriptPubKey;
return true;
}
}
}

return true;
}
}
return false;
}
 
Did that,
for transparency reasons, here the relevant code part which clearly allows spent TxIn for the Block Payees.
I originally thought that we all can submit the consensus vote, so I was sending around many 1000 DRK transactions to have enough inputs for winning every vote. Then I realized I need the Ubernode-Privkey ;-)

However, this should be fixed.

bool CMasternodePayments::GetBlockPayee(int nBlockHeight, CScript& payee)
{
BOOST_FOREACH(CMasternodePaymentWinner& winner, vWinning){
if(winner.nBlockHeight == nBlockHeight) {

CTransaction tx;
uint256 hash;
if(GetTransaction(winner.vin.prevout.hash, tx, hash, true)){
BOOST_FOREACH(CTxOut out, tx.vout){
if(out.nValue == 1000*COIN){
payee = out.scriptPubKey;
return true;
}
}
}

return true;
}
}
return false;
}
Are you looking through all of the code? Have you found anything with the Darksend code?
 
Did that,
for transparency reasons, here the relevant code part which clearly allows spent TxIn for the Block Payees.
I originally thought that we all can submit the consensus vote, so I was sending around many 1000 DRK transactions to have enough inputs for winning every vote. Then I realized I need the Ubernode-Privkey ;-)

However, this should be fixed.

bool CMasternodePayments::GetBlockPayee(int nBlockHeight, CScript& payee)
{
BOOST_FOREACH(CMasternodePaymentWinner& winner, vWinning){
if(winner.nBlockHeight == nBlockHeight) {

CTransaction tx;
uint256 hash;
if(GetTransaction(winner.vin.prevout.hash, tx, hash, true)){
BOOST_FOREACH(CTxOut out, tx.vout){
if(out.nValue == 1000*COIN){
payee = out.scriptPubKey;
return true;
}
}
}

return true;
}
}
return false;
}
If you've found a bug we should all tip you to say thanks...
 
Well it is not a bug that can be used practically by the users, but it is a bug which could allow an Ubernode to elect anyone as a masternode payee even if
a) the guy is not in the masternode list
b) even if the 1000 DRK TxIn is long spent

So sending around 1000 DRK many times to different addresses creates many valid TxIn Transactions (that of course are spent).
So here we have to TRUST the Ubernodes to do the correct thing.

Better would be to add additional checks to keep the system trustless.

Tips are welcome anyway ;-)
XuweR8VEhesiq7mY9ny59xNnK3SpLQWr67

I am going through the rest of the code now.
 
Did that,
for transparency reasons, here the relevant code part which clearly allows spent TxIn for the Block Payees.
I originally thought that we all can submit the consensus vote, so I was sending around many 1000 DRK transactions to have enough inputs for winning every vote. Then I realized I need the Ubernode-Privkey ;-)

However, this should be fixed.

bool CMasternodePayments::GetBlockPayee(int nBlockHeight, CScript& payee)
{
BOOST_FOREACH(CMasternodePaymentWinner& winner, vWinning){
if(winner.nBlockHeight == nBlockHeight) {

CTransaction tx;
uint256 hash;
if(GetTransaction(winner.vin.prevout.hash, tx, hash, true)){
BOOST_FOREACH(CTxOut out, tx.vout){
if(out.nValue == 1000*COIN){
payee = out.scriptPubKey;
return true;
}
}
}

return true;
}
}
return false;
}

You're right, there should be a more explicit check. However, it checks and removes invalid nodes in ThreadCheckDarksendPool() every 60 seconds. But the check shouldn't be in GetBlockPayee, someone could wait till the last second before the block is solved and possibly fork the network if they owned that input.

Patched: https://github.com/darkcoin/darkcoin/commit/bbc819d8c2ee76a07c1201f5e2c5a27c9ed194a3
 
Last edited by a moderator:
Well it is not a bug that can be used practically by the users, but it is a bug which could allow an Ubernode to elect anyone as a masternode payee even if
a) the guy is not in the masternode list
b) even if the 1000 DRK TxIn is long spent

So sending around 1000 DRK many times to different addresses creates many valid TxIn Transactions (that of course are spent).
So here we have to TRUST the Ubernodes to do the correct thing.

Better would be to add additional checks to keep the system trustless.

Tips are welcome anyway ;-)
XuweR8VEhesiq7mY9ny59xNnK3SpLQWr67

I am going through the rest of the code now.

The algorithm the reference node uses is deterministic, you or anyone else can run the code and compare the "masternode winners". The list should be the same. But I completely agree, it needs to go. Writing the payment system to be completely trustless and non-exploitable has proven very difficult.
 
Back
Top