diff --git a/src/main/java/org/qortal/crypto/MemoryPoW.java b/src/main/java/org/qortal/crypto/MemoryPoW.java index d9373fbc..82e88248 100644 --- a/src/main/java/org/qortal/crypto/MemoryPoW.java +++ b/src/main/java/org/qortal/crypto/MemoryPoW.java @@ -66,7 +66,7 @@ public class MemoryPoW { byteBuffer = null; int longBufferLength = workBufferLength / 8; - long[] workBuffer = new long[longBufferLength / 8]; + long[] workBuffer = new long[longBufferLength]; long[] state = new long[4]; long seed = 8682522807148012L; diff --git a/src/main/java/org/qortal/network/Handshake.java b/src/main/java/org/qortal/network/Handshake.java index 8fb0fa2e..80a9a8b9 100644 --- a/src/main/java/org/qortal/network/Handshake.java +++ b/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 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]; diff --git a/src/main/java/org/qortal/transaction/ChatTransaction.java b/src/main/java/org/qortal/transaction/ChatTransaction.java index 74347b11..d3eec9f7 100644 --- a/src/main/java/org/qortal/transaction/ChatTransaction.java +++ b/src/main/java/org/qortal/transaction/ChatTransaction.java @@ -26,8 +26,8 @@ public class ChatTransaction extends Transaction { // Other useful constants public static final int MAX_DATA_SIZE = 256; 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_NO_QORT = 16; // leading zero bits + public static final int POW_DIFFICULTY_WITH_QORT = 8; // leading zero bits + public static final int POW_DIFFICULTY_NO_QORT = 14; // leading zero bits // Constructors diff --git a/src/main/java/org/qortal/transaction/PublicizeTransaction.java b/src/main/java/org/qortal/transaction/PublicizeTransaction.java index a7b0a84a..75cfd2a2 100644 --- a/src/main/java/org/qortal/transaction/PublicizeTransaction.java +++ b/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. */ 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_DIFFICULTY = 18; // leading zero bits + public static final int POW_DIFFICULTY = 15; // leading zero bits // Constructors diff --git a/src/test/java/org/qortal/test/MemoryPoWTests.java b/src/test/java/org/qortal/test/MemoryPoWTests.java index 80759ef2..2427afb0 100644 --- a/src/test/java/org/qortal/test/MemoryPoWTests.java +++ b/src/test/java/org/qortal/test/MemoryPoWTests.java @@ -10,9 +10,6 @@ import java.util.Random; public class MemoryPoWTests { 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 public void testCompute() { @@ -21,69 +18,95 @@ public class MemoryPoWTests { byte[] data = new byte[256]; random.nextBytes(data); + final int difficulty = 8; + long startTime = System.currentTimeMillis(); - // Integer nonce = MemoryPoW.compute(data, workBufferLength, start, range, difficulty); int nonce = MemoryPoW.compute2(data, workBufferLength, difficulty); 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); - 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 public void testMultipleComputes() { Random random = new Random(); - byte[] data = new byte[256]; - int[] times = new int[100]; + final int sampleSize = 20; + final long stddevDivisor = sampleSize * (sampleSize - 1); - int timesS1 = 0; - int timesS2 = 0; + for (int difficulty = 8; difficulty < 16; difficulty += 2) { + 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) { - random.nextBytes(data); + int maxNonce = 0; - long startTime = System.currentTimeMillis(); - int nonce = MemoryPoW.compute2(data, workBufferLength, difficulty); - times[i] = (int) (System.currentTimeMillis() - startTime); + for (int i = 0; i < sampleSize; ++i) { + random.nextBytes(data); - timesS1 += times[i]; - timesS2 += (times[i] * times[i]); + final long startTime = System.currentTimeMillis(); + int nonce = MemoryPoW.compute2(data, workBufferLength, difficulty); + times[i] = System.currentTimeMillis() - startTime; - if (nonce > maxNonce) - maxNonce = nonce; - } + timesS1 += times[i]; + 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)) ); - System.out.println(String.format("%d timings, mean: %d ms, stddev: %.2f ms", times.length, timesS1 / times.length, stddev)); + double stddev = (double) Math.sqrt( (sampleSize * timesS2 - timesS1 * timesS1) / stddevDivisor ); - 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 public void testKnownCompute2() { byte[] data = new byte[] { (byte) 0xaa, (byte) 0xbb, (byte) 0xcc }; - int difficulty = 12; - int expectedNonce = 4013; - int nonce = MemoryPoW.compute2(data, 8 * 1024 * 1024, difficulty); + int difficulty = 8; + int expectedNonce = 326; + int nonce = MemoryPoW.compute2(data, workBufferLength, difficulty); System.out.println(String.format("Difficulty %d, nonce: %d", difficulty, nonce)); assertEquals(expectedNonce, nonce); - difficulty = 16; - expectedNonce = 41029; - nonce = MemoryPoW.compute2(data, 8 * 1024 * 1024, difficulty); + difficulty = 14; + expectedNonce = 11032; + nonce = MemoryPoW.compute2(data, workBufferLength, difficulty); System.out.println(String.format("Difficulty %d, nonce: %d", difficulty, 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)); + } + }