diff --git a/pom.xml b/pom.xml
index 7c7ac147..f236761e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
org.qortal
qortal
- 4.1.3
+ 4.2.0
jar
true
diff --git a/src/main/java/org/qortal/controller/Controller.java b/src/main/java/org/qortal/controller/Controller.java
index e1e90486..2cab24ec 100644
--- a/src/main/java/org/qortal/controller/Controller.java
+++ b/src/main/java/org/qortal/controller/Controller.java
@@ -1278,13 +1278,6 @@ public class Controller extends Thread {
TransactionImporter.getInstance().onNetworkTransactionSignaturesMessage(peer, message);
break;
- case GET_ONLINE_ACCOUNTS:
- case ONLINE_ACCOUNTS:
- case GET_ONLINE_ACCOUNTS_V2:
- case ONLINE_ACCOUNTS_V2:
- // No longer supported - to be eventually removed
- break;
-
case GET_ONLINE_ACCOUNTS_V3:
OnlineAccountsManager.getInstance().onNetworkGetOnlineAccountsV3Message(peer, message);
break;
diff --git a/src/main/java/org/qortal/controller/OnlineAccountsManager.java b/src/main/java/org/qortal/controller/OnlineAccountsManager.java
index 5e64161d..25cace2f 100644
--- a/src/main/java/org/qortal/controller/OnlineAccountsManager.java
+++ b/src/main/java/org/qortal/controller/OnlineAccountsManager.java
@@ -414,7 +414,7 @@ public class OnlineAccountsManager {
boolean isSuperiorEntry = isOnlineAccountsDataSuperior(onlineAccountData);
if (isSuperiorEntry)
// Remove existing inferior entry so it can be re-added below (it's likely the existing copy is missing a nonce value)
- onlineAccounts.remove(onlineAccountData);
+ onlineAccounts.removeIf(a -> Objects.equals(a.getPublicKey(), onlineAccountData.getPublicKey()));
boolean isNewEntry = onlineAccounts.add(onlineAccountData);
@@ -743,14 +743,8 @@ public class OnlineAccountsManager {
if (onlineAccounts == null)
onlineAccounts = this.latestBlocksOnlineAccounts.get(timestamp);
- if (onlineAccounts != null) {
- // Remove accounts with matching timestamp, nonce, and public key
- final Set finalOnlineAccounts = onlineAccounts;
- blocksOnlineAccounts.removeIf(a1 -> finalOnlineAccounts.stream()
- .anyMatch(a2 -> a2.getTimestamp() == a1.getTimestamp() &&
- Objects.equals(a2.getNonce(), a1.getNonce()) &&
- Arrays.equals(a2.getPublicKey(), a1.getPublicKey())));
- }
+ if (onlineAccounts != null)
+ blocksOnlineAccounts.removeAll(onlineAccounts);
}
/**
diff --git a/src/main/java/org/qortal/data/network/OnlineAccountData.java b/src/main/java/org/qortal/data/network/OnlineAccountData.java
index bd4842db..a1e1b30f 100644
--- a/src/main/java/org/qortal/data/network/OnlineAccountData.java
+++ b/src/main/java/org/qortal/data/network/OnlineAccountData.java
@@ -1,6 +1,7 @@
package org.qortal.data.network;
import java.util.Arrays;
+import java.util.Objects;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@@ -34,10 +35,6 @@ public class OnlineAccountData {
this.nonce = nonce;
}
- public OnlineAccountData(long timestamp, byte[] signature, byte[] publicKey) {
- this(timestamp, signature, publicKey, null);
- }
-
public long getTimestamp() {
return this.timestamp;
}
@@ -76,6 +73,10 @@ public class OnlineAccountData {
if (otherOnlineAccountData.timestamp != this.timestamp)
return false;
+ // Almost as quick
+ if (!Objects.equals(otherOnlineAccountData.nonce, this.nonce))
+ return false;
+
if (!Arrays.equals(otherOnlineAccountData.publicKey, this.publicKey))
return false;
@@ -88,9 +89,10 @@ public class OnlineAccountData {
public int hashCode() {
int h = this.hash;
if (h == 0) {
- this.hash = h = Long.hashCode(this.timestamp)
- ^ Arrays.hashCode(this.publicKey);
+ h = Objects.hash(timestamp, nonce);
+ h = 31 * h + Arrays.hashCode(publicKey);
// We don't use signature because newer aggregate signatures use random nonces
+ this.hash = h;
}
return h;
}
diff --git a/src/main/java/org/qortal/network/Network.java b/src/main/java/org/qortal/network/Network.java
index ca79f367..a3528a66 100644
--- a/src/main/java/org/qortal/network/Network.java
+++ b/src/main/java/org/qortal/network/Network.java
@@ -187,7 +187,7 @@ public class Network {
this.bindAddress = bindAddress; // Store the selected address, so that it can be used by other parts of the app
break; // We don't want to bind to more than one address
- } catch (UnknownHostException e) {
+ } catch (UnknownHostException | UnsupportedAddressTypeException e) {
LOGGER.error("Can't bind listen socket to address {}", Settings.getInstance().getBindAddress());
if (i == bindAddresses.size()-1) { // Only throw an exception if all addresses have been tried
throw new IOException("Can't bind listen socket to address", e);
diff --git a/src/main/java/org/qortal/network/message/GetOnlineAccountsMessage.java b/src/main/java/org/qortal/network/message/GetOnlineAccountsMessage.java
deleted file mode 100644
index ae98cf40..00000000
--- a/src/main/java/org/qortal/network/message/GetOnlineAccountsMessage.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.qortal.network.message;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.qortal.data.network.OnlineAccountData;
-import org.qortal.transform.Transformer;
-
-import com.google.common.primitives.Ints;
-import com.google.common.primitives.Longs;
-
-public class GetOnlineAccountsMessage extends Message {
- private static final int MAX_ACCOUNT_COUNT = 5000;
-
- private List onlineAccounts;
-
- public GetOnlineAccountsMessage(List onlineAccounts) {
- super(MessageType.GET_ONLINE_ACCOUNTS);
-
- ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-
- try {
- bytes.write(Ints.toByteArray(onlineAccounts.size()));
-
- for (OnlineAccountData onlineAccountData : onlineAccounts) {
- bytes.write(Longs.toByteArray(onlineAccountData.getTimestamp()));
-
- bytes.write(onlineAccountData.getPublicKey());
- }
- } catch (IOException e) {
- throw new AssertionError("IOException shouldn't occur with ByteArrayOutputStream");
- }
-
- this.dataBytes = bytes.toByteArray();
- this.checksumBytes = Message.generateChecksum(this.dataBytes);
- }
-
- private GetOnlineAccountsMessage(int id, List onlineAccounts) {
- super(id, MessageType.GET_ONLINE_ACCOUNTS);
-
- this.onlineAccounts = onlineAccounts.stream().limit(MAX_ACCOUNT_COUNT).collect(Collectors.toList());
- }
-
- public List getOnlineAccounts() {
- return this.onlineAccounts;
- }
-
- public static Message fromByteBuffer(int id, ByteBuffer bytes) {
- final int accountCount = bytes.getInt();
-
- List onlineAccounts = new ArrayList<>(accountCount);
-
- for (int i = 0; i < Math.min(MAX_ACCOUNT_COUNT, accountCount); ++i) {
- long timestamp = bytes.getLong();
-
- byte[] publicKey = new byte[Transformer.PUBLIC_KEY_LENGTH];
- bytes.get(publicKey);
-
- onlineAccounts.add(new OnlineAccountData(timestamp, null, publicKey));
- }
-
- return new GetOnlineAccountsMessage(id, onlineAccounts);
- }
-
-}
diff --git a/src/main/java/org/qortal/network/message/GetOnlineAccountsV2Message.java b/src/main/java/org/qortal/network/message/GetOnlineAccountsV2Message.java
deleted file mode 100644
index fe6b5d72..00000000
--- a/src/main/java/org/qortal/network/message/GetOnlineAccountsV2Message.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package org.qortal.network.message;
-
-import com.google.common.primitives.Ints;
-import com.google.common.primitives.Longs;
-import org.qortal.data.network.OnlineAccountData;
-import org.qortal.transform.Transformer;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * For requesting online accounts info from remote peer, given our list of online accounts.
- *
- * Different format to V1:
- * V1 is: number of entries, then timestamp + pubkey for each entry
- * V2 is: groups of: number of entries, timestamp, then pubkey for each entry
- *
- * Also V2 only builds online accounts message once!
- */
-public class GetOnlineAccountsV2Message extends Message {
-
- private List onlineAccounts;
-
- public GetOnlineAccountsV2Message(List onlineAccounts) {
- super(MessageType.GET_ONLINE_ACCOUNTS_V2);
-
- // If we don't have ANY online accounts then it's an easier construction...
- if (onlineAccounts.isEmpty()) {
- // Always supply a number of accounts
- this.dataBytes = Ints.toByteArray(0);
- this.checksumBytes = Message.generateChecksum(this.dataBytes);
- return;
- }
-
- // How many of each timestamp
- Map countByTimestamp = new HashMap<>();
-
- for (OnlineAccountData onlineAccountData : onlineAccounts) {
- Long timestamp = onlineAccountData.getTimestamp();
- countByTimestamp.compute(timestamp, (k, v) -> v == null ? 1 : ++v);
- }
-
- // We should know exactly how many bytes to allocate now
- int byteSize = countByTimestamp.size() * (Transformer.INT_LENGTH + Transformer.TIMESTAMP_LENGTH)
- + onlineAccounts.size() * Transformer.PUBLIC_KEY_LENGTH;
-
- ByteArrayOutputStream bytes = new ByteArrayOutputStream(byteSize);
-
- try {
- for (long timestamp : countByTimestamp.keySet()) {
- bytes.write(Ints.toByteArray(countByTimestamp.get(timestamp)));
-
- bytes.write(Longs.toByteArray(timestamp));
-
- for (OnlineAccountData onlineAccountData : onlineAccounts) {
- if (onlineAccountData.getTimestamp() == timestamp)
- bytes.write(onlineAccountData.getPublicKey());
- }
- }
- } catch (IOException e) {
- throw new AssertionError("IOException shouldn't occur with ByteArrayOutputStream");
- }
-
- this.dataBytes = bytes.toByteArray();
- this.checksumBytes = Message.generateChecksum(this.dataBytes);
- }
-
- private GetOnlineAccountsV2Message(int id, List onlineAccounts) {
- super(id, MessageType.GET_ONLINE_ACCOUNTS_V2);
-
- this.onlineAccounts = onlineAccounts;
- }
-
- public List getOnlineAccounts() {
- return this.onlineAccounts;
- }
-
- public static Message fromByteBuffer(int id, ByteBuffer bytes) {
- int accountCount = bytes.getInt();
-
- List onlineAccounts = new ArrayList<>(accountCount);
-
- while (accountCount > 0) {
- long timestamp = bytes.getLong();
-
- for (int i = 0; i < accountCount; ++i) {
- byte[] publicKey = new byte[Transformer.PUBLIC_KEY_LENGTH];
- bytes.get(publicKey);
-
- onlineAccounts.add(new OnlineAccountData(timestamp, null, publicKey));
- }
-
- if (bytes.hasRemaining()) {
- accountCount = bytes.getInt();
- } else {
- // we've finished
- accountCount = 0;
- }
- }
-
- return new GetOnlineAccountsV2Message(id, onlineAccounts);
- }
-
-}
diff --git a/src/main/java/org/qortal/network/message/MessageType.java b/src/main/java/org/qortal/network/message/MessageType.java
index 4dd4a3c8..6b420e2d 100644
--- a/src/main/java/org/qortal/network/message/MessageType.java
+++ b/src/main/java/org/qortal/network/message/MessageType.java
@@ -43,11 +43,7 @@ public enum MessageType {
BLOCK_SUMMARIES(70, BlockSummariesMessage::fromByteBuffer),
GET_BLOCK_SUMMARIES(71, GetBlockSummariesMessage::fromByteBuffer),
BLOCK_SUMMARIES_V2(72, BlockSummariesV2Message::fromByteBuffer),
-
- ONLINE_ACCOUNTS(80, OnlineAccountsMessage::fromByteBuffer),
- GET_ONLINE_ACCOUNTS(81, GetOnlineAccountsMessage::fromByteBuffer),
- ONLINE_ACCOUNTS_V2(82, OnlineAccountsV2Message::fromByteBuffer),
- GET_ONLINE_ACCOUNTS_V2(83, GetOnlineAccountsV2Message::fromByteBuffer),
+
ONLINE_ACCOUNTS_V3(84, OnlineAccountsV3Message::fromByteBuffer),
GET_ONLINE_ACCOUNTS_V3(85, GetOnlineAccountsV3Message::fromByteBuffer),
diff --git a/src/main/java/org/qortal/network/message/OnlineAccountsMessage.java b/src/main/java/org/qortal/network/message/OnlineAccountsMessage.java
deleted file mode 100644
index e7e4c32c..00000000
--- a/src/main/java/org/qortal/network/message/OnlineAccountsMessage.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.qortal.network.message;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.qortal.data.network.OnlineAccountData;
-import org.qortal.transform.Transformer;
-
-import com.google.common.primitives.Ints;
-import com.google.common.primitives.Longs;
-
-public class OnlineAccountsMessage extends Message {
- private static final int MAX_ACCOUNT_COUNT = 5000;
-
- private List onlineAccounts;
-
- public OnlineAccountsMessage(List onlineAccounts) {
- super(MessageType.ONLINE_ACCOUNTS);
-
- ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-
- try {
- bytes.write(Ints.toByteArray(onlineAccounts.size()));
-
- for (OnlineAccountData onlineAccountData : onlineAccounts) {
- bytes.write(Longs.toByteArray(onlineAccountData.getTimestamp()));
-
- bytes.write(onlineAccountData.getSignature());
-
- bytes.write(onlineAccountData.getPublicKey());
- }
- } catch (IOException e) {
- throw new AssertionError("IOException shouldn't occur with ByteArrayOutputStream");
- }
-
- this.dataBytes = bytes.toByteArray();
- this.checksumBytes = Message.generateChecksum(this.dataBytes);
- }
-
- private OnlineAccountsMessage(int id, List onlineAccounts) {
- super(id, MessageType.ONLINE_ACCOUNTS);
-
- this.onlineAccounts = onlineAccounts.stream().limit(MAX_ACCOUNT_COUNT).collect(Collectors.toList());
- }
-
- public List getOnlineAccounts() {
- return this.onlineAccounts;
- }
-
- public static Message fromByteBuffer(int id, ByteBuffer bytes) {
- final int accountCount = bytes.getInt();
-
- List onlineAccounts = new ArrayList<>(accountCount);
-
- for (int i = 0; i < Math.min(MAX_ACCOUNT_COUNT, accountCount); ++i) {
- long timestamp = bytes.getLong();
-
- byte[] signature = new byte[Transformer.SIGNATURE_LENGTH];
- bytes.get(signature);
-
- byte[] publicKey = new byte[Transformer.PUBLIC_KEY_LENGTH];
- bytes.get(publicKey);
-
- OnlineAccountData onlineAccountData = new OnlineAccountData(timestamp, signature, publicKey);
- onlineAccounts.add(onlineAccountData);
- }
-
- return new OnlineAccountsMessage(id, onlineAccounts);
- }
-
-}
diff --git a/src/main/java/org/qortal/network/message/OnlineAccountsV2Message.java b/src/main/java/org/qortal/network/message/OnlineAccountsV2Message.java
deleted file mode 100644
index 6803e3bf..00000000
--- a/src/main/java/org/qortal/network/message/OnlineAccountsV2Message.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package org.qortal.network.message;
-
-import com.google.common.primitives.Ints;
-import com.google.common.primitives.Longs;
-import org.qortal.data.network.OnlineAccountData;
-import org.qortal.transform.Transformer;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * For sending online accounts info to remote peer.
- *
- * Different format to V1:
- * V1 is: number of entries, then timestamp + sig + pubkey for each entry
- * V2 is: groups of: number of entries, timestamp, then sig + pubkey for each entry
- *
- * Also V2 only builds online accounts message once!
- */
-public class OnlineAccountsV2Message extends Message {
-
- private List onlineAccounts;
-
- public OnlineAccountsV2Message(List onlineAccounts) {
- super(MessageType.ONLINE_ACCOUNTS_V2);
-
- // Shortcut in case we have no online accounts
- if (onlineAccounts.isEmpty()) {
- this.dataBytes = Ints.toByteArray(0);
- this.checksumBytes = Message.generateChecksum(this.dataBytes);
- return;
- }
-
- // How many of each timestamp
- Map countByTimestamp = new HashMap<>();
-
- for (OnlineAccountData onlineAccountData : onlineAccounts) {
- Long timestamp = onlineAccountData.getTimestamp();
- countByTimestamp.compute(timestamp, (k, v) -> v == null ? 1 : ++v);
- }
-
- // We should know exactly how many bytes to allocate now
- int byteSize = countByTimestamp.size() * (Transformer.INT_LENGTH + Transformer.TIMESTAMP_LENGTH)
- + onlineAccounts.size() * (Transformer.SIGNATURE_LENGTH + Transformer.PUBLIC_KEY_LENGTH);
-
- ByteArrayOutputStream bytes = new ByteArrayOutputStream(byteSize);
-
- try {
- for (long timestamp : countByTimestamp.keySet()) {
- bytes.write(Ints.toByteArray(countByTimestamp.get(timestamp)));
-
- bytes.write(Longs.toByteArray(timestamp));
-
- for (OnlineAccountData onlineAccountData : onlineAccounts) {
- if (onlineAccountData.getTimestamp() == timestamp) {
- bytes.write(onlineAccountData.getSignature());
- bytes.write(onlineAccountData.getPublicKey());
- }
- }
- }
- } catch (IOException e) {
- throw new AssertionError("IOException shouldn't occur with ByteArrayOutputStream");
- }
-
- this.dataBytes = bytes.toByteArray();
- this.checksumBytes = Message.generateChecksum(this.dataBytes);
- }
-
- private OnlineAccountsV2Message(int id, List onlineAccounts) {
- super(id, MessageType.ONLINE_ACCOUNTS_V2);
-
- this.onlineAccounts = onlineAccounts;
- }
-
- public List getOnlineAccounts() {
- return this.onlineAccounts;
- }
-
- public static Message fromByteBuffer(int id, ByteBuffer bytes) throws MessageException {
- int accountCount = bytes.getInt();
-
- List onlineAccounts = new ArrayList<>(accountCount);
-
- while (accountCount > 0) {
- long timestamp = bytes.getLong();
-
- for (int i = 0; i < accountCount; ++i) {
- byte[] signature = new byte[Transformer.SIGNATURE_LENGTH];
- bytes.get(signature);
-
- byte[] publicKey = new byte[Transformer.PUBLIC_KEY_LENGTH];
- bytes.get(publicKey);
-
- onlineAccounts.add(new OnlineAccountData(timestamp, signature, publicKey));
- }
-
- if (bytes.hasRemaining()) {
- accountCount = bytes.getInt();
- } else {
- // we've finished
- accountCount = 0;
- }
- }
-
- return new OnlineAccountsV2Message(id, onlineAccounts);
- }
-
-}
diff --git a/src/main/java/org/qortal/network/message/OnlineAccountsV3Message.java b/src/main/java/org/qortal/network/message/OnlineAccountsV3Message.java
index d554d96c..c057fbce 100644
--- a/src/main/java/org/qortal/network/message/OnlineAccountsV3Message.java
+++ b/src/main/java/org/qortal/network/message/OnlineAccountsV3Message.java
@@ -99,9 +99,10 @@ public class OnlineAccountsV3Message extends Message {
bytes.get(publicKey);
// Nonce is optional - will be -1 if missing
+ // ... but we should skip/ignore an online account if it has no nonce
Integer nonce = bytes.getInt();
if (nonce < 0) {
- nonce = null;
+ continue;
}
onlineAccounts.add(new OnlineAccountData(timestamp, signature, publicKey, nonce));
diff --git a/src/main/resources/q-apps/q-apps.js b/src/main/resources/q-apps/q-apps.js
index d26b7791..b638c621 100644
--- a/src/main/resources/q-apps/q-apps.js
+++ b/src/main/resources/q-apps/q-apps.js
@@ -448,6 +448,10 @@ function getDefaultTimeout(action) {
// User may take a long time to accept/deny the popup
return 60 * 60 * 1000;
+ case "SEARCH_QDN_RESOURCES":
+ // Searching for data can be slow, especially when metadata and statuses are also being included
+ return 30 * 1000;
+
case "FETCH_QDN_RESOURCE":
// Fetching data can take a while, especially if the status hasn't been checked first
return 60 * 1000;
diff --git a/src/test/java/org/qortal/test/network/OnlineAccountsTests.java b/src/test/java/org/qortal/test/network/OnlineAccountsTests.java
index c9e646f1..c8220d66 100644
--- a/src/test/java/org/qortal/test/network/OnlineAccountsTests.java
+++ b/src/test/java/org/qortal/test/network/OnlineAccountsTests.java
@@ -51,89 +51,6 @@ public class OnlineAccountsTests extends Common {
}
- @Test
- public void testGetOnlineAccountsV2() throws MessageException {
- List onlineAccountsOut = generateOnlineAccounts(false);
-
- Message messageOut = new GetOnlineAccountsV2Message(onlineAccountsOut);
-
- byte[] messageBytes = messageOut.toBytes();
- ByteBuffer byteBuffer = ByteBuffer.wrap(messageBytes);
-
- GetOnlineAccountsV2Message messageIn = (GetOnlineAccountsV2Message) Message.fromByteBuffer(byteBuffer);
-
- List onlineAccountsIn = messageIn.getOnlineAccounts();
-
- assertEquals("size mismatch", onlineAccountsOut.size(), onlineAccountsIn.size());
- assertTrue("accounts mismatch", onlineAccountsIn.containsAll(onlineAccountsOut));
-
- Message oldMessageOut = new GetOnlineAccountsMessage(onlineAccountsOut);
- byte[] oldMessageBytes = oldMessageOut.toBytes();
-
- long numTimestamps = onlineAccountsOut.stream().mapToLong(OnlineAccountData::getTimestamp).sorted().distinct().count();
-
- System.out.println(String.format("For %d accounts split across %d timestamp%s: old size %d vs new size %d",
- onlineAccountsOut.size(),
- numTimestamps,
- numTimestamps != 1 ? "s" : "",
- oldMessageBytes.length,
- messageBytes.length));
- }
-
- @Test
- public void testOnlineAccountsV2() throws MessageException {
- List onlineAccountsOut = generateOnlineAccounts(true);
-
- Message messageOut = new OnlineAccountsV2Message(onlineAccountsOut);
-
- byte[] messageBytes = messageOut.toBytes();
- ByteBuffer byteBuffer = ByteBuffer.wrap(messageBytes);
-
- OnlineAccountsV2Message messageIn = (OnlineAccountsV2Message) Message.fromByteBuffer(byteBuffer);
-
- List onlineAccountsIn = messageIn.getOnlineAccounts();
-
- assertEquals("size mismatch", onlineAccountsOut.size(), onlineAccountsIn.size());
- assertTrue("accounts mismatch", onlineAccountsIn.containsAll(onlineAccountsOut));
-
- Message oldMessageOut = new OnlineAccountsMessage(onlineAccountsOut);
- byte[] oldMessageBytes = oldMessageOut.toBytes();
-
- long numTimestamps = onlineAccountsOut.stream().mapToLong(OnlineAccountData::getTimestamp).sorted().distinct().count();
-
- System.out.println(String.format("For %d accounts split across %d timestamp%s: old size %d vs new size %d",
- onlineAccountsOut.size(),
- numTimestamps,
- numTimestamps != 1 ? "s" : "",
- oldMessageBytes.length,
- messageBytes.length));
- }
-
- private List generateOnlineAccounts(boolean withSignatures) {
- List onlineAccounts = new ArrayList<>();
-
- int numTimestamps = RANDOM.nextInt(2) + 1; // 1 or 2
-
- for (int t = 0; t < numTimestamps; ++t) {
- int numAccounts = RANDOM.nextInt(3000);
-
- for (int a = 0; a < numAccounts; ++a) {
- byte[] sig = null;
- if (withSignatures) {
- sig = new byte[Transformer.SIGNATURE_LENGTH];
- RANDOM.nextBytes(sig);
- }
-
- byte[] pubkey = new byte[Transformer.PUBLIC_KEY_LENGTH];
- RANDOM.nextBytes(pubkey);
-
- onlineAccounts.add(new OnlineAccountData(t << 32, sig, pubkey));
- }
- }
-
- return onlineAccounts;
- }
-
@Test
public void testOnlineAccountsModulusV1() throws IllegalAccessException, DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
diff --git a/src/test/java/org/qortal/test/network/OnlineAccountsV3Tests.java b/src/test/java/org/qortal/test/network/OnlineAccountsV3Tests.java
index 6136c1e1..2c3c01ca 100644
--- a/src/test/java/org/qortal/test/network/OnlineAccountsV3Tests.java
+++ b/src/test/java/org/qortal/test/network/OnlineAccountsV3Tests.java
@@ -26,41 +26,6 @@ public class OnlineAccountsV3Tests {
Security.insertProviderAt(new BouncyCastleJsseProvider(), 1);
}
- @Ignore("For informational use")
- @Test
- public void compareV2ToV3() throws MessageException {
- List onlineAccounts = generateOnlineAccounts(false);
-
- // How many of each timestamp and leading byte (of public key)
- Map> hashesByTimestampThenByte = convertToHashMaps(onlineAccounts);
-
- byte[] v3DataBytes = new GetOnlineAccountsV3Message(hashesByTimestampThenByte).toBytes();
- int v3ByteSize = v3DataBytes.length;
-
- byte[] v2DataBytes = new GetOnlineAccountsV2Message(onlineAccounts).toBytes();
- int v2ByteSize = v2DataBytes.length;
-
- int numTimestamps = hashesByTimestampThenByte.size();
- System.out.printf("For %d accounts split across %d timestamp%s: V2 size %d vs V3 size %d%n",
- onlineAccounts.size(),
- numTimestamps,
- numTimestamps != 1 ? "s" : "",
- v2ByteSize,
- v3ByteSize
- );
-
- for (var outerMapEntry : hashesByTimestampThenByte.entrySet()) {
- long timestamp = outerMapEntry.getKey();
-
- var innerMap = outerMapEntry.getValue();
-
- System.out.printf("For timestamp %d: %d / 256 slots used.%n",
- timestamp,
- innerMap.size()
- );
- }
- }
-
private Map> convertToHashMaps(List onlineAccounts) {
// How many of each timestamp and leading byte (of public key)
Map> hashesByTimestampThenByte = new HashMap<>();
@@ -200,7 +165,9 @@ public class OnlineAccountsV3Tests {
byte[] pubkey = new byte[Transformer.PUBLIC_KEY_LENGTH];
RANDOM.nextBytes(pubkey);
- onlineAccounts.add(new OnlineAccountData(timestamp, sig, pubkey));
+ Integer nonce = RANDOM.nextInt();
+
+ onlineAccounts.add(new OnlineAccountData(timestamp, sig, pubkey, nonce));
}
}