Browse Source

Fix incorrect PoW buffer usage length in verify & adjust difficulties

CHAT: 8 or 14
MESSAGE: 14
PUBLICIZE: 15
Handshake: 8

Added test to cover verify bug
pull/67/head
catbref 4 years ago
parent
commit
a338202ded
  1. 2
      src/main/java/org/qortal/crypto/MemoryPoW.java
  2. 2
      src/main/java/org/qortal/network/Handshake.java
  3. 4
      src/main/java/org/qortal/transaction/ChatTransaction.java
  4. 2
      src/main/java/org/qortal/transaction/PublicizeTransaction.java
  5. 85
      src/test/java/org/qortal/test/MemoryPoWTests.java

2
src/main/java/org/qortal/crypto/MemoryPoW.java

@ -66,7 +66,7 @@ public class MemoryPoW {
byteBuffer = null; byteBuffer = null;
int longBufferLength = workBufferLength / 8; int longBufferLength = workBufferLength / 8;
long[] workBuffer = new long[longBufferLength / 8]; long[] workBuffer = new long[longBufferLength];
long[] state = new long[4]; long[] state = new long[4];
long seed = 8682522807148012L; long seed = 8682522807148012L;

2
src/main/java/org/qortal/network/Handshake.java

@ -211,7 +211,7 @@ public enum Handshake {
private static final Pattern VERSION_PATTERN = Pattern.compile(Controller.VERSION_PREFIX + "(\\d{1,3})\\.(\\d{1,5})\\.(\\d{1,5})"); private static final Pattern VERSION_PATTERN = Pattern.compile(Controller.VERSION_PREFIX + "(\\d{1,3})\\.(\\d{1,5})\\.(\\d{1,5})");
private static final int POW_BUFFER_SIZE = 8 * 1024 * 1024; // bytes private static final int POW_BUFFER_SIZE = 8 * 1024 * 1024; // bytes
private static final int POW_DIFFICULTY = 12; // leading zero bits private static final int POW_DIFFICULTY = 8; // leading zero bits
private static final byte[] ZERO_CHALLENGE = new byte[ChallengeMessage.CHALLENGE_LENGTH]; private static final byte[] ZERO_CHALLENGE = new byte[ChallengeMessage.CHALLENGE_LENGTH];

4
src/main/java/org/qortal/transaction/ChatTransaction.java

@ -26,8 +26,8 @@ public class ChatTransaction extends Transaction {
// Other useful constants // Other useful constants
public static final int MAX_DATA_SIZE = 256; public static final int MAX_DATA_SIZE = 256;
public static final int POW_BUFFER_SIZE = 8 * 1024 * 1024; // bytes public static final int POW_BUFFER_SIZE = 8 * 1024 * 1024; // bytes
public static final int POW_DIFFICULTY_WITH_QORT = 12; // leading zero bits public static final int POW_DIFFICULTY_WITH_QORT = 8; // leading zero bits
public static final int POW_DIFFICULTY_NO_QORT = 16; // leading zero bits public static final int POW_DIFFICULTY_NO_QORT = 14; // leading zero bits
// Constructors // Constructors

2
src/main/java/org/qortal/transaction/PublicizeTransaction.java

@ -26,7 +26,7 @@ public class PublicizeTransaction extends Transaction {
/** If time difference between transaction and now is greater than this then we don't verify proof-of-work. */ /** If time difference between transaction and now is greater than this then we don't verify proof-of-work. */
public static final long HISTORIC_THRESHOLD = 2 * 7 * 24 * 60 * 60 * 1000L; public static final long HISTORIC_THRESHOLD = 2 * 7 * 24 * 60 * 60 * 1000L;
public static final int POW_BUFFER_SIZE = 8 * 1024 * 1024; // bytes public static final int POW_BUFFER_SIZE = 8 * 1024 * 1024; // bytes
public static final int POW_DIFFICULTY = 18; // leading zero bits public static final int POW_DIFFICULTY = 15; // leading zero bits
// Constructors // Constructors

85
src/test/java/org/qortal/test/MemoryPoWTests.java

@ -10,9 +10,6 @@ import java.util.Random;
public class MemoryPoWTests { public class MemoryPoWTests {
private static final int workBufferLength = 8 * 1024 * 1024; private static final int workBufferLength = 8 * 1024 * 1024;
private static final int start = 0;
private static final int range = 1000000;
private static final int difficulty = 11;
@Test @Test
public void testCompute() { public void testCompute() {
@ -21,69 +18,95 @@ public class MemoryPoWTests {
byte[] data = new byte[256]; byte[] data = new byte[256];
random.nextBytes(data); random.nextBytes(data);
final int difficulty = 8;
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
// Integer nonce = MemoryPoW.compute(data, workBufferLength, start, range, difficulty);
int nonce = MemoryPoW.compute2(data, workBufferLength, difficulty); int nonce = MemoryPoW.compute2(data, workBufferLength, difficulty);
long finishTime = System.currentTimeMillis(); long finishTime = System.currentTimeMillis();
System.out.println(String.format("Memory-hard PoW (buffer size: %dKB, range: %d, leading zeros: %d) took %dms", workBufferLength / 1024, range, difficulty, finishTime - startTime));
assertNotNull(nonce); assertNotNull(nonce);
System.out.println(String.format("nonce: %d", nonce)); System.out.println(String.format("Memory-hard PoW (buffer size: %dKB, leading zeros: %d) took %dms, nonce: %d", workBufferLength / 1024,
difficulty,
finishTime - startTime,
nonce));
assertTrue(MemoryPoW.verify2(data, workBufferLength, difficulty, nonce));
} }
@Test @Test
public void testMultipleComputes() { public void testMultipleComputes() {
Random random = new Random(); Random random = new Random();
byte[] data = new byte[256]; final int sampleSize = 20;
int[] times = new int[100]; final long stddevDivisor = sampleSize * (sampleSize - 1);
int timesS1 = 0; for (int difficulty = 8; difficulty < 16; difficulty += 2) {
int timesS2 = 0; byte[] data = new byte[256];
long[] times = new long[sampleSize];
int maxNonce = 0; long timesS1 = 0;
long timesS2 = 0;
for (int i = 0; i < times.length; ++i) { int maxNonce = 0;
random.nextBytes(data);
long startTime = System.currentTimeMillis(); for (int i = 0; i < sampleSize; ++i) {
int nonce = MemoryPoW.compute2(data, workBufferLength, difficulty); random.nextBytes(data);
times[i] = (int) (System.currentTimeMillis() - startTime);
timesS1 += times[i]; final long startTime = System.currentTimeMillis();
timesS2 += (times[i] * times[i]); int nonce = MemoryPoW.compute2(data, workBufferLength, difficulty);
times[i] = System.currentTimeMillis() - startTime;
if (nonce > maxNonce) timesS1 += times[i];
maxNonce = nonce; timesS2 += times[i] * times[i];
}
if (nonce > maxNonce)
maxNonce = nonce;
}
double stddev = Math.sqrt( ((double) times.length * timesS2 - timesS1 * timesS1) / ((double) times.length * (times.length - 1)) ); double stddev = (double) Math.sqrt( (sampleSize * timesS2 - timesS1 * timesS1) / stddevDivisor );
System.out.println(String.format("%d timings, mean: %d ms, stddev: %.2f ms", times.length, timesS1 / times.length, stddev));
System.out.println(String.format("Max nonce: %d", maxNonce)); System.out.println(String.format("Difficulty: %d, %d timings, mean: %d ms, stddev: %.2f ms, max nonce: %d",
difficulty,
sampleSize,
timesS1 / sampleSize,
stddev,
maxNonce));
}
} }
@Test @Test
public void testKnownCompute2() { public void testKnownCompute2() {
byte[] data = new byte[] { (byte) 0xaa, (byte) 0xbb, (byte) 0xcc }; byte[] data = new byte[] { (byte) 0xaa, (byte) 0xbb, (byte) 0xcc };
int difficulty = 12; int difficulty = 8;
int expectedNonce = 4013; int expectedNonce = 326;
int nonce = MemoryPoW.compute2(data, 8 * 1024 * 1024, difficulty); int nonce = MemoryPoW.compute2(data, workBufferLength, difficulty);
System.out.println(String.format("Difficulty %d, nonce: %d", difficulty, nonce)); System.out.println(String.format("Difficulty %d, nonce: %d", difficulty, nonce));
assertEquals(expectedNonce, nonce); assertEquals(expectedNonce, nonce);
difficulty = 16; difficulty = 14;
expectedNonce = 41029; expectedNonce = 11032;
nonce = MemoryPoW.compute2(data, 8 * 1024 * 1024, difficulty); nonce = MemoryPoW.compute2(data, workBufferLength, difficulty);
System.out.println(String.format("Difficulty %d, nonce: %d", difficulty, nonce)); System.out.println(String.format("Difficulty %d, nonce: %d", difficulty, nonce));
assertEquals(expectedNonce, nonce); assertEquals(expectedNonce, nonce);
} }
@Test
public void testKnownVerify() {
byte[] data = new byte[] { (byte) 0xaa, (byte) 0xbb, (byte) 0xcc };
int difficulty = 8;
int expectedNonce = 326;
assertTrue(MemoryPoW.verify2(data, workBufferLength, difficulty, expectedNonce));
difficulty = 14;
expectedNonce = 11032;
assertTrue(MemoryPoW.verify2(data, workBufferLength, difficulty, expectedNonce));
}
} }

Loading…
Cancel
Save