mirror of
https://github.com/Qortal/qortal.git
synced 2025-03-13 11:12:31 +00:00
Cherry-pick minor fixes from another branch to resolve "No online accounts - not even our own?" issues
This commit is contained in:
parent
d9b330b46a
commit
829ab1eb37
@ -355,7 +355,7 @@ public class Block {
|
|||||||
|
|
||||||
long timestamp = calcTimestamp(parentBlockData, minter.getPublicKey(), minterLevel);
|
long timestamp = calcTimestamp(parentBlockData, minter.getPublicKey(), minterLevel);
|
||||||
|
|
||||||
long onlineAccountsTimestamp = OnlineAccountsManager.toOnlineAccountTimestamp(timestamp);
|
long onlineAccountsTimestamp = OnlineAccountsManager.getCurrentOnlineAccountTimestamp();
|
||||||
|
|
||||||
// Fetch our list of online accounts
|
// Fetch our list of online accounts
|
||||||
List<OnlineAccountData> onlineAccounts = OnlineAccountsManager.getInstance().getOnlineAccounts(onlineAccountsTimestamp);
|
List<OnlineAccountData> onlineAccounts = OnlineAccountsManager.getInstance().getOnlineAccounts(onlineAccountsTimestamp);
|
||||||
|
@ -53,7 +53,7 @@ public class OnlineAccountsManager {
|
|||||||
private static final long ONLINE_ACCOUNTS_BROADCAST_INTERVAL = 15 * 1000L; // ms
|
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_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 final ScheduledExecutorService executor = Executors.newScheduledThreadPool(4, new NamedThreadFactory("OnlineAccounts"));
|
||||||
private volatile boolean isStopping = false;
|
private volatile boolean isStopping = false;
|
||||||
@ -75,8 +75,12 @@ public class OnlineAccountsManager {
|
|||||||
*/
|
*/
|
||||||
private final SortedMap<Long, Set<OnlineAccountData>> latestBlocksOnlineAccounts = new ConcurrentSkipListMap<>();
|
private final SortedMap<Long, Set<OnlineAccountData>> latestBlocksOnlineAccounts = new ConcurrentSkipListMap<>();
|
||||||
|
|
||||||
public static long toOnlineAccountTimestamp(long timestamp) {
|
public static Long getCurrentOnlineAccountTimestamp() {
|
||||||
return (timestamp / ONLINE_TIMESTAMP_MODULUS) * ONLINE_TIMESTAMP_MODULUS;
|
Long now = NTP.getTime();
|
||||||
|
if (now == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return (now / ONLINE_TIMESTAMP_MODULUS) * ONLINE_TIMESTAMP_MODULUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
private OnlineAccountsManager() {
|
private OnlineAccountsManager() {
|
||||||
@ -118,11 +122,10 @@ public class OnlineAccountsManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Long now = NTP.getTime();
|
final Long onlineAccountsTimestamp = getCurrentOnlineAccountTimestamp();
|
||||||
if (now == null)
|
if (onlineAccountsTimestamp == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
final long onlineAccountsTimestamp = toOnlineAccountTimestamp(now);
|
|
||||||
byte[] timestampBytes = Longs.toByteArray(onlineAccountsTimestamp);
|
byte[] timestampBytes = Longs.toByteArray(onlineAccountsTimestamp);
|
||||||
|
|
||||||
Set<OnlineAccountData> replacementAccounts = new HashSet<>();
|
Set<OnlineAccountData> replacementAccounts = new HashSet<>();
|
||||||
@ -162,14 +165,14 @@ public class OnlineAccountsManager {
|
|||||||
// Remove from queue
|
// Remove from queue
|
||||||
onlineAccountsImportQueue.remove(onlineAccountData);
|
onlineAccountsImportQueue.remove(onlineAccountData);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.debug("Finished validating online accounts import queue");
|
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
LOGGER.error("Repository issue while verifying online accounts", e);
|
LOGGER.error("Repository issue while verifying online accounts", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.debug("Merging {} validated online accounts from import queue", onlineAccountsToAdd.size());
|
if (!onlineAccountsToAdd.isEmpty()) {
|
||||||
addAccounts(onlineAccountsToAdd);
|
LOGGER.debug("Merging {} validated online accounts from import queue", onlineAccountsToAdd.size());
|
||||||
|
addAccounts(onlineAccountsToAdd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
@ -224,7 +227,8 @@ public class OnlineAccountsManager {
|
|||||||
return true;
|
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
|
// For keeping track of which hashes to rebuild
|
||||||
Map<Long, Set<Byte>> hashesToRebuild = new HashMap<>();
|
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]);
|
hashesToRebuild.computeIfAbsent(onlineAccountData.getTimestamp(), k -> new HashSet<>()).add(onlineAccountData.getPublicKey()[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hashesToRebuild.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
for (var entry : hashesToRebuild.entrySet()) {
|
for (var entry : hashesToRebuild.entrySet()) {
|
||||||
Long timestamp = entry.getKey();
|
Long timestamp = entry.getKey();
|
||||||
|
|
||||||
@ -263,6 +270,8 @@ public class OnlineAccountsManager {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean addAccount(OnlineAccountData onlineAccountData) {
|
private boolean addAccount(OnlineAccountData onlineAccountData) {
|
||||||
@ -341,10 +350,10 @@ public class OnlineAccountsManager {
|
|||||||
* Send online accounts that are minting on this node.
|
* Send online accounts that are minting on this node.
|
||||||
*/
|
*/
|
||||||
private void sendOurOnlineAccountsInfo() {
|
private void sendOurOnlineAccountsInfo() {
|
||||||
final Long now = NTP.getTime();
|
// 'current' timestamp
|
||||||
if (now == null) {
|
final Long onlineAccountsTimestamp = getCurrentOnlineAccountTimestamp();
|
||||||
|
if (onlineAccountsTimestamp == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
List<MintingAccountData> mintingAccounts;
|
List<MintingAccountData> mintingAccounts;
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
@ -378,10 +387,6 @@ public class OnlineAccountsManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'current' timestamp
|
|
||||||
final long onlineAccountsTimestamp = toOnlineAccountTimestamp(now);
|
|
||||||
boolean hasInfoChanged = false;
|
|
||||||
|
|
||||||
byte[] timestampBytes = Longs.toByteArray(onlineAccountsTimestamp);
|
byte[] timestampBytes = Longs.toByteArray(onlineAccountsTimestamp);
|
||||||
List<OnlineAccountData> ourOnlineAccounts = new ArrayList<>();
|
List<OnlineAccountData> ourOnlineAccounts = new ArrayList<>();
|
||||||
|
|
||||||
@ -393,15 +398,10 @@ public class OnlineAccountsManager {
|
|||||||
|
|
||||||
// Our account is online
|
// Our account is online
|
||||||
OnlineAccountData ourOnlineAccountData = new OnlineAccountData(onlineAccountsTimestamp, signature, publicKey);
|
OnlineAccountData ourOnlineAccountData = new OnlineAccountData(onlineAccountsTimestamp, signature, publicKey);
|
||||||
|
ourOnlineAccounts.add(ourOnlineAccountData);
|
||||||
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)
|
if (!hasInfoChanged)
|
||||||
return;
|
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
|
// 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() {
|
public boolean hasOnlineAccounts() {
|
||||||
final Long now = NTP.getTime();
|
// 'current' timestamp
|
||||||
if (now == null)
|
final Long onlineAccountsTimestamp = getCurrentOnlineAccountTimestamp();
|
||||||
|
if (onlineAccountsTimestamp == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
final long onlineTimestamp = toOnlineAccountTimestamp(now);
|
return this.currentOnlineAccounts.containsKey(onlineAccountsTimestamp);
|
||||||
|
|
||||||
return this.currentOnlineAccounts.containsKey(onlineTimestamp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns list of online accounts matching given timestamp.
|
* 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::mint() - only wants online accounts with (online) timestamp that matches block's (online) 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
|
|
||||||
public List<OnlineAccountData> getOnlineAccounts(long onlineTimestamp) {
|
public List<OnlineAccountData> getOnlineAccounts(long onlineTimestamp) {
|
||||||
return new ArrayList<>(Set.copyOf(this.currentOnlineAccounts.getOrDefault(onlineTimestamp, Collections.emptySet())));
|
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
|
// 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() {
|
public List<OnlineAccountData> getOnlineAccounts() {
|
||||||
final Long now = NTP.getTime();
|
// 'current' timestamp
|
||||||
if (now == null)
|
final Long onlineAccountsTimestamp = getCurrentOnlineAccountTimestamp();
|
||||||
|
if (onlineAccountsTimestamp == null)
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
|
||||||
final long onlineTimestamp = toOnlineAccountTimestamp(now);
|
return getOnlineAccounts(onlineAccountsTimestamp);
|
||||||
|
|
||||||
return getOnlineAccounts(onlineTimestamp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block processing
|
// Block processing
|
||||||
|
Loading…
x
Reference in New Issue
Block a user