Browse Source

Cherry-pick minor fixes from another branch to resolve "No online accounts - not even our own?" issues

reduce-reward-shares
catbref 2 years ago
parent
commit
829ab1eb37
  1. 2
      src/main/java/org/qortal/block/Block.java
  2. 65
      src/main/java/org/qortal/controller/OnlineAccountsManager.java

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

@ -355,7 +355,7 @@ public class Block {
long timestamp = calcTimestamp(parentBlockData, minter.getPublicKey(), minterLevel);
long onlineAccountsTimestamp = OnlineAccountsManager.toOnlineAccountTimestamp(timestamp);
long onlineAccountsTimestamp = OnlineAccountsManager.getCurrentOnlineAccountTimestamp();
// Fetch our list of online accounts
List<OnlineAccountData> onlineAccounts = OnlineAccountsManager.getInstance().getOnlineAccounts(onlineAccountsTimestamp);

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

@ -53,7 +53,7 @@ public class OnlineAccountsManager {
private static final long ONLINE_ACCOUNTS_BROADCAST_INTERVAL = 15 * 1000L; // ms
private static final long ONLINE_ACCOUNTS_V2_PEER_VERSION = 0x0300020000L; // v3.2.0
private static final long ONLINE_ACCOUNTS_V3_PEER_VERSION = 0x03000200cbL; // v3.2.203
private static final long ONLINE_ACCOUNTS_V3_PEER_VERSION = 0x03000300cbL; // v3.3.203
private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(4, new NamedThreadFactory("OnlineAccounts"));
private volatile boolean isStopping = false;
@ -75,8 +75,12 @@ public class OnlineAccountsManager {
*/
private final SortedMap<Long, Set<OnlineAccountData>> latestBlocksOnlineAccounts = new ConcurrentSkipListMap<>();
public static long toOnlineAccountTimestamp(long timestamp) {
return (timestamp / ONLINE_TIMESTAMP_MODULUS) * ONLINE_TIMESTAMP_MODULUS;
public static Long getCurrentOnlineAccountTimestamp() {
Long now = NTP.getTime();
if (now == null)
return null;
return (now / ONLINE_TIMESTAMP_MODULUS) * ONLINE_TIMESTAMP_MODULUS;
}
private OnlineAccountsManager() {
@ -118,11 +122,10 @@ public class OnlineAccountsManager {
return;
}
final Long now = NTP.getTime();
if (now == null)
final Long onlineAccountsTimestamp = getCurrentOnlineAccountTimestamp();
if (onlineAccountsTimestamp == null)
return;
final long onlineAccountsTimestamp = toOnlineAccountTimestamp(now);
byte[] timestampBytes = Longs.toByteArray(onlineAccountsTimestamp);
Set<OnlineAccountData> replacementAccounts = new HashSet<>();
@ -162,15 +165,15 @@ public class OnlineAccountsManager {
// Remove from queue
onlineAccountsImportQueue.remove(onlineAccountData);
}
LOGGER.debug("Finished validating online accounts import queue");
} catch (DataException e) {
LOGGER.error("Repository issue while verifying online accounts", e);
}
if (!onlineAccountsToAdd.isEmpty()) {
LOGGER.debug("Merging {} validated online accounts from import queue", onlineAccountsToAdd.size());
addAccounts(onlineAccountsToAdd);
}
}
// Utilities
@ -224,7 +227,8 @@ public class OnlineAccountsManager {
return true;
}
private void addAccounts(Set<OnlineAccountData> onlineAccountsToAdd) {
/** Adds accounts, maybe rebuilds hashes, returns whether any new accounts were added / hashes rebuilt. */
private boolean addAccounts(Collection<OnlineAccountData> onlineAccountsToAdd) {
// For keeping track of which hashes to rebuild
Map<Long, Set<Byte>> hashesToRebuild = new HashMap<>();
@ -235,6 +239,9 @@ public class OnlineAccountsManager {
hashesToRebuild.computeIfAbsent(onlineAccountData.getTimestamp(), k -> new HashSet<>()).add(onlineAccountData.getPublicKey()[0]);
}
if (hashesToRebuild.isEmpty())
return false;
for (var entry : hashesToRebuild.entrySet()) {
Long timestamp = entry.getKey();
@ -263,6 +270,8 @@ public class OnlineAccountsManager {
));
}
}
return true;
}
private boolean addAccount(OnlineAccountData onlineAccountData) {
@ -341,10 +350,10 @@ public class OnlineAccountsManager {
* Send online accounts that are minting on this node.
*/
private void sendOurOnlineAccountsInfo() {
final Long now = NTP.getTime();
if (now == null) {
// 'current' timestamp
final Long onlineAccountsTimestamp = getCurrentOnlineAccountTimestamp();
if (onlineAccountsTimestamp == null)
return;
}
List<MintingAccountData> mintingAccounts;
try (final Repository repository = RepositoryManager.getRepository()) {
@ -378,10 +387,6 @@ public class OnlineAccountsManager {
return;
}
// 'current' timestamp
final long onlineAccountsTimestamp = toOnlineAccountTimestamp(now);
boolean hasInfoChanged = false;
byte[] timestampBytes = Longs.toByteArray(onlineAccountsTimestamp);
List<OnlineAccountData> ourOnlineAccounts = new ArrayList<>();
@ -393,15 +398,10 @@ public class OnlineAccountsManager {
// Our account is online
OnlineAccountData ourOnlineAccountData = new OnlineAccountData(onlineAccountsTimestamp, signature, publicKey);
boolean isNewEntry = addAccount(ourOnlineAccountData);
if (isNewEntry) {
LOGGER.trace(() -> String.format("Added our online account %s with timestamp %d", Base58.encode(mintingAccount.getPublicKey()), onlineAccountsTimestamp));
ourOnlineAccounts.add(ourOnlineAccountData);
hasInfoChanged = true;
}
}
boolean hasInfoChanged = addAccounts(ourOnlineAccounts);
if (!hasInfoChanged)
return;
@ -425,20 +425,18 @@ public class OnlineAccountsManager {
*/
// 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)
// 'current' timestamp
final Long onlineAccountsTimestamp = getCurrentOnlineAccountTimestamp();
if (onlineAccountsTimestamp == null)
return false;
final long onlineTimestamp = toOnlineAccountTimestamp(now);
return this.currentOnlineAccounts.containsKey(onlineTimestamp);
return this.currentOnlineAccounts.containsKey(onlineAccountsTimestamp);
}
/**
* Returns list of online accounts matching given timestamp.
*/
// Block::mint() - only wants online accounts with timestamp that matches block's timestamp so they can be added to new block
// Block::areOnlineAccountsValid() - only wants online accounts with timestamp that matches block's timestamp to avoid re-verifying sigs
// Block::mint() - only wants online accounts with (online) timestamp that matches block's (online) timestamp so they can be added to new block
public List<OnlineAccountData> getOnlineAccounts(long onlineTimestamp) {
return new ArrayList<>(Set.copyOf(this.currentOnlineAccounts.getOrDefault(onlineTimestamp, Collections.emptySet())));
}
@ -448,13 +446,12 @@ public class OnlineAccountsManager {
*/
// API: calls this to return list of online accounts - probably expects ALL timestamps - but going to get 'current' from now on
public List<OnlineAccountData> getOnlineAccounts() {
final Long now = NTP.getTime();
if (now == null)
// 'current' timestamp
final Long onlineAccountsTimestamp = getCurrentOnlineAccountTimestamp();
if (onlineAccountsTimestamp == null)
return Collections.emptyList();
final long onlineTimestamp = toOnlineAccountTimestamp(now);
return getOnlineAccounts(onlineTimestamp);
return getOnlineAccounts(onlineAccountsTimestamp);
}
// Block processing

Loading…
Cancel
Save