/******************************************************************************
* 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;
/**
* Economic Clustering concept (EC) solves the most critical flaw of "classical" Proof-of-Stake - the problem called
* "Nothing-at-Stake".
*
* I ought to respect BCNext's wish and say that this concept is inspired by Economic Majority idea of Meni Rosenfeld
* (http://en.wikipedia.org/wiki/User:Meni_Rosenfeld).
*
* EC is a vital part of Transparent Forging. Words "Mining in Nxt relies on cooperation of people and even forces it"
* (https://bitcointalk.org/index.php?topic=553205.0) were said about EC.
*
* Keep in mind that this concept has not been peer reviewed. You are very welcome to do it...
*
* Come-from-Beyond (21.05.2014)
*/
public final class EconomicClustering {
private static final Blockchain blockchain = BlockchainImpl.getInstance();
public static Block getECBlock(int timestamp) {
Block block = blockchain.getLastBlock();
if (timestamp < block.getTimestamp() - Constants.MAX_TIMEDRIFT) {
throw new IllegalArgumentException("Timestamp cannot be more than 15 s earlier than last block timestamp: " + block.getTimestamp());
}
int distance = 0;
while (block.getTimestamp() > timestamp - Constants.EC_RULE_TERMINATOR && distance < Constants.EC_BLOCK_DISTANCE_LIMIT) {
block = blockchain.getBlock(block.getPreviousBlockId());
distance += 1;
}
return block;
}
public static boolean verifyFork(Transaction transaction) {
if (blockchain.getHeight() < Constants.DIGITAL_GOODS_STORE_BLOCK) {
return true;
}
if (transaction.getReferencedTransactionFullHash() != null) {
return true;
}
if (blockchain.getHeight() - transaction.getECBlockHeight() > Constants.EC_BLOCK_DISTANCE_LIMIT) {
return false;
}
Block ecBlock = blockchain.getBlock(transaction.getECBlockId());
return ecBlock != null && ecBlock.getHeight() == transaction.getECBlockHeight();
}
}