forked from Qortal/qortal
Fix new account level not taking effect in block rewards
Added encoded online accounts list decoder.
This commit is contained in:
parent
30df320e7f
commit
49ac7921a1
105
src/main/java/org/qora/DecodeOnlineAccounts.java
Normal file
105
src/main/java/org/qora/DecodeOnlineAccounts.java
Normal file
@ -0,0 +1,105 @@
|
||||
package org.qora;
|
||||
|
||||
import java.security.Security;
|
||||
|
||||
import org.bitcoinj.core.Base58;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider;
|
||||
import org.qora.block.BlockChain;
|
||||
import org.qora.controller.Controller;
|
||||
import org.qora.data.account.RewardShareData;
|
||||
import org.qora.gui.Gui;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.Repository;
|
||||
import org.qora.repository.RepositoryFactory;
|
||||
import org.qora.repository.RepositoryManager;
|
||||
import org.qora.repository.hsqldb.HSQLDBRepositoryFactory;
|
||||
import org.qora.settings.Settings;
|
||||
import org.qora.transform.block.BlockTransformer;
|
||||
import org.roaringbitmap.IntIterator;
|
||||
|
||||
import io.druid.extendedset.intset.ConciseSet;
|
||||
|
||||
public class DecodeOnlineAccounts {
|
||||
|
||||
private static void usage() {
|
||||
System.err.println("Usage: DecodeOnlineAccounts [<settings-file>] <base58-encoded-accounts>");
|
||||
System.err.println("Example: DecodeOnlineAccounts 4GmR5B");
|
||||
System.err.println("Example: DecodeOnlineAccounts settings-test.json 4GmR5B");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (args.length < 1 || args.length > 2)
|
||||
usage();
|
||||
|
||||
byte[] encodedOnlineAccounts = Base58.decode(args[args.length - 1]);
|
||||
|
||||
ConciseSet accountIndexes = BlockTransformer.decodeOnlineAccounts(encodedOnlineAccounts);
|
||||
|
||||
String delimiter = "";
|
||||
System.out.print("Account indexes: ");
|
||||
|
||||
IntIterator iterator = accountIndexes.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
int accountIndex = iterator.next();
|
||||
|
||||
System.out.print(String.format("%s%d", delimiter, accountIndex));
|
||||
delimiter = ", ";
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
Security.insertProviderAt(new BouncyCastleProvider(), 0);
|
||||
Security.insertProviderAt(new BouncyCastleJsseProvider(), 1);
|
||||
|
||||
// Load/check settings, which potentially sets up blockchain config, etc.
|
||||
try {
|
||||
if (args.length > 1)
|
||||
Settings.fileInstance(args[0]);
|
||||
else
|
||||
Settings.getInstance();
|
||||
} catch (Throwable t) {
|
||||
Gui.getInstance().fatalError("Settings file", t.getMessage());
|
||||
return; // Not System.exit() so that GUI can display error
|
||||
}
|
||||
|
||||
try {
|
||||
RepositoryFactory repositoryFactory = new HSQLDBRepositoryFactory(Controller.getRepositoryUrl());
|
||||
RepositoryManager.setRepositoryFactory(repositoryFactory);
|
||||
} catch (DataException e) {
|
||||
System.err.println("Couldn't connect to repository: " + e.getMessage());
|
||||
System.exit(2);
|
||||
}
|
||||
|
||||
try {
|
||||
BlockChain.validate();
|
||||
} catch (DataException e) {
|
||||
System.err.println("Couldn't validate repository: " + e.getMessage());
|
||||
System.exit(2);
|
||||
}
|
||||
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
iterator = accountIndexes.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
int accountIndex = iterator.next();
|
||||
|
||||
RewardShareData rewardShareData = repository.getAccountRepository().getRewardShareByIndex(accountIndex);
|
||||
|
||||
System.out.println(String.format("Reward-share public key: %s, minter: %s, recipient: %s, share: %s",
|
||||
Base58.encode(rewardShareData.getRewardSharePublicKey()),
|
||||
rewardShareData.getMintingAccount(), rewardShareData.getRecipient(),
|
||||
rewardShareData.getSharePercent().toPlainString()));
|
||||
}
|
||||
} catch (DataException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
RepositoryManager.closeRepositoryFactory();
|
||||
} catch (DataException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -133,15 +133,12 @@ public class Block {
|
||||
final Account mintingAccount;
|
||||
final AccountData mintingAccountData;
|
||||
final boolean isMinterFounder;
|
||||
final int shareBin;
|
||||
|
||||
final Account recipientAccount;
|
||||
final AccountData recipientAccountData;
|
||||
final boolean isRecipientFounder;
|
||||
|
||||
ExpandedAccount(Repository repository, int accountIndex) throws DataException {
|
||||
final List<ShareByLevel> sharesByLevel = BlockChain.getInstance().getBlockSharesByLevel();
|
||||
|
||||
this.rewardShareData = repository.getAccountRepository().getRewardShareByIndex(accountIndex);
|
||||
|
||||
this.mintingAccount = new PublicKeyAccount(repository, this.rewardShareData.getMinterPublicKey());
|
||||
@ -150,23 +147,25 @@ public class Block {
|
||||
this.mintingAccountData = repository.getAccountRepository().getAccount(this.mintingAccount.getAddress());
|
||||
this.isMinterFounder = Account.isFounder(mintingAccountData.getFlags());
|
||||
|
||||
int currentShareBin = -1;
|
||||
|
||||
if (!this.isMinterFounder)
|
||||
for (int s = 0; s < sharesByLevel.size(); ++s)
|
||||
if (sharesByLevel.get(s).levels.contains(this.mintingAccountData.getLevel())) {
|
||||
currentShareBin = s;
|
||||
break;
|
||||
}
|
||||
|
||||
this.shareBin = currentShareBin;
|
||||
|
||||
this.recipientAccountData = repository.getAccountRepository().getAccount(this.recipientAccount.getAddress());
|
||||
this.isRecipientFounder = Account.isFounder(recipientAccountData.getFlags());
|
||||
|
||||
this.isRecipientAlsoMinter = this.mintingAccountData.getAddress().equals(this.recipientAccountData.getAddress());
|
||||
}
|
||||
|
||||
int getShareBin() {
|
||||
if (this.isMinterFounder)
|
||||
return -1;
|
||||
|
||||
final List<ShareByLevel> sharesByLevel = BlockChain.getInstance().getBlockSharesByLevel();
|
||||
|
||||
for (int s = 0; s < sharesByLevel.size(); ++s)
|
||||
if (sharesByLevel.get(s).levels.contains(this.mintingAccountData.getLevel()))
|
||||
return s;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void distribute(BigDecimal accountAmount) throws DataException {
|
||||
final BigDecimal oneHundred = BigDecimal.valueOf(100L);
|
||||
|
||||
@ -1601,7 +1600,7 @@ public class Block {
|
||||
LOGGER.trace(() -> String.format("Bin %d share of %s: %s", binIndex, totalAmount.toPlainString(), binAmount.toPlainString()));
|
||||
|
||||
// Spread across all accounts in bin
|
||||
List<ExpandedAccount> binnedAccounts = expandedAccounts.stream().filter(accountInfo -> !accountInfo.isMinterFounder && accountInfo.shareBin == binIndex).collect(Collectors.toList());
|
||||
List<ExpandedAccount> binnedAccounts = expandedAccounts.stream().filter(accountInfo -> !accountInfo.isMinterFounder && accountInfo.getShareBin() == binIndex).collect(Collectors.toList());
|
||||
if (binnedAccounts.isEmpty())
|
||||
continue;
|
||||
|
||||
@ -1717,9 +1716,11 @@ public class Block {
|
||||
// Spread remainder across founder accounts
|
||||
BigDecimal foundersAmount = totalAmount.subtract(sharedAmount);
|
||||
BigDecimal finalSharedAmount = sharedAmount;
|
||||
LOGGER.debug(() -> String.format("Shared %s of %s, remaining %s to founders", finalSharedAmount.toPlainString(), totalAmount.toPlainString(), foundersAmount.toPlainString()));
|
||||
|
||||
List<ExpandedAccount> founderAccounts = expandedAccounts.stream().filter(accountInfo -> accountInfo.isMinterFounder).collect(Collectors.toList());
|
||||
LOGGER.debug(() -> String.format("Shared %s of %s, remaining %s to %d founder%s",
|
||||
finalSharedAmount.toPlainString(), totalAmount.toPlainString(),
|
||||
foundersAmount.toPlainString(), founderAccounts.size(), (founderAccounts.size() != 1 ? "s" : "")));
|
||||
if (founderAccounts.isEmpty())
|
||||
return;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user