@E-K

How do you solve the so called 'Nothing @ Stake' problem if with NXT style POS(i did not much clear about how NXT slove this also)?

Thanks.

How do you solve the so called 'Nothing @ Stake' problem if with NXT style POS(i did not much clear about how NXT slove this also)?

Thanks.

I would suggest the following change to the NXT scheme.

As we have already discussed, that it's better that the personal raises exponentially (doubles every 7 seconds) rather than linearity (for NXT it increases by the amount of your stake every second), we can be sure that the maximum possible target will be *never* reached later than in 30 minutes.

What if we allow

**everyone, even those without any stake,**to solve PoS blocks once one particular target reaches its highest possible value.

Highest possible value would mean "T=UINT64_MAX" and any other block's PoS hash H is by nature "H<=T".

To reflect the worst case, accounts that have no stake value, indeed do participate in the PoS, but differently.

Their base_target is 1, and their personal_target also starts with 1, their PoS hash is assumed to be UINT64_MAX, and their personal target is doubling every 7 seconds. If there is at least one account with a stake he will find the block instead, for sure.

Otherwise, after 30 minutes (and not before), an account without stake can generate a block when the target has reached UINT64_MAX.

Right now, regular accounts calculate their current target value like this:

Code:

double balance = getCurrentStakeBalance();

double personal_target = base_target * balance;

if(personal_target < base_target || personal_target > max_target)

personal_target = max_target;

if(personal_target != max_target){

// Now increase exponentially so that target doubles every 7 seconds. This ensures that even if target is 1 (worst case) a block will be found after 30 minutes max.

double factor = pow(2, (1.0/7.0)*time_diff_to_last_block);

// TODO, correct to handle integer overflow this way?

double new_target = personal_target * factor;

if(new_target<personal_target){

personal_target = max_target;

}else{

personal_target = new_target;

}

}

double personal_target = base_target * balance;

if(personal_target < base_target || personal_target > max_target)

personal_target = max_target;

if(personal_target != max_target){

// Now increase exponentially so that target doubles every 7 seconds. This ensures that even if target is 1 (worst case) a block will be found after 30 minutes max.

double factor = pow(2, (1.0/7.0)*time_diff_to_last_block);

// TODO, correct to handle integer overflow this way?

double new_target = personal_target * factor;

if(new_target<personal_target){

personal_target = max_target;

}else{

personal_target = new_target;

}

}

we would need a change like this (see the else branch that calculated 0-stake target value starting from 1 and so reflecting the worst case. Furthermore, it can only stake once the worst case itself has been reached, i.e., die target has gone past uint64_max):

Code:

double balance = getCurrentStakeBalance();

if(balance > 0){

double personal_target = base_target * balance;

if(personal_target < base_target || personal_target > max_target)

personal_target = max_target;

if(personal_target != max_target){

// Now increase exponentially so that target doubles every 7 seconds. This ensures that even if target is 1 (worst case) a block will be found after 30 minutes max.

double factor = pow(2, (1.0/7.0)*time_diff_to_last_block);

// TODO, correct to handle integer overflow this way?

double new_target = personal_target * factor;

if(new_target<personal_target){ // just the integer overflow handler

personal_target = max_target;

}else{

personal_target = new_target;

}

}

}

else{

double personal_target = 1;

double factor = pow(2, (1.0/7.0)*time_diff_to_last_block);

double new_target = personal_target * factor;

if(new_target<personal_target){ // just the integer overflow handler

personal_target = max_target;

}else{

personal_target = 0; // Only if gone past max_target balance=0 account can stake

}

}

if(balance > 0){

double personal_target = base_target * balance;

if(personal_target < base_target || personal_target > max_target)

personal_target = max_target;

if(personal_target != max_target){

// Now increase exponentially so that target doubles every 7 seconds. This ensures that even if target is 1 (worst case) a block will be found after 30 minutes max.

double factor = pow(2, (1.0/7.0)*time_diff_to_last_block);

// TODO, correct to handle integer overflow this way?

double new_target = personal_target * factor;

if(new_target<personal_target){ // just the integer overflow handler

personal_target = max_target;

}else{

personal_target = new_target;

}

}

}

else{

double personal_target = 1;

double factor = pow(2, (1.0/7.0)*time_diff_to_last_block);

double new_target = personal_target * factor;

if(new_target<personal_target){ // just the integer overflow handler

personal_target = max_target;

}else{

personal_target = 0; // Only if gone past max_target balance=0 account can stake

}

}