use of io.nuls.kernel.validate.ValidateResult in project nuls by nuls-io.
the class AccountLedgerServiceImpl method verifyAndSaveUnconfirmedTransaction.
@Override
public Result<Integer> verifyAndSaveUnconfirmedTransaction(Transaction tx) {
saveLock.lock();
try {
ValidateResult result = tx.verify();
if (result.isFailed()) {
return result;
}
if (!tx.isSystemTx()) {
Map<String, Coin> toCoinMap = addToCoinMap(tx);
if (usedTxSets == null) {
initUsedTxSets();
}
result = this.ledgerService.verifyCoinData(tx, toCoinMap, usedTxSets);
if (result.isFailed()) {
Log.info("verifyCoinData failed : " + result.getMsg());
return result;
}
}
Result<Integer> res = saveUnconfirmedTransaction(tx);
return res;
} finally {
saveLock.unlock();
}
}
use of io.nuls.kernel.validate.ValidateResult in project nuls by nuls-io.
the class ChainContainer method verifyRedPunish.
private boolean verifyRedPunish(RedPunishTransaction data) {
RedPunishData punishData = data.getTxData();
if (ConsensusConfig.getSeedNodeStringList().contains(AddressTool.getStringAddressByBytes(punishData.getAddress()))) {
Log.warn("The seed node can not be punished!");
return false;
}
HeaderSignValidator validator = NulsContext.getServiceBean(HeaderSignValidator.class);
LedgerService ledgerService = NulsContext.getServiceBean(LedgerService.class);
if (punishData.getReasonCode() == PunishReasonEnum.DOUBLE_SPEND.getCode()) {
if (NulsContext.MAIN_NET_VERSION <= 1) {
Log.warn("The red punish tx need higher version!");
return false;
}
SmallBlock smallBlock = new SmallBlock();
try {
smallBlock.parse(punishData.getEvidence(), 0);
} catch (NulsException e) {
Log.error(e);
return false;
}
BlockHeader header = smallBlock.getHeader();
if (header.getTime() != data.getTime()) {
return false;
}
ValidateResult result = validator.validate(header);
if (result.isFailed()) {
Log.warn(result.getMsg());
return false;
}
List<NulsDigestData> txHashList = smallBlock.getTxHashList();
if (!header.getMerkleHash().equals(NulsDigestData.calcMerkleDigestData(txHashList))) {
Log.warn(TransactionErrorCode.TX_DATA_VALIDATION_ERROR.getMsg());
return false;
}
List<Transaction> txList = smallBlock.getSubTxList();
if (null == txList || txList.size() < 2) {
Log.warn(TransactionErrorCode.TX_DATA_VALIDATION_ERROR.getMsg());
return false;
}
result = ledgerService.verifyDoubleSpend(txList);
if (result.isSuccess()) {
Log.warn(PocConsensusErrorCode.TRANSACTIONS_NEVER_DOUBLE_SPEND.getMsg());
return false;
}
} else if (punishData.getReasonCode() == PunishReasonEnum.BIFURCATION.getCode()) {
if (NulsContext.MAIN_NET_VERSION <= 1) {
Log.warn("The red punish tx need higher version!");
return false;
}
NulsByteBuffer byteBuffer = new NulsByteBuffer(punishData.getEvidence());
// 轮次
long[] roundIndex = new long[NulsContext.REDPUNISH_BIFURCATION];
for (int i = 0; i < NulsContext.REDPUNISH_BIFURCATION && !byteBuffer.isFinished(); i++) {
BlockHeader header1 = null;
BlockHeader header2 = null;
try {
header1 = byteBuffer.readNulsData(new BlockHeader());
header2 = byteBuffer.readNulsData(new BlockHeader());
} catch (NulsException e) {
Log.error(e);
}
if (null == header1 || null == header2) {
Log.warn(KernelErrorCode.DATA_NOT_FOUND.getMsg());
return false;
}
if (header1.getHeight() != header2.getHeight()) {
Log.warn(TransactionErrorCode.TX_DATA_VALIDATION_ERROR.getMsg());
return false;
}
if (i == NulsContext.REDPUNISH_BIFURCATION - 1 && (header1.getTime() + header2.getTime()) / 2 != data.getTime()) {
return false;
}
ValidateResult result = validator.validate(header1);
if (result.isFailed()) {
Log.warn(TransactionErrorCode.TX_DATA_VALIDATION_ERROR.getMsg());
return false;
}
result = validator.validate(header2);
if (result.isFailed()) {
Log.warn(TransactionErrorCode.TX_DATA_VALIDATION_ERROR.getMsg());
return false;
}
if (!Arrays.equals(header1.getBlockSignature().getPublicKey(), header2.getBlockSignature().getPublicKey())) {
Log.warn(TransactionErrorCode.SIGNATURE_ERROR.getMsg());
return false;
}
BlockExtendsData blockExtendsData = new BlockExtendsData(header1.getExtend());
roundIndex[i] = blockExtendsData.getRoundIndex();
}
// 验证轮次是否连续
boolean rs = true;
for (int i = 0; i < roundIndex.length; i++) {
if (i < roundIndex.length - 2 && roundIndex[i + 1] - roundIndex[i] != 1) {
rs = false;
break;
}
}
if (!rs) {
Log.warn(PocConsensusErrorCode.RED_CARD_VERIFICATION_FAILED.getMsg());
return false;
}
} else if (punishData.getReasonCode() != PunishReasonEnum.TOO_MUCH_YELLOW_PUNISH.getCode()) {
Log.warn(PocConsensusErrorCode.RED_CARD_VERIFICATION_FAILED.getMsg());
return false;
}
try {
return verifyCoinData(data);
} catch (IOException e) {
Log.error(e);
return false;
}
}
use of io.nuls.kernel.validate.ValidateResult in project nuls by nuls-io.
the class GenesisBlock method init.
private synchronized void init(String json) throws Exception {
if (status > 0) {
return;
}
Map<String, Object> jsonMap = null;
try {
jsonMap = JSONUtils.json2map(json);
} catch (Exception e) {
Log.error(e);
}
String time = (String) jsonMap.get(CONFIG_FILED_TIME);
AssertUtil.canNotEmpty(time, KernelErrorCode.CONFIG_ERROR.getMsg());
blockTime = Long.parseLong(time);
this.initGengsisTxs(jsonMap);
this.fillHeader(jsonMap);
ValidateResult validateResult = this.verify();
if (validateResult.isFailed()) {
throw new NulsRuntimeException(validateResult.getErrorCode());
}
this.status = 1;
}
use of io.nuls.kernel.validate.ValidateResult in project nuls by nuls-io.
the class UtxoLedgerServiceImpl method verifyDoubleSpend.
/**
* 双花验证不通过的交易需要放入result的data中,一次只验证一对双花的交易
*
* @return ValidateResult<List < Transaction>>
*/
@Override
public ValidateResult<List<Transaction>> verifyDoubleSpend(List<Transaction> txList) {
if (txList == null) {
return ValidateResult.getFailedResult(CLASS_NAME, LedgerErrorCode.NULL_PARAMETER);
}
// 计算HashMap容量
int initialCapacity = 0;
CoinData coinData;
for (Transaction tx : txList) {
coinData = tx.getCoinData();
if (coinData == null) {
continue;
}
initialCapacity += tx.getCoinData().getFrom().size();
}
initialCapacity = MapUtil.tableSizeFor(initialCapacity) << 1;
HashMap<String, Transaction> fromMap = new HashMap<>(initialCapacity);
List<Coin> froms;
Transaction prePutTx;
// 判断是否有重复的fromCoin存在,如果存在,则是双花
for (Transaction tx : txList) {
coinData = tx.getCoinData();
if (coinData == null) {
continue;
}
froms = coinData.getFrom();
for (Coin from : froms) {
prePutTx = fromMap.put(asString(from.getOwner()), tx);
// 不为空则代表此coin在map中已存在,则是双花
if (prePutTx != null) {
List<Transaction> resultList = new ArrayList<>(2);
resultList.add(prePutTx);
resultList.add(tx);
ValidateResult validateResult = ValidateResult.getFailedResult(CLASS_NAME, TransactionErrorCode.TRANSACTION_REPEATED);
validateResult.setData(resultList);
return validateResult;
}
}
}
return ValidateResult.getSuccessResult();
}
use of io.nuls.kernel.validate.ValidateResult in project nuls by nuls-io.
the class TxProcessTask method processTx.
private boolean processTx(Transaction tx, boolean isOrphanTx) {
try {
Result result = tx.verify();
if (result.isFailed()) {
return false;
}
Transaction tempTx = ledgerService.getTx(tx.getHash());
if (tempTx != null) {
return isOrphanTx;
}
ValidateResult validateResult = ledgerService.verifyCoinData(tx, temporaryToMap, temporaryFromSet);
if (validateResult.isSuccess()) {
pool.add(tx, false);
List<Coin> fromCoins = tx.getCoinData().getFrom();
for (Coin coin : fromCoins) {
String key = LedgerUtil.asString(coin.getOwner());
temporaryFromSet.remove(key);
temporaryToMap.remove(key);
}
// count++;
transactionCacheStorageService.putTx(tx);
transactionService.forwardTx(tx, null);
return true;
} else if (validateResult.getErrorCode().equals(TransactionErrorCode.ORPHAN_TX) && !isOrphanTx) {
processOrphanTx(tx);
} else if (isOrphanTx) {
return tx.getTime() < (TimeService.currentTimeMillis() - 3600000L);
}
} catch (Exception e) {
Log.error(e);
}
return false;
}
Aggregations