/******************************************************************************
* Copyright © 2013-2016 The Nxt Core Developers. *
* *
* See the AUTHORS.txt, DEVELOPER-AGREEMENT.txt and LICENSE.txt files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* Nxt software, including this file, may be copied, modified, propagated, *
* or distributed except according to the terms contained in the LICENSE.txt *
* file. *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
package nxt;
import nxt.crypto.HashFunction;
import nxt.util.Convert;
import nxt.util.Logger;
import org.junit.Assert;
import org.junit.Test;
import java.math.BigInteger;
import java.util.Arrays;
public class TestMintCalculations {
@Test
public void targetCalculation() {
byte[] target = CurrencyMinting.getTarget(4, 32, 1, 0, 100000);
Logger.logDebugMessage("initial target: " + Arrays.toString(target));
Assert.assertEquals(32, target.length);
Assert.assertArrayEquals(new byte[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15}, target);
target = CurrencyMinting.getTarget(4, 32, 1, 50000, 100000);
Logger.logDebugMessage("midway target: " + Arrays.toString(target));
Assert.assertEquals(32, target.length);
Assert.assertArrayEquals(new byte[] {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 63, 0, 0}, target);
target = CurrencyMinting.getTarget(4, 32, 1, 100000, 100000);
Logger.logDebugMessage("final target: " + Arrays.toString(target));
Assert.assertEquals(32, target.length);
Assert.assertArrayEquals(new byte[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0}, target);
target = CurrencyMinting.getTarget(4, 32, 100, 100000, 100000);
Logger.logDebugMessage("final target for 100 units: " + Arrays.toString(target));
Assert.assertEquals(32, target.length);
Assert.assertArrayEquals(new byte[]{92, -113, -62, -11, 40, 92, -113, -62, -11, 40, 92, -113, -62, -11, 40, 92, -113, -62, -11, 40, 92, -113, -62, -11, 40, 92, -113, 2, 0, 0, 0, 0}, target);
try {
CurrencyMinting.getTarget(0, 5, 1, 0, 100000);
Assert.fail();
} catch(IllegalArgumentException e) {
Logger.logDebugMessage("Difficulty too low");
}
}
@Test
public void hashing() {
long nonce;
for (nonce=0; nonce < Long.MAX_VALUE; nonce++) {
if (CurrencyMinting.meetsTarget(CurrencyMinting.getHash(HashFunction.Keccak25.getId(), nonce, 123, 1, 1, 987),
CurrencyMinting.getTarget(8, 16, 1, 0, 100000))) {
break;
}
}
Assert.assertEquals(149, nonce);
for (nonce=0; nonce < Long.MAX_VALUE; nonce++) {
if (CurrencyMinting.meetsTarget(CurrencyMinting.getHash(HashFunction.Keccak25.getId(), nonce, 123, 1, 1, 987),
CurrencyMinting.getTarget(8, 16, 1, 100000, 100000))) {
break;
}
}
Assert.assertEquals(120597, nonce);
for (nonce=0; nonce < Long.MAX_VALUE; nonce++) {
if (CurrencyMinting.meetsTarget(CurrencyMinting.getHash(HashFunction.Keccak25.getId(), nonce, 123, 100, 1, 987),
CurrencyMinting.getTarget(8, 16, 100, 0, 100000))) {
break;
}
}
Assert.assertEquals(5123, nonce);
}
@Test
public void sha256() {
byte[] hash = HashFunction.SHA256.hash(new byte[]{0x61,0x62,0x63});
Assert.assertEquals("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", Convert.toHexString(hash));
hash = HashFunction.SHA256.hash(new byte[]{});
Assert.assertEquals("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", Convert.toHexString(hash));
}
@Test
public void sha3() {
byte[] hash = HashFunction.SHA3.hash(new byte[]{(byte)0x41, (byte)0xFB});
Assert.assertEquals("A8EACEDA4D47B3281A795AD9E1EA2122B407BAF9AABCB9E18B5717B7873537D2".toLowerCase(), Convert.toHexString(hash));
hash = HashFunction.SHA3.hash(new byte[]{});
Assert.assertEquals("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", Convert.toHexString(hash));
}
@Test
public void scrypt() {
byte[] hash = HashFunction.SCRYPT.hash(new byte[]{(byte) 0x41, (byte) 0xFB});
Assert.assertEquals("da3f4f010d772567a8896465d11df28693b244c91b8ba4bea5a30f6be572b667".toLowerCase(), Convert.toHexString(hash));
hash = HashFunction.SCRYPT.hash(new byte[]{});
Assert.assertEquals("0cf2967ca5c120e80b37f8f75c971842e05da107278c1058e6ffbc68911c11f1", Convert.toHexString(hash));
}
@Test
public void lowDifficultyProblem() {
BigInteger numericTarget = CurrencyMinting.getNumericTarget(1, 255, 1, 0, 100000);
byte[] targetRowBytes = numericTarget.toByteArray();
Assert.assertEquals(32, targetRowBytes.length);
numericTarget = CurrencyMinting.getNumericTarget(2, 255, 1, 0, 100000);
targetRowBytes = numericTarget.toByteArray();
Assert.assertEquals(32, targetRowBytes.length);
numericTarget = CurrencyMinting.getNumericTarget(254, 255, 1, 0, 100000);
targetRowBytes = numericTarget.toByteArray();
Assert.assertEquals(1, targetRowBytes.length);
numericTarget = CurrencyMinting.getNumericTarget(1, 255, 1, 100000, 100000);
targetRowBytes = numericTarget.toByteArray();
Assert.assertEquals(1, targetRowBytes.length);
numericTarget = CurrencyMinting.getNumericTarget(2, 255, 1, 100000, 100000);
targetRowBytes = numericTarget.toByteArray();
Assert.assertEquals(1, targetRowBytes.length);
numericTarget = CurrencyMinting.getNumericTarget(254, 255, 1, 100000, 100000);
targetRowBytes = numericTarget.toByteArray();
Assert.assertEquals(1, targetRowBytes.length);
}
}