/* * 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; /** * Created by Anton Nashatyrev on 27.11.2015. */ public class EthashParams { // bytes in word private final int WORD_BYTES = 4; // bytes in dataset at genesis private final long DATASET_BYTES_INIT = 1L << 30; // dataset growth per epoch private final long DATASET_BYTES_GROWTH = 1L << 23; // bytes in dataset at genesis private final long CACHE_BYTES_INIT = 1L << 24; // cache growth per epoch private final long CACHE_BYTES_GROWTH = 1L << 17; // Size of the DAG relative to the cache private final long CACHE_MULTIPLIER = 1024; // blocks per epoch private final long EPOCH_LENGTH = 30000; // width of mix private final int MIX_BYTES = 128; // hash length in bytes private final int HASH_BYTES = 64; // number of parents of each dataset element private final long DATASET_PARENTS = 256; // number of rounds in cache production private final long CACHE_ROUNDS = 3; // number of accesses in hashimoto loop private final long ACCESSES = 64; /** * The parameters for Ethash's cache and dataset depend on the block number. * The cache size and dataset size both grow linearly; however, we always take the highest * prime below the linearly growing threshold in order to reduce the risk of accidental * regularities leading to cyclic behavior. */ public long getCacheSize(long blockNumber) { long sz = CACHE_BYTES_INIT + CACHE_BYTES_GROWTH * (blockNumber / EPOCH_LENGTH); sz -= HASH_BYTES; while (!isPrime(sz / HASH_BYTES)) { sz -= 2 * HASH_BYTES; } return sz; } public long getFullSize(long blockNumber) { long sz = DATASET_BYTES_INIT + DATASET_BYTES_GROWTH * (blockNumber / EPOCH_LENGTH); sz -= MIX_BYTES; while (!isPrime(sz / MIX_BYTES)) { sz -= 2 * MIX_BYTES; } return sz; } private static boolean isPrime(long num) { if (num == 2) return true; if (num % 2 == 0) return false; for (int i = 3; i * i < num; i += 2) if (num % i == 0) return false; return true; } public int getWORD_BYTES() { return WORD_BYTES; } public long getDATASET_BYTES_INIT() { return DATASET_BYTES_INIT; } public long getDATASET_BYTES_GROWTH() { return DATASET_BYTES_GROWTH; } public long getCACHE_BYTES_INIT() { return CACHE_BYTES_INIT; } public long getCACHE_BYTES_GROWTH() { return CACHE_BYTES_GROWTH; } public long getCACHE_MULTIPLIER() { return CACHE_MULTIPLIER; } public long getEPOCH_LENGTH() { return EPOCH_LENGTH; } public int getMIX_BYTES() { return MIX_BYTES; } public int getHASH_BYTES() { return HASH_BYTES; } public long getDATASET_PARENTS() { return DATASET_PARENTS; } public long getCACHE_ROUNDS() { return CACHE_ROUNDS; } public long getACCESSES() { return ACCESSES; } }