mirror of
https://github.com/Qortal/qortal.git
synced 2025-07-23 04:36:50 +00:00
Added shareBinsByLevelV2.
This allows for different share bin distribution starting at an undecided future block height. This height will correspond with the QORA reduction. New values decided in recent community vote.
This commit is contained in:
@@ -10,7 +10,6 @@ import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.MessageFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -185,8 +184,11 @@ public class Block {
|
||||
if (accountLevel <= 0)
|
||||
return null; // level 0 isn't included in any share bins
|
||||
|
||||
// Select the correct set of share bins based on block height
|
||||
final BlockChain blockChain = BlockChain.getInstance();
|
||||
final AccountLevelShareBin[] shareBinsByLevel = blockChain.getShareBinsByAccountLevel();
|
||||
final AccountLevelShareBin[] shareBinsByLevel = (blockHeight >= blockChain.getSharesByLevelV2Height()) ?
|
||||
blockChain.getShareBinsByAccountLevelV2() : blockChain.getShareBinsByAccountLevelV1();
|
||||
|
||||
if (accountLevel > shareBinsByLevel.length)
|
||||
return null;
|
||||
|
||||
@@ -1896,10 +1898,14 @@ public class Block {
|
||||
final List<ExpandedAccount> onlineFounderAccounts = expandedAccounts.stream().filter(expandedAccount -> expandedAccount.isMinterFounder).collect(Collectors.toList());
|
||||
final boolean haveFounders = !onlineFounderAccounts.isEmpty();
|
||||
|
||||
// Select the correct set of share bins based on block height
|
||||
List<AccountLevelShareBin> accountLevelShareBinsForBlock = (this.blockData.getHeight() >= BlockChain.getInstance().getSharesByLevelV2Height()) ?
|
||||
BlockChain.getInstance().getAccountLevelShareBinsV2() : BlockChain.getInstance().getAccountLevelShareBinsV1();
|
||||
|
||||
// Determine reward candidates based on account level
|
||||
// This needs a deep copy, so the shares can be modified when tiers aren't activated yet
|
||||
List<AccountLevelShareBin> accountLevelShareBins = new ArrayList<>();
|
||||
for (AccountLevelShareBin accountLevelShareBin : BlockChain.getInstance().getAccountLevelShareBins()) {
|
||||
for (AccountLevelShareBin accountLevelShareBin : accountLevelShareBinsForBlock) {
|
||||
accountLevelShareBins.add((AccountLevelShareBin) accountLevelShareBin.clone());
|
||||
}
|
||||
|
||||
|
@@ -68,6 +68,7 @@ public class BlockChain {
|
||||
atFindNextTransactionFix,
|
||||
newBlockSigHeight,
|
||||
shareBinFix,
|
||||
sharesByLevelV2Height,
|
||||
rewardShareLimitTimestamp,
|
||||
calcChainWeightTimestamp,
|
||||
transactionV5Timestamp,
|
||||
@@ -122,9 +123,11 @@ public class BlockChain {
|
||||
return shareBinCopy;
|
||||
}
|
||||
}
|
||||
private List<AccountLevelShareBin> sharesByLevel;
|
||||
private List<AccountLevelShareBin> sharesByLevelV1;
|
||||
private List<AccountLevelShareBin> sharesByLevelV2;
|
||||
/** Generated lookup of share-bin by account level */
|
||||
private AccountLevelShareBin[] shareBinsByLevel;
|
||||
private AccountLevelShareBin[] shareBinsByLevelV1;
|
||||
private AccountLevelShareBin[] shareBinsByLevelV2;
|
||||
|
||||
/** Share of block reward/fees to legacy QORA coin holders, by block height */
|
||||
public static class ShareByHeight {
|
||||
@@ -370,12 +373,20 @@ public class BlockChain {
|
||||
return this.rewardsByHeight;
|
||||
}
|
||||
|
||||
public List<AccountLevelShareBin> getAccountLevelShareBins() {
|
||||
return this.sharesByLevel;
|
||||
public List<AccountLevelShareBin> getAccountLevelShareBinsV1() {
|
||||
return this.sharesByLevelV1;
|
||||
}
|
||||
|
||||
public AccountLevelShareBin[] getShareBinsByAccountLevel() {
|
||||
return this.shareBinsByLevel;
|
||||
public List<AccountLevelShareBin> getAccountLevelShareBinsV2() {
|
||||
return this.sharesByLevelV2;
|
||||
}
|
||||
|
||||
public AccountLevelShareBin[] getShareBinsByAccountLevelV1() {
|
||||
return this.shareBinsByLevelV1;
|
||||
}
|
||||
|
||||
public AccountLevelShareBin[] getShareBinsByAccountLevelV2() {
|
||||
return this.shareBinsByLevelV2;
|
||||
}
|
||||
|
||||
public List<Integer> getBlocksNeededByLevel() {
|
||||
@@ -444,6 +455,10 @@ public class BlockChain {
|
||||
return this.featureTriggers.get(FeatureTrigger.shareBinFix.name()).intValue();
|
||||
}
|
||||
|
||||
public int getSharesByLevelV2Height() {
|
||||
return this.featureTriggers.get(FeatureTrigger.sharesByLevelV2Height.name()).intValue();
|
||||
}
|
||||
|
||||
public long getRewardShareLimitTimestamp() {
|
||||
return this.featureTriggers.get(FeatureTrigger.rewardShareLimitTimestamp.name()).longValue();
|
||||
}
|
||||
@@ -521,8 +536,11 @@ public class BlockChain {
|
||||
if (this.rewardsByHeight == null)
|
||||
Settings.throwValidationError("No \"rewardsByHeight\" entry found in blockchain config");
|
||||
|
||||
if (this.sharesByLevel == null)
|
||||
Settings.throwValidationError("No \"sharesByLevel\" entry found in blockchain config");
|
||||
if (this.sharesByLevelV1 == null)
|
||||
Settings.throwValidationError("No \"sharesByLevelV1\" entry found in blockchain config");
|
||||
|
||||
if (this.sharesByLevelV2 == null)
|
||||
Settings.throwValidationError("No \"sharesByLevelV2\" entry found in blockchain config");
|
||||
|
||||
if (this.qoraHoldersShareByHeight == null)
|
||||
Settings.throwValidationError("No \"qoraHoldersShareByHeight\" entry found in blockchain config");
|
||||
@@ -562,13 +580,22 @@ public class BlockChain {
|
||||
if (!this.featureTriggers.containsKey(featureTrigger.name()))
|
||||
Settings.throwValidationError(String.format("Missing feature trigger \"%s\" in blockchain config", featureTrigger.name()));
|
||||
|
||||
// Check block reward share bounds
|
||||
long totalShare = this.getQoraHoldersShareAtHeight(1);
|
||||
// Check block reward share bounds (V1)
|
||||
long totalShareV1 = this.qoraHoldersShareByHeight.get(0).share;
|
||||
// Add share percents for account-level-based rewards
|
||||
for (AccountLevelShareBin accountLevelShareBin : this.sharesByLevel)
|
||||
totalShare += accountLevelShareBin.share;
|
||||
for (AccountLevelShareBin accountLevelShareBin : this.sharesByLevelV1)
|
||||
totalShareV1 += accountLevelShareBin.share;
|
||||
|
||||
if (totalShare < 0 || totalShare > 1_00000000L)
|
||||
if (totalShareV1 < 0 || totalShareV1 > 1_00000000L)
|
||||
Settings.throwValidationError("Total non-founder share out of bounds (0<x<1e8)");
|
||||
|
||||
// Check block reward share bounds (V2)
|
||||
long totalShareV2 = this.qoraHoldersShareByHeight.get(1).share;
|
||||
// Add share percents for account-level-based rewards
|
||||
for (AccountLevelShareBin accountLevelShareBin : this.sharesByLevelV2)
|
||||
totalShareV2 += accountLevelShareBin.share;
|
||||
|
||||
if (totalShareV2 < 0 || totalShareV2 > 1_00000000L)
|
||||
Settings.throwValidationError("Total non-founder share out of bounds (0<x<1e8)");
|
||||
}
|
||||
|
||||
@@ -584,20 +611,30 @@ public class BlockChain {
|
||||
cumulativeBlocks += this.blocksNeededByLevel.get(level);
|
||||
}
|
||||
|
||||
// Generate lookup-array for account-level share bins
|
||||
AccountLevelShareBin lastAccountLevelShareBin = this.sharesByLevel.get(this.sharesByLevel.size() - 1);
|
||||
final int lastLevel = lastAccountLevelShareBin.levels.get(lastAccountLevelShareBin.levels.size() - 1);
|
||||
this.shareBinsByLevel = new AccountLevelShareBin[lastLevel];
|
||||
|
||||
for (AccountLevelShareBin accountLevelShareBin : this.sharesByLevel)
|
||||
// Generate lookup-array for account-level share bins (V1)
|
||||
AccountLevelShareBin lastAccountLevelShareBinV1 = this.sharesByLevelV1.get(this.sharesByLevelV1.size() - 1);
|
||||
final int lastLevelV1 = lastAccountLevelShareBinV1.levels.get(lastAccountLevelShareBinV1.levels.size() - 1);
|
||||
this.shareBinsByLevelV1 = new AccountLevelShareBin[lastLevelV1];
|
||||
for (AccountLevelShareBin accountLevelShareBin : this.sharesByLevelV1)
|
||||
for (int level : accountLevelShareBin.levels)
|
||||
// level 1 stored at index 0, level 2 stored at index 1, etc.
|
||||
// level 0 not allowed
|
||||
this.shareBinsByLevel[level - 1] = accountLevelShareBin;
|
||||
this.shareBinsByLevelV1[level - 1] = accountLevelShareBin;
|
||||
|
||||
// Generate lookup-array for account-level share bins (V2)
|
||||
AccountLevelShareBin lastAccountLevelShareBinV2 = this.sharesByLevelV2.get(this.sharesByLevelV2.size() - 1);
|
||||
final int lastLevelV2 = lastAccountLevelShareBinV2.levels.get(lastAccountLevelShareBinV2.levels.size() - 1);
|
||||
this.shareBinsByLevelV2 = new AccountLevelShareBin[lastLevelV2];
|
||||
for (AccountLevelShareBin accountLevelShareBin : this.sharesByLevelV2)
|
||||
for (int level : accountLevelShareBin.levels)
|
||||
// level 1 stored at index 0, level 2 stored at index 1, etc.
|
||||
// level 0 not allowed
|
||||
this.shareBinsByLevelV2[level - 1] = accountLevelShareBin;
|
||||
|
||||
// Convert collections to unmodifiable form
|
||||
this.rewardsByHeight = Collections.unmodifiableList(this.rewardsByHeight);
|
||||
this.sharesByLevel = Collections.unmodifiableList(this.sharesByLevel);
|
||||
this.sharesByLevelV1 = Collections.unmodifiableList(this.sharesByLevelV1);
|
||||
this.sharesByLevelV2 = Collections.unmodifiableList(this.sharesByLevelV2);
|
||||
this.blocksNeededByLevel = Collections.unmodifiableList(this.blocksNeededByLevel);
|
||||
this.cumulativeBlocksByLevel = Collections.unmodifiableList(this.cumulativeBlocksByLevel);
|
||||
this.blockTimingsByHeight = Collections.unmodifiableList(this.blockTimingsByHeight);
|
||||
|
@@ -39,13 +39,20 @@
|
||||
{ "height": 2851201, "reward": 2.25 },
|
||||
{ "height": 3110401, "reward": 2.00 }
|
||||
],
|
||||
"sharesByLevel": [
|
||||
"sharesByLevelV1": [
|
||||
{ "id": 1, "levels": [ 1, 2 ], "share": 0.05 },
|
||||
{ "id": 2, "levels": [ 3, 4 ], "share": 0.10 },
|
||||
{ "id": 3, "levels": [ 5, 6 ], "share": 0.15 },
|
||||
{ "id": 4, "levels": [ 7, 8 ], "share": 0.20 },
|
||||
{ "id": 5, "levels": [ 9, 10 ], "share": 0.25 }
|
||||
],
|
||||
"sharesByLevelV2": [
|
||||
{ "id": 1, "levels": [ 1, 2 ], "share": 0.06 },
|
||||
{ "id": 2, "levels": [ 3, 4 ], "share": 0.13 },
|
||||
{ "id": 3, "levels": [ 5, 6 ], "share": 0.19 },
|
||||
{ "id": 4, "levels": [ 7, 8 ], "share": 0.26 },
|
||||
{ "id": 5, "levels": [ 9, 10 ], "share": 0.32 }
|
||||
],
|
||||
"qoraHoldersShareByHeight": [
|
||||
{ "height": 1, "share": 0.20 },
|
||||
{ "height": 9999999, "share": 0.01 }
|
||||
@@ -67,6 +74,7 @@
|
||||
"atFindNextTransactionFix": 275000,
|
||||
"newBlockSigHeight": 320000,
|
||||
"shareBinFix": 399000,
|
||||
"sharesByLevelV2Height": 9999999,
|
||||
"rewardShareLimitTimestamp": 1657382400000,
|
||||
"calcChainWeightTimestamp": 1620579600000,
|
||||
"transactionV5Timestamp": 1642176000000,
|
||||
|
Reference in New Issue
Block a user