mirror of
https://github.com/Qortal/qortal.git
synced 2025-05-05 17:27:52 +00:00
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
This commit is contained in:
parent
e0398490ae
commit
a338202ded
@ -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;
|
||||||
|
@ -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];
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 = (double) Math.sqrt( (sampleSize * timesS2 - timesS1 * timesS1) / stddevDivisor );
|
||||||
|
|
||||||
|
System.out.println(String.format("Difficulty: %d, %d timings, mean: %d ms, stddev: %.2f ms, max nonce: %d",
|
||||||
|
difficulty,
|
||||||
|
sampleSize,
|
||||||
|
timesS1 / sampleSize,
|
||||||
|
stddev,
|
||||||
|
maxNonce));
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
System.out.println(String.format("Max nonce: %d", 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…
x
Reference in New Issue
Block a user