From 5b81b30974b4fba01bbf796e45d2bb4bbdd7b185 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 24 Sep 2022 13:02:27 +0100 Subject: [PATCH] Modified online accounts request interval, and introduced bursting. It will now request online accounts every 1 minute instead of every 5 seconds, except for the first 5 minutes following a new online accounts timestamp, in which it will request every 5 seconds (referred to as the "burst" interval). It will also use the burst interval for the first 5 minutes after the node starts. This is based on the idea that most online accounts arrive soon after a new timestamp begins, and so there is no need to request accounts so frequently after that. This should reduce data usage by a significant amount. Once mempow is fully rolled out, the "burst" feature can be reduced or removed, since online accounts will be sent ahead of time, generally 15-30 mins prior to the new online accounts timestamp becoming active. --- .../org/qortal/controller/Controller.java | 4 +++ .../controller/OnlineAccountsManager.java | 31 ++++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/qortal/controller/Controller.java b/src/main/java/org/qortal/controller/Controller.java index f6711991..8e1dfd8a 100644 --- a/src/main/java/org/qortal/controller/Controller.java +++ b/src/main/java/org/qortal/controller/Controller.java @@ -317,6 +317,10 @@ public class Controller extends Thread { } } + public static long uptime() { + return System.currentTimeMillis() - Controller.startTime; + } + /** Returns highest block, or null if it's not available. */ public BlockData getChainTip() { synchronized (this.latestBlocks) { diff --git a/src/main/java/org/qortal/controller/OnlineAccountsManager.java b/src/main/java/org/qortal/controller/OnlineAccountsManager.java index de8cfb12..a0f4db68 100644 --- a/src/main/java/org/qortal/controller/OnlineAccountsManager.java +++ b/src/main/java/org/qortal/controller/OnlineAccountsManager.java @@ -55,7 +55,12 @@ public class OnlineAccountsManager { private static final long ONLINE_ACCOUNTS_QUEUE_INTERVAL = 100L; //ms private static final long ONLINE_ACCOUNTS_TASKS_INTERVAL = 10 * 1000L; // ms - private static final long ONLINE_ACCOUNTS_BROADCAST_INTERVAL = 5 * 1000L; // ms + private static final long ONLINE_ACCOUNTS_COMPUTE_INTERVAL = 5 * 1000L; // ms + private static final long ONLINE_ACCOUNTS_BROADCAST_INTERVAL = 60 * 1000L; // ms + // After switching to a new online timestamp, we "burst" the online accounts requests + // at an increased interval for a specified amount of time + private static final long ONLINE_ACCOUNTS_BROADCAST_BURST_INTERVAL = 5 * 1000L; // ms + private static final long ONLINE_ACCOUNTS_BROADCAST_BURST_LENGTH = 5 * 60 * 1000L; // ms private static final long INITIAL_SLEEP_INTERVAL = 30 * 1000L; @@ -83,6 +88,8 @@ public class OnlineAccountsManager { */ private final SortedMap> latestBlocksOnlineAccounts = new ConcurrentSkipListMap<>(); + private long lastOnlineAccountsRequest = 0; + private boolean hasOurOnlineAccounts = false; public static long getOnlineTimestampModulus() { @@ -121,7 +128,7 @@ public class OnlineAccountsManager { executor.scheduleAtFixedRate(this::expireOldOnlineAccounts, ONLINE_ACCOUNTS_TASKS_INTERVAL, ONLINE_ACCOUNTS_TASKS_INTERVAL, TimeUnit.MILLISECONDS); // Request online accounts from peers - executor.scheduleAtFixedRate(this::requestRemoteOnlineAccounts, ONLINE_ACCOUNTS_BROADCAST_INTERVAL, ONLINE_ACCOUNTS_BROADCAST_INTERVAL, TimeUnit.MILLISECONDS); + executor.scheduleAtFixedRate(this::requestRemoteOnlineAccounts, ONLINE_ACCOUNTS_BROADCAST_BURST_INTERVAL, ONLINE_ACCOUNTS_BROADCAST_BURST_INTERVAL, TimeUnit.MILLISECONDS); // Process import queue executor.scheduleWithFixedDelay(this::processOnlineAccountsImportQueue, ONLINE_ACCOUNTS_QUEUE_INTERVAL, ONLINE_ACCOUNTS_QUEUE_INTERVAL, TimeUnit.MILLISECONDS); @@ -136,7 +143,7 @@ public class OnlineAccountsManager { } // Send our online accounts - executor.scheduleAtFixedRate(this::sendOurOnlineAccountsInfo, ONLINE_ACCOUNTS_BROADCAST_INTERVAL, ONLINE_ACCOUNTS_BROADCAST_INTERVAL, TimeUnit.MILLISECONDS); + executor.scheduleAtFixedRate(this::sendOurOnlineAccountsInfo, ONLINE_ACCOUNTS_COMPUTE_INTERVAL, ONLINE_ACCOUNTS_COMPUTE_INTERVAL, TimeUnit.MILLISECONDS); } public void shutdown() { @@ -435,8 +442,24 @@ public class OnlineAccountsManager { if (!Controller.getInstance().isUpToDate()) return; - Message messageV3 = new GetOnlineAccountsV3Message(currentOnlineAccountsHashes); + long onlineAccountsTimestamp = getCurrentOnlineAccountTimestamp(); + if (now - onlineAccountsTimestamp >= ONLINE_ACCOUNTS_BROADCAST_BURST_LENGTH) { + // New online timestamp started more than 5 mins ago - we probably don't need to request so frequently + if (Controller.uptime() < ONLINE_ACCOUNTS_BROADCAST_BURST_LENGTH) { + // The node recently started up, so we should request at the burst interval + // This could allow accounts to move around the network more easily when an auto update is occurring + } + else if (now - lastOnlineAccountsRequest < ONLINE_ACCOUNTS_BROADCAST_INTERVAL) { + // We already requested online accounts in the last minute, so no need to request again + return; + } + } + + LOGGER.info("Requesting online accounts via broadcast..."); + + lastOnlineAccountsRequest = now; + Message messageV3 = new GetOnlineAccountsV3Message(currentOnlineAccountsHashes); Network.getInstance().broadcast(peer -> messageV3); }