The testnet is almost ready, I will test for ~2 hours locally and then release it!
Note to the devs in here:
We need a better (more easy to understand) miner with multiple "policies" such as "mining the work with greatest bounty fund", "mining with best POW reward", "etc."
Also, we need to have a thread where we can put specific development questions up for discussion. Like this one here:
Can you all please check if the POW target value retargetting mechanism makes sence?
We aim for having 10 POW submissions per block, so we average over the last 3 blocks and calculate a "factor" by which the POW target value is scaled (the value is capped at 25% up or down).
Any obvious flaws with this?
POWRETARGET_N_BLOCKS = 3 ... 3 blocks sliding window
POWRETARGET_POW_PER_BLOCK_SCALER = 10 ... 10 POW submissions per block public static BigInteger calculateNextMinPowTarget(long lastBlockId) {
System.out.println("entrance");
// First check in cache
BigInteger cached = powDifficultyLRUCache.get(lastBlockId);
if(cached != null)
return cached;
// Genesis specialty
if (lastBlockId == 0)
return Constants.least_possible_target;
Block b = Nxt.getBlockchain().getBlock(lastBlockId);
// try to cycle over the last N blocks, or - if height is smaller -
// over entire blockchain
int go_back_counter = Math.min(Constants.POWRETARGET_N_BLOCKS, b.getHeight());
int original_back_counter = go_back_counter;
// ... and count the number of PoW transactions inside those blocks
int pow_counter = 0;
BigInteger last_pow_target = b.getMinPowTarget();
while (go_back_counter > 0) {
pow_counter += b.countNumberPOW();
b = b.getPreviousBlock();
go_back_counter -= 1;
}
// scale up if there are not yet N blocks there, avoids MADNESS
if(original_back_counter
double scaledCounter = (double)pow_counter;
scaledCounter = scaledCounter / (1.0*original_back_counter);
scaledCounter = scaledCounter * Constants.POWRETARGET_N_BLOCKS;
pow_counter = (int)scaledCounter;
}
// if no PoW was sent during last n blocks, something is strange, give
// back the lowest possible target
if (pow_counter == 0){
pow_counter = 1; // dirty ugly fix
}
// Check the needed adjustment here, but make sure we do not adjust more
// than * 2 or /2.
// This will prevent huge difficulty jumps, yet it will quickly
// (exponentially) approxiamate the desired number
// of PoW packages per block.
BigDecimal new_pow_target = new BigDecimal(last_pow_target);
double factor = (double)(Constants.POWRETARGET_N_BLOCKS * Constants.POWRETARGET_POW_PER_BLOCK_SCALER) / (double)pow_counter; // RETARGETING
System.out.println("Retargetting: Had POW " + pow_counter + " should be " + ((Constants.POWRETARGET_N_BLOCKS * Constants.POWRETARGET_POW_PER_BLOCK_SCALER)) + ", scaling by factor " + factor);
// limits, we do not want to change the target too CRAZY at once
if (factor > 1.25)
factor = 1.25;
if (factor < 0.75)
factor = (double) 0.75;
BigDecimal factorDec = new BigDecimal(factor);
// Apply the retarget: Adjust target so that we again - on average -
// reach n PoW per block
new_pow_target = new_pow_target.multiply(factorDec);
BigInteger converted_new_pow = new_pow_target.toBigInteger();
if(converted_new_pow.compareTo(Constants.least_possible_target)==1) converted_new_pow = Constants.least_possible_target;
powDifficultyLRUCache.set(lastBlockId, converted_new_pow);
return converted_new_pow;
}