/* * Copyright (c) [2016] [ <ether.camp> ] * This file is part of the ethereumJ library. * * The ethereumJ library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The ethereumJ library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the ethereumJ library. If not, see <http://www.gnu.org/licenses/>. */ package org.ethereum.mine; import org.apache.commons.lang3.tuple.Pair; import org.ethereum.TestUtils; import org.ethereum.config.SystemProperties; import org.ethereum.core.Block; import org.ethereum.util.ByteUtil; import org.ethereum.util.FastByteComparisons; import org.ethereum.util.blockchain.StandaloneBlockchain; import org.junit.*; import org.spongycastle.util.encoders.Hex; import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import static org.ethereum.crypto.HashUtil.sha3; import static org.ethereum.util.ByteUtil.*; import static org.junit.Assert.assertArrayEquals; /** * Created by Anton Nashatyrev on 02.12.2015. */ public class EthashTest { @BeforeClass public static void setup() { SystemProperties.getDefault().setBlockchainConfig(StandaloneBlockchain.getEasyMiningConfig()); } @AfterClass public static void cleanup() { SystemProperties.resetToDefault(); } @Test // check exact values public void test_0() { byte[] rlp = Hex.decode("f9021af90215a0809870664d9a43cf1827aa515de6374e2fad1bf64290a9f261dd49c525d6a0efa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794f927a40c8b7f6e07c5af7fa2155b4864a4112b13a010c8ec4f62ecea600c616443bcf527d97e5b1c5bb4a9769c496d1bf32636c95da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086015a1c28ae5e82bf958302472c808455c4e47b99476574682f76312e302e312f6c696e75782f676f312e342e32a0788ac534cb2f6a226a01535e29b11a96602d447aed972463b5cbcc7dd5d633f288e2ff1b6435006517c0c0"); Block b = new Block(rlp); EthashAlgo ethash = new EthashAlgo(); long cacheSize = ethash.getParams().getCacheSize(b.getNumber()); long fullSize = ethash.getParams().getFullSize(b.getNumber()); byte[] seedHash = ethash.getSeedHash(b.getNumber()); int[] cache = ethash.makeCache(cacheSize, seedHash); byte[] blockTrunkHash = sha3(b.getHeader().getEncodedWithoutNonce()); long nonce = ByteUtil.byteArrayToLong(b.getNonce()); long timeSum = 0; for (int i = 0; i < 100; i++) { long s = System.currentTimeMillis(); Pair<byte[], byte[]> pair = ethash.hashimotoLight(fullSize, cache, blockTrunkHash, longToBytes(nonce)); timeSum += System.currentTimeMillis() - s; System.out.println("Time: " + (System.currentTimeMillis() - s)); nonce++; } Assert.assertTrue("hashimotoLigt took > 500ms in avrg", timeSum / 100 < 500); Pair<byte[], byte[]> pair = ethash.hashimotoLight(fullSize, cache, blockTrunkHash, b.getNonce()); System.out.println(Hex.toHexString(pair.getLeft())); System.out.println(Hex.toHexString(pair.getRight())); byte[] boundary = b.getHeader().getPowBoundary(); byte[] pow = b.getHeader().calcPowValue(); assertArrayEquals(Hex.decode("0000000000bd59a74a8619f14c3d793747f1989a29ed6c83a5a488bac185679b"), boundary); assertArrayEquals(Hex.decode("000000000017f78925469f2f18fe7866ef6d3ed28d36fb013bc93d081e05809c"), pow); assertArrayEquals(pow, pair.getRight()); } @Test public void cacheTest() { EthashAlgo ethash = new EthashAlgo(); byte[] seed = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~".getBytes(); long cacheSize = 1024; long fullSize = 1024 * 32; int[] cache = ethash.makeCache(cacheSize, seed); Assert.assertArrayEquals(intsToBytes(cache, false), Hex.decode("2da2b506f21070e1143d908e867962486d6b0a02e31d468fd5e3a7143aafa76a14201f63374314e2a6aaf84ad2eb57105dea3378378965a1b3873453bb2b78f9a8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995ca8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995ca8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995c259440b89fa3481c2c33171477c305c8e1e421f8d8f6d59585449d0034f3e421808d8da6bbd0b6378f567647cc6c4ba6c434592b198ad444e7284905b7c6adaf70bf43ec2daa7bd5e8951aa609ab472c124cf9eba3d38cff5091dc3f58409edcc386c743c3bd66f92408796ee1e82dd149eaefbf52b00ce33014a6eb3e50625413b072a58bc01da28262f42cbe4f87d4abc2bf287d15618405a1fe4e386fcdafbb171064bd99901d8f81dd6789396ce5e364ac944bbbd75a7827291c70b42d26385910cd53ca535ab29433dd5c5714d26e0dce95514c5ef866329c12e958097e84462197c2b32087849dab33e88b11da61d52f9dbc0b92cc61f742c07dbbf751c49d7678624ee60dfbe62e5e8c47a03d8247643f3d16ad8c8e663953bcda1f59d7e2d4a9bf0768e789432212621967a8f41121ad1df6ae1fa78782530695414c6213942865b2730375019105cae91a4c17a558d4b63059661d9f108362143107babe0b848de412e4da59168cce82bfbff3c99e022dd6ac1e559db991f2e3f7bb910cefd173e65ed00a8d5d416534e2c8416ff23977dbf3eb7180b75c71580d08ce95efeb9b0afe904ea12285a392aff0c8561ff79fca67f694a62b9e52377485c57cc3598d84cac0a9d27960de0cc31ff9bbfe455acaa62c8aa5d2cce96f345da9afe843d258a99c4eaf3650fc62efd81c7b81cd0d534d2d71eeda7a6e315d540b4473c80f8730037dc2ae3e47b986240cfc65ccc565f0d8cde0bc68a57e39a271dda57440b3598bee19f799611d25731a96b5dbbbefdff6f4f656161462633030d62560ea4e9c161cf78fc96a2ca5aaa32453a6c5dea206f766244e8c9d9a8dc61185ce37f1fc804459c5f07434f8ecb34141b8dcae7eae704c950b55556c5f40140c3714b45eddb02637513268778cbf937a33e4e33183685f9deb31ef54e90161e76d969587dd782eaa94e289420e7c2ee908517f5893a26fdb5873d68f92d118d4bcf98d7a4916794d6ab290045e30f9ea00ca547c584b8482b0331ba1539a0f2714fddc3a0b06b0cfbb6a607b8339c39bcfd6640b1f653e9d70ef6c985b")); int[] bytes = ethash.calcDatasetItem(cache, 0); Assert.assertArrayEquals(intsToBytes(bytes, false), Hex.decode("b1698f829f90b35455804e5185d78f549fcb1bdce2bee006d4d7e68eb154b596be1427769eb1c3c3e93180c760af75f81d1023da6a0ffbe321c153a7c0103597")); byte[] blockHash = "~~~X~~~~~~~~~~~~~~~~~~~~~~~~~~~~".getBytes(); long nonce = 0x7c7c597cL; Pair<byte[], byte[]> pair = ethash.hashimotoLight(fullSize, cache, blockHash, longToBytes(nonce)); // comparing mix hash Assert.assertArrayEquals(pair.getLeft(), Hex.decode("d7b668b90c2f26961d98d7dd244f5966368165edbce8cb8162dd282b6e5a8eae")); // comparing the final hash Assert.assertArrayEquals(pair.getRight(), Hex.decode("b8cb1cb3ac1a7a6e12c4bc90f2779ef97e661f7957619e677636509d2f26055c")); System.out.println(Hex.toHexString(pair.getLeft())); System.out.println(Hex.toHexString(pair.getRight())); } @Test public void cacheTestFast() { EthashAlgo ethash = new EthashAlgo(); byte[] seed = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~".getBytes(); long cacheSize = 1024; long fullSize = 1024 * 32; int[] cache = ethash.makeCache(cacheSize, seed); Assert.assertArrayEquals(intsToBytes(cache, false), Hex.decode("2da2b506f21070e1143d908e867962486d6b0a02e31d468fd5e3a7143aafa76a14201f63374314e2a6aaf84ad2eb57105dea3378378965a1b3873453bb2b78f9a8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995ca8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995ca8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995c259440b89fa3481c2c33171477c305c8e1e421f8d8f6d59585449d0034f3e421808d8da6bbd0b6378f567647cc6c4ba6c434592b198ad444e7284905b7c6adaf70bf43ec2daa7bd5e8951aa609ab472c124cf9eba3d38cff5091dc3f58409edcc386c743c3bd66f92408796ee1e82dd149eaefbf52b00ce33014a6eb3e50625413b072a58bc01da28262f42cbe4f87d4abc2bf287d15618405a1fe4e386fcdafbb171064bd99901d8f81dd6789396ce5e364ac944bbbd75a7827291c70b42d26385910cd53ca535ab29433dd5c5714d26e0dce95514c5ef866329c12e958097e84462197c2b32087849dab33e88b11da61d52f9dbc0b92cc61f742c07dbbf751c49d7678624ee60dfbe62e5e8c47a03d8247643f3d16ad8c8e663953bcda1f59d7e2d4a9bf0768e789432212621967a8f41121ad1df6ae1fa78782530695414c6213942865b2730375019105cae91a4c17a558d4b63059661d9f108362143107babe0b848de412e4da59168cce82bfbff3c99e022dd6ac1e559db991f2e3f7bb910cefd173e65ed00a8d5d416534e2c8416ff23977dbf3eb7180b75c71580d08ce95efeb9b0afe904ea12285a392aff0c8561ff79fca67f694a62b9e52377485c57cc3598d84cac0a9d27960de0cc31ff9bbfe455acaa62c8aa5d2cce96f345da9afe843d258a99c4eaf3650fc62efd81c7b81cd0d534d2d71eeda7a6e315d540b4473c80f8730037dc2ae3e47b986240cfc65ccc565f0d8cde0bc68a57e39a271dda57440b3598bee19f799611d25731a96b5dbbbefdff6f4f656161462633030d62560ea4e9c161cf78fc96a2ca5aaa32453a6c5dea206f766244e8c9d9a8dc61185ce37f1fc804459c5f07434f8ecb34141b8dcae7eae704c950b55556c5f40140c3714b45eddb02637513268778cbf937a33e4e33183685f9deb31ef54e90161e76d969587dd782eaa94e289420e7c2ee908517f5893a26fdb5873d68f92d118d4bcf98d7a4916794d6ab290045e30f9ea00ca547c584b8482b0331ba1539a0f2714fddc3a0b06b0cfbb6a607b8339c39bcfd6640b1f653e9d70ef6c985b")); int[] i = ethash.calcDatasetItem(cache, 0); Assert.assertArrayEquals(intsToBytes(i, false), Hex.decode("b1698f829f90b35455804e5185d78f549fcb1bdce2bee006d4d7e68eb154b596be1427769eb1c3c3e93180c760af75f81d1023da6a0ffbe321c153a7c0103597")); // byte[] blockHash = "~~~X~~~~~~~~~~~~~~~~~~~~~~~~~~~~".getBytes(); long nonce = 0x7c7c597cL; Pair<byte[], byte[]> pair = ethash.hashimotoLight(fullSize, cache, blockHash, longToBytes(nonce)); // comparing mix hash Assert.assertArrayEquals(pair.getLeft(), Hex.decode("d7b668b90c2f26961d98d7dd244f5966368165edbce8cb8162dd282b6e5a8eae")); // comparing the final hash Assert.assertArrayEquals(pair.getRight(), Hex.decode("b8cb1cb3ac1a7a6e12c4bc90f2779ef97e661f7957619e677636509d2f26055c")); System.out.println(Hex.toHexString(pair.getLeft())); System.out.println(Hex.toHexString(pair.getRight())); } @Test public void realBlockValidateTest1() { byte[] rlp = Hex.decode("f9021af90215a0809870664d9a43cf1827aa515de6374e2fad1bf64290a9f261dd49c525d6a0efa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794f927a40c8b7f6e07c5af7fa2155b4864a4112b13a010c8ec4f62ecea600c616443bcf527d97e5b1c5bb4a9769c496d1bf32636c95da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086015a1c28ae5e82bf958302472c808455c4e47b99476574682f76312e302e312f6c696e75782f676f312e342e32a0788ac534cb2f6a226a01535e29b11a96602d447aed972463b5cbcc7dd5d633f288e2ff1b6435006517c0c0"); Block b = new Block(rlp); EthashAlgo ethash = new EthashAlgo(); long cacheSize = ethash.getParams().getCacheSize(b.getNumber()); long fullSize = ethash.getParams().getFullSize(b.getNumber()); byte[] seedHash = ethash.getSeedHash(b.getNumber()); long s = System.currentTimeMillis(); int[] cache = ethash.makeCache(cacheSize, seedHash); System.out.println("Cache generation took: " + (System.currentTimeMillis() - s) + " ms"); byte[] blockTruncHash = sha3(b.getHeader().getEncodedWithoutNonce()); Pair<byte[], byte[]> pair = ethash.hashimotoLight(fullSize, cache, blockTruncHash, b.getNonce()); System.out.println(Hex.toHexString(pair.getLeft())); System.out.println(Hex.toHexString(pair.getRight())); byte[] boundary = b.getHeader().getPowBoundary(); Assert.assertTrue(FastByteComparisons.compareTo(pair.getRight(), 0, 32, boundary, 0, 32) < 0); } @Test public void realBlockValidateTest2() { byte[] rlp = Hex.decode("f9021af90215a06b42cf11dbb8a448a118939d1a68773f3deca05f8063d26113dac5f9f8ce6713a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452bc44d5378309ee2abf1539bf71de1b7d7be3b5a037b5b65861017992bd33375bb71e0752d57eb94972a9496177f056aa340a2843a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008606b6e75611ca830a2ace832fefd880845668803198d783010203844765746887676f312e342e32856c696e7578a08eddfce4ba14ac38363b0534d12ed7ad4c224897dd443730256f04c6f835449f88108919adc0f2952bc0c0"); Block b = new Block(rlp); System.out.println(b); boolean valid = Ethash.getForBlock(SystemProperties.getDefault(), b.getNumber()).validate(b.getHeader()); Assert.assertTrue(valid); } @Test public void realBlockValidateTest3() { String blocks = "f9021af90215a0cc395ced01d7af387640ac1258ab8819b84ca3e59ff476d933441c3800c63928a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794738db714c08b8a32a29e0e68af00215079aa9c5ca03665d3f9edac25c8a8cdad22945e0fb2e6812f679bea3445639b3890f310ced9a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008606b4637b26e7830a2ac9832fefd8808456687ffc98d783010203844765746887676f312e352e31856c696e7578a0a64edb0df18caa7d36fcb8ca740fee12d4d82b39883ddb3d729414122ba7410688524d07ed4c40ab09c0c0\n" + "f9021af90215a0c49ccf0465b0222c815aed70ec9a8317ffe2cfe3539e9340c6bbeb06699a80dea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942a65aca4d5fc5b5c859090a6c34d164135398226a00a550ad67f02eeb6030abf46f9c88435a05b058374ea1ee4c177ef28c4d2f475a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008606b53a07965b830a2aca832fefd880845668800198d783010302844765746887676f312e352e31856c696e7578a035f6b345260d8c3807bb0e805f23866c5ba9431a9e9a5e240101f541990f47f5886796ab8d23f3c3c2c0c0\n" + "f9021af90215a076e41437e45099f2a0872a8df8623a644ead1136afe751358c56781513ecb74ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452bc44d5378309ee2abf1539bf71de1b7d7be3b5a09b0dcb614329b921c4ef22eb4f8a913539806da3cbe43c1eafa37cfa3943a845a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008606b610aed75d830a2acb832fefd880845668800598d783010203844765746887676f312e342e32856c696e7578a056ac10c8b2378f46b610db89631968bc5f409f32934f287b95d5cfbe12cefd05886ba4adf9b970445ec0c0\n" + "f902fdf90217a09daf27b854a6e1272c2f3070f7729ba5f4891a9dc324c360a0ad32d1d62419f7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794790b8a3ce86e707ed0ed32bf89b3269692a23cc1a02b7e61e61837adb79b36eee4e1589b2c2140852bb105dc034d5cfa052c6ef5b8a0b36ebb69537e04d3bcd94a20bebcb12a8ef4715eb26fc1d19382392cc98db9b1a0c86bea989ed46040c5d1cbc39da108fb249bb9bf0804a5889e897f7e0c710864b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008606b539ecc193830a2acc832fefd882a410845668801a98d783010302844765746887676f312e352e31856c696e7578a0d82d30ce9d68e733738eee0c6f37c95968622878334f4f010e95acae000bb40188b34e28af786cc323f8e0f86f82d65e850ba43b740083015f9094ff45159c63fb01f45cd86767a020406f06faa8528820d3ff69fe230800801ba0d0ea8a650bf50b61b421e8275a79219988889c3e86460b323fb3d4d60bd80d3ca05a653410e7fd97786b3b503936127ece61ed3dcfabdbcbe8d7f06066f4a41687f86d822a3b850ba43b740082520894c47aaa860008be6f65b58c6c6e02a84e666efe318742087a56e84c00801ca0bc2b89b75b68e7ad8eb1db4de4aa550db79df3bd6430f2258fe55805ca7d7fe7a07d8b53c48f24788f21e3a26cfbd007cdab71a8ef7f28f6f6fae6ed4dcd4a0df1c0\n" + "f9021af90215a07cda9a6543dfcafccba0aa0a1a78156ecc7f4b679b8401aec57472294db63a06a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452bc44d5378309ee2abf1539bf71de1b7d7be3b5a0ac89cd6a0d58b13786cef698cfeda1f21edbfbd00b67db034cf2f62497b95359a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008606b61093ff3b830a2acd832fefd880845668802598d783010203844765746887676f312e342e32856c696e7578a0b969e4528849b36fc9c019e83e53cee58e5ef6c3fb3b00105570e602b2a39f1f88aabdc28bdf9e4799c0c0\n" + "f9021af90215a06b42cf11dbb8a448a118939d1a68773f3deca05f8063d26113dac5f9f8ce6713a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452bc44d5378309ee2abf1539bf71de1b7d7be3b5a037b5b65861017992bd33375bb71e0752d57eb94972a9496177f056aa340a2843a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008606b6e75611ca830a2ace832fefd880845668803198d783010203844765746887676f312e342e32856c696e7578a08eddfce4ba14ac38363b0534d12ed7ad4c224897dd443730256f04c6f835449f88108919adc0f2952bc0c0\n" + "f9036ef90217a0cb927dc709468a107fac77151c6dff1ab73eabcccc57d82d238a7b5554f6db51a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794580992b51e3925e23280efb93d3047c82f17e038a03a68272caba0b4a825667d3d223bb8c18f6f793bd8151822b27798716c0b23cba01e360dfc633f5d2edad4e75cfa36555ae480ce346dcce8f253bb0d298e043dcaa0644b51189a7f9d4287e78fb923ced0b8b30edee234d6756fd06b45abc7ec12bdb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008606b7be32fc9c830a2acf832fefd882f618845668803a98d783010400844765746887676f312e352e31856c696e7578a09a1a1cb1182fa1c8baeb7f2abd3f109d85b136f5968c76c3c26977dad5dba1ec88de7908cc14f57037f90150f86e82b609850ba43b740083015f909454cec426307c1acaa63b25aa48fade5df9e5d418872fe2475ad71000801ba0884206762dfebbdc69d5fb92ca1c33999a419f9c9ec116e02594f9535a30c9a0a05daf584f1b480ff599e4ed62278bac9c9d4c4f16af1d65504c13dbb713aa3539f86f82b60a850ba43b740083015f9094f442c4ab4d8cf106bcda6b1f7994485f3f4291a9880df897c536bccc00801ba0a7c7855917b5f8319651d241f3ca2ac5d728a76c83c43cb9e60adc9af1988051a009f117ce8cdfccc762d7a221abc19eb8773176c6f56b75c8ce2a1b907e0a3babf86d81d6850ba43b740082562294fbb1b73c4f0bda4f67dca266ce6ef42f520fbb988820d04471d11f6800801ba065586cc9545ea639580de624574644c34ea9bd0d2e7bfd8bab8f5ed3de572d86a0431d8fc8fcc803413f9f0ded6eaf267cb072bfed75fff97286623dd78e0e3d40c0"; for (String s : blocks.split("\\n")) { Block b = new Block(Hex.decode(s)); System.out.println(b); boolean valid = Ethash.getForBlock(SystemProperties.getDefault(), b.getNumber()).validate(b.getHeader()); Assert.assertTrue(valid); } System.out.println("OK"); } @Test public void blockMineTest()throws Exception { byte[] rlp = Hex.decode("f9021af90215a0809870664d9a43cf1827aa515de6374e2fad1bf64290a9f261dd49c525d6a0efa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794f927a40c8b7f6e07c5af7fa2155b4864a4112b13a010c8ec4f62ecea600c616443bcf527d97e5b1c5bb4a9769c496d1bf32636c95da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008600000000010082bf958302472c808455c4e47b99476574682f76312e302e312f6c696e75782f676f312e342e32a0788ac534cb2f6a226a01535e29b11a96602d447aed972463b5cbcc7dd5d633f288e2ff1b6435006517c0c0"); Block b = new Block(rlp); System.out.println(b); long nonce = Ethash.getForBlock(SystemProperties.getDefault(), b.getNumber()).mineLight(b).get().nonce; b.setNonce(longToBytes(nonce)); Assert.assertTrue(Ethash.getForBlock(SystemProperties.getDefault(), b.getNumber()).validate(b.getHeader())); } @Test public void changeEpochTestLight()throws Exception { List<Block> blocks = TestUtils.getRandomChain(new byte[32], 29999, 3); for (Block b : blocks) { b.getHeader().setDifficulty(ByteUtil.intToBytes(100)); b.setNonce(new byte[0]); long nonce = Ethash.getForBlock(SystemProperties.getDefault(), b.getNumber()).mineLight(b).get().nonce; b.setNonce(longToBytes(nonce)); Assert.assertTrue(Ethash.getForBlock(SystemProperties.getDefault(), b.getNumber()).validate(b.getHeader())); } } @Ignore // takes ~20 min @Test public void changeEpochTest()throws Exception { List<Block> blocks = TestUtils.getRandomChain(new byte[32], 29999, 3); for (Block b : blocks) { b.getHeader().setDifficulty(ByteUtil.intToBytes(100)); b.setNonce(new byte[0]); long nonce = Ethash.getForBlock(SystemProperties.getDefault(), b.getNumber()).mine(b).get().nonce; b.setNonce(longToBytes(nonce)); Assert.assertTrue(Ethash.getForBlock(SystemProperties.getDefault(), b.getNumber()).validate(b.getHeader())); } } @Test public void mineCancelTest() throws Exception { byte[] rlp = Hex.decode("f9021af90215a0809870664d9a43cf1827aa515de6374e2fad1bf64290a9f261dd49c525d6a0efa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794f927a40c8b7f6e07c5af7fa2155b4864a4112b13a010c8ec4f62ecea600c616443bcf527d97e5b1c5bb4a9769c496d1bf32636c95da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008600000000010082bf958302472c808455c4e47b99476574682f76312e302e312f6c696e75782f676f312e342e32a0788ac534cb2f6a226a01535e29b11a96602d447aed972463b5cbcc7dd5d633f288e2ff1b6435006517c0c0"); // small difficulty Block b = new Block(rlp); // large difficulty Block difficultBlock = new Block(Hex.decode("f9021af90215a0809870664d9a43cf1827aa515de6374e2fad1bf64290a9f261dd49c525d6a0efa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794f927a40c8b7f6e07c5af7fa2155b4864a4112b13a010c8ec4f62ecea600c616443bcf527d97e5b1c5bb4a9769c496d1bf32636c95da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008600000001000082bf958302472c808455c4e47b99476574682f76312e302e312f6c696e75782f676f312e342e32a0788ac534cb2f6a226a01535e29b11a96602d447aed972463b5cbcc7dd5d633f288e2ff1b6435006517c0c0")); // first warming up for the cache to be created System.out.println("Warming..."); long res = Ethash.getForBlock(SystemProperties.getDefault(), b.getNumber()).mineLight(b).get().nonce; System.out.println("Submitting..."); Future<MinerIfc.MiningResult> light = Ethash.getForBlock(SystemProperties.getDefault(), b.getNumber()).mineLight(difficultBlock, 8); Thread.sleep(200); long s = System.nanoTime(); boolean cancel = light.cancel(true); try { System.out.println("Waiting"); light.get(); Assert.assertTrue(false); } catch (InterruptedException|ExecutionException|CancellationException e) { System.out.println("Exception: ok"); } long t = System.nanoTime() - s; System.out.println("Time: " + (t / 1000) + " usec"); Assert.assertTrue(cancel); Assert.assertTrue(t < 500_000_000); Assert.assertTrue(light.isCancelled()); b.setNonce(new byte[0]); Ethash.getForBlock(SystemProperties.getDefault(), b.getNumber()).mineLight(b, 8).get(); boolean validate = Ethash.getForBlock(SystemProperties.getDefault(), b.getNumber()).validate(b.getHeader()); Assert.assertTrue(validate); } @Test @Ignore public void fullDagTime() { EthashAlgo ethashAlgo = new EthashAlgo(); System.out.println("Calculating cache..."); int[] cache = ethashAlgo.makeCache(16_000_000, ethashAlgo.getSeedHash(0)); long s = System.currentTimeMillis(); System.out.println("Calculating full DAG..."); // ethashAlgo.calcDataset(1_000_000_000, cache); int[][] ret = new int[(1_000_000_000 / ethashAlgo.getParams().getHASH_BYTES())][]; long ss = 0; for (int i = 0; i < ret.length; i++) { ret[i] = ethashAlgo.calcDatasetItem(cache, i); if (i % 10000 == 0 && i > 0) { System.out.println("Calculated " + i + " of " + ret.length + " in "+ (System.currentTimeMillis() - s) / 1000 + " sec " + "Speed: " + (i - 100000) / ((System.currentTimeMillis() - ss) / 1000d) + " items/sec"); if (i == 100000) ss = System.currentTimeMillis(); } } System.out.println("Calculated in " + (System.currentTimeMillis() - s) / 1000 + " sec"); } @Test @Ignore public void fullDagMineTime() throws ExecutionException, InterruptedException { Ethash.fileCacheEnabled = true; byte[] rlp = Hex.decode("f9021af90215a0809870664d9a43cf1827aa515de6374e2fad1bf64290a9f261dd49c525d6a0efa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794f927a40c8b7f6e07c5af7fa2155b4864a4112b13a010c8ec4f62ecea600c616443bcf527d97e5b1c5bb4a9769c496d1bf32636c95da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008600000000010082bf958302472c808455c4e47b99476574682f76312e302e312f6c696e75782f676f312e342e32a0788ac534cb2f6a226a01535e29b11a96602d447aed972463b5cbcc7dd5d633f288e2ff1b6435006517c0c0"); // small difficulty Block b = new Block(rlp); b.getHeader().setDifficulty(longToBytesNoLeadZeroes(0x20000)); b.setExtraData(new byte[] {}); Ethash ethash = Ethash.getForBlock(SystemProperties.getDefault(), 0); System.out.println("Generating DAG..."); ethash.mine(b).get(); System.out.println("DAG generated..."); System.out.println("Mining block with diff: " + b.getDifficultyBI()); long s = System.currentTimeMillis(); for (int i = 0; i < 100; i++) { b.setExtraData(intToBytes(i)); ethash.mine(b, 8).get(); if (!ethash.validate(b.getHeader())) { throw new RuntimeException("Not validated: " + b); } System.out.print("."); } System.out.println(); System.out.println("Mined 100 blocks in " + (System.currentTimeMillis() - s) / 1000 + " sec"); } }