Browse Source

OnlineAccountsV3: slightly rework Block.mint() so it doesn't need to filter so many online accounts

Slight optimization to BlockMinter by adding OnlineAccountsManager.hasOnlineAccounts():boolean instead of returning actual data, only to call isEmpty()!
pull/91/head
catbref 2 years ago
parent
commit
ae92a6eed4
  1. 33
      src/main/java/org/qortal/block/Block.java
  2. 4
      src/main/java/org/qortal/controller/BlockMinter.java
  3. 15
      src/main/java/org/qortal/controller/OnlineAccountsManager.java

33
src/main/java/org/qortal/block/Block.java

@ -346,20 +346,24 @@ public class Block {
int version = parentBlock.getNextBlockVersion();
byte[] reference = parentBlockData.getSignature();
// Qortal: minter is always a reward-share, so find actual minter and get their effective minting level
int minterLevel = Account.getRewardShareEffectiveMintingLevel(repository, minter.getPublicKey());
if (minterLevel == 0) {
LOGGER.error("Minter effective level returned zero?");
return null;
}
long timestamp = calcTimestamp(parentBlockData, minter.getPublicKey(), minterLevel);
long onlineAccountsTimestamp = OnlineAccountsManager.toOnlineAccountTimestamp(timestamp);
// Fetch our list of online accounts
List<OnlineAccountData> onlineAccounts = OnlineAccountsManager.getInstance().getOnlineAccounts();
List<OnlineAccountData> onlineAccounts = OnlineAccountsManager.getInstance().getOnlineAccounts(onlineAccountsTimestamp);
if (onlineAccounts.isEmpty()) {
LOGGER.error("No online accounts - not even our own?");
return null;
}
// Find newest online accounts timestamp
long onlineAccountsTimestamp = 0;
for (OnlineAccountData onlineAccountData : onlineAccounts) {
if (onlineAccountData.getTimestamp() > onlineAccountsTimestamp)
onlineAccountsTimestamp = onlineAccountData.getTimestamp();
}
// Load sorted list of reward share public keys into memory, so that the indexes can be obtained.
// This is up to 100x faster than querying each index separately. For 4150 reward share keys, it
// was taking around 5000ms to query individually, vs 50ms using this approach.
@ -368,10 +372,6 @@ public class Block {
// Map using index into sorted list of reward-shares as key
Map<Integer, OnlineAccountData> indexedOnlineAccounts = new HashMap<>();
for (OnlineAccountData onlineAccountData : onlineAccounts) {
// Disregard online accounts with different timestamps
if (onlineAccountData.getTimestamp() != onlineAccountsTimestamp)
continue;
Integer accountIndex = getRewardShareIndex(onlineAccountData.getPublicKey(), allRewardSharePublicKeys);
if (accountIndex == null)
// Online account (reward-share) with current timestamp but reward-share cancelled
@ -399,15 +399,6 @@ public class Block {
byte[] minterSignature = minter.sign(BlockTransformer.getBytesForMinterSignature(parentBlockData,
minter.getPublicKey(), encodedOnlineAccounts));
// Qortal: minter is always a reward-share, so find actual minter and get their effective minting level
int minterLevel = Account.getRewardShareEffectiveMintingLevel(repository, minter.getPublicKey());
if (minterLevel == 0) {
LOGGER.error("Minter effective level returned zero?");
return null;
}
long timestamp = calcTimestamp(parentBlockData, minter.getPublicKey(), minterLevel);
int transactionCount = 0;
byte[] transactionsSignature = null;
int height = parentBlockData.getHeight() + 1;

4
src/main/java/org/qortal/controller/BlockMinter.java

@ -114,8 +114,8 @@ public class BlockMinter extends Thread {
if (minLatestBlockTimestamp == null)
continue;
// No online accounts? (e.g. during startup)
if (OnlineAccountsManager.getInstance().getOnlineAccounts().isEmpty())
// No online accounts for current timestamp? (e.g. during startup)
if (!OnlineAccountsManager.getInstance().hasOnlineAccounts())
continue;
List<MintingAccountData> mintingAccountsData = repository.getAccountRepository().getMintingAccounts();

15
src/main/java/org/qortal/controller/OnlineAccountsManager.java

@ -420,6 +420,20 @@ public class OnlineAccountsManager {
LOGGER.debug("Broadcasted {} online account{} with timestamp {}", ourOnlineAccounts.size(), (ourOnlineAccounts.size() != 1 ? "s" : ""), onlineAccountsTimestamp);
}
/**
* Returns whether online accounts manager has any online accounts with timestamp recent enough to be considered currently online.
*/
// BlockMinter: only calls this to check whether returned list is empty or not, to determine whether minting is even possible or not
public boolean hasOnlineAccounts() {
final Long now = NTP.getTime();
if (now == null)
return false;
final long onlineTimestamp = toOnlineAccountTimestamp(now);
return this.currentOnlineAccounts.containsKey(onlineTimestamp);
}
/**
* Returns list of online accounts matching given timestamp.
*/
@ -433,7 +447,6 @@ public class OnlineAccountsManager {
* Returns list of online accounts with timestamp recent enough to be considered currently online.
*/
// API: calls this to return list of online accounts - probably expects ALL timestamps - but going to get 'current' from now on
// BlockMinter: only calls this to check whether returned list is empty or not, to determine whether minting is even possible or not
public List<OnlineAccountData> getOnlineAccounts() {
final Long now = NTP.getTime();
if (now == null)

Loading…
Cancel
Save