use of io.nuls.kernel.exception.NulsRuntimeException in project nuls by nuls-io.
the class AccountLedgerResource method getUnconfirmedTx.
/**
* 获取未确认的交易
*/
private Result getUnconfirmedTx(String hash) {
Result result = null;
try {
Result<Transaction> txResult = accountLedgerService.getUnconfirmedTransaction(NulsDigestData.fromDigestHex(hash));
if (txResult.isFailed() || null == txResult.getData()) {
result = Result.getFailed(TransactionErrorCode.TX_NOT_EXIST);
} else {
Transaction tx = txResult.getData();
tx.setStatus(TxStatusEnum.UNCONFIRM);
String fromAddress = null;
if (tx.getTransactionSignature() != null) {
TransactionSignature signature = new TransactionSignature();
signature.parse(new NulsByteBuffer(tx.getTransactionSignature()));
if (signature.getP2PHKSignatures() != null && signature.getP2PHKSignatures().size() == 1) {
byte[] addressBytes = AddressTool.getAddress(signature.getP2PHKSignatures().get(0).getPublicKey());
fromAddress = AddressTool.getStringAddressByBytes(addressBytes);
}
}
TransactionDto txDto = null;
CoinData coinData = tx.getCoinData();
if (coinData != null) {
// 组装from数据
List<Coin> froms = coinData.getFrom();
if (froms != null && froms.size() > 0) {
byte[] fromHash, owner;
int fromIndex;
NulsDigestData fromHashObj;
Transaction fromTx;
Coin fromUtxo;
for (Coin from : froms) {
if (fromAddress != null) {
from.setFromAddress(fromAddress);
} else {
owner = from.getOwner();
// owner拆分出txHash和index
fromHash = AccountLegerUtils.getTxHashBytes(owner);
fromIndex = AccountLegerUtils.getIndex(owner);
// 查询from UTXO
fromHashObj = new NulsDigestData();
fromHashObj.parse(fromHash, 0);
// 获取上一笔的to,先查未确认,如果没有再查已确认
fromTx = accountLedgerService.getUnconfirmedTransaction(fromHashObj).getData();
if (null == fromTx) {
fromTx = ledgerService.getTx(fromHashObj);
}
fromUtxo = fromTx.getCoinData().getTo().get(fromIndex);
from.setFrom(fromUtxo);
}
}
}
txDto = new TransactionDto(tx);
List<OutputDto> outputDtoList = new ArrayList<>();
// 组装to数据
List<Coin> tos = coinData.getTo();
if (tos != null && tos.size() > 0) {
String txHash = hash;
OutputDto outputDto = null;
Coin to;
for (int i = 0, length = tos.size(); i < length; i++) {
to = tos.get(i);
outputDto = new OutputDto(to);
outputDto.setTxHash(txHash);
outputDto.setIndex(i);
outputDto.setStatus(0);
outputDtoList.add(outputDto);
}
}
txDto.setOutputs(outputDtoList);
// 计算交易实际发生的金额
calTransactionValue(txDto);
}
result = Result.getSuccess();
result.setData(txDto);
}
} catch (NulsRuntimeException re) {
Log.error(re);
result = Result.getFailed(re.getErrorCode());
} catch (Exception e) {
Log.error(e);
result = Result.getFailed(LedgerErrorCode.SYS_UNKOWN_EXCEPTION);
}
return result;
}
use of io.nuls.kernel.exception.NulsRuntimeException in project nuls by nuls-io.
the class LocalUtxoServiceImpl method deleteUtxoOfTransaction.
@Override
public Result deleteUtxoOfTransaction(Transaction tx) {
if (tx == null) {
return Result.getFailed(KernelErrorCode.NULL_PARAMETER);
}
CoinData coinData = tx.getCoinData();
if (coinData != null) {
// delete utxo - to
List<Coin> tos = coinData.getTo();
List<byte[]> toList = new ArrayList<>();
byte[] outKey;
for (int i = 0, length = tos.size(); i < length; i++) {
try {
// if(!AccountLegerUtils.isLocalAccount(tos.get(i).getOwner()))
if (null == AccountLegerUtils.isLocalAccount(tos.get(i).getAddress())) {
continue;
}
outKey = ArraysTool.concatenate(tx.getHash().serialize(), new VarInt(i).encode());
toList.add(outKey);
} catch (IOException e) {
throw new NulsRuntimeException(e);
}
}
// save - from
List<Coin> froms = coinData.getFrom();
List<Entry<byte[], byte[]>> fromList = new ArrayList<>();
byte[] fromSource;
Coin fromOfFromCoin;
byte[] utxoFromSource;
byte[] fromIndex;
Transaction sourceTx;
byte[] address;
for (Coin from : froms) {
fromSource = from.getOwner();
fromOfFromCoin = from.getFrom();
if (fromOfFromCoin == null) {
utxoFromSource = new byte[tx.getHash().size()];
fromIndex = new byte[fromSource.length - utxoFromSource.length];
System.arraycopy(fromSource, 0, utxoFromSource, 0, tx.getHash().size());
System.arraycopy(fromSource, tx.getHash().size(), fromIndex, 0, fromIndex.length);
try {
sourceTx = ledgerService.getTx(NulsDigestData.fromDigestHex(Hex.encode(utxoFromSource)));
} catch (Exception e) {
continue;
}
if (sourceTx == null) {
return Result.getFailed(TransactionErrorCode.TX_NOT_EXIST);
}
fromOfFromCoin = sourceTx.getCoinData().getTo().get((int) new VarInt(fromIndex, 0).value);
from.setFrom(fromOfFromCoin);
}
if (fromOfFromCoin == null) {
Log.warn("from coin not found!");
continue;
}
address = fromOfFromCoin.getAddress();
if (null == AccountLegerUtils.isLocalAccount(address)) {
continue;
}
try {
fromList.add(new Entry<>(fromSource, fromOfFromCoin.serialize()));
} catch (IOException e) {
throw new NulsRuntimeException(e);
}
}
Result result = localUtxoStorageService.batchSaveAndDeleteUTXO(fromList, toList);
if (result.isFailed() || result.getData() == null || (int) result.getData() != fromList.size() + toList.size()) {
return Result.getFailed();
}
}
return Result.getSuccess();
}
use of io.nuls.kernel.exception.NulsRuntimeException in project nuls by nuls-io.
the class ContractTokenTransferStorageServiceImpl method afterPropertiesSet.
@Override
public void afterPropertiesSet() {
this.area = ContractStorageConstant.DB_NAME_CONTRACT_NRC20_TOKEN_TRANSFER;
Result result = dbService.createArea(this.area);
if (result.isFailed() && !DBErrorCode.DB_AREA_EXIST.equals(result.getErrorCode())) {
throw new NulsRuntimeException(result.getErrorCode());
}
}
use of io.nuls.kernel.exception.NulsRuntimeException in project nuls by nuls-io.
the class ContractUtxoServiceImpl method saveUtxoForContractAddress.
/**
* 从地址的维度上讲,分为两大类交易
* 第一大类交易是普通地址转入合约地址
* 合约交易 - 调用合约时 调用者地址向合约地址转入金额
* 普通转账交易 - 普通地址向合约地址转入金额
* 第二大类交易是智能合约特殊转账交易,合约地址转出到普通地址/合约地址
*
* @param tx
* @return
*/
@Override
public Result saveUtxoForContractAddress(Transaction tx) {
if (tx == null) {
return Result.getFailed(KernelErrorCode.NULL_PARAMETER);
}
CoinData coinData = tx.getCoinData();
if (coinData != null) {
// 在合约独立账本中,只有合约转账(从合约转出)交易才能从合约地址中转出金额,所以只有这类交易才处理fromCoinData -> delete - from
List<byte[]> fromList = new ArrayList<>();
// 合约特殊转账交易
List<Coin> froms = new ArrayList<>();
List<Coin> deleteFroms = new ArrayList<>();
if (tx.getType() == ContractConstant.TX_TYPE_CONTRACT_TRANSFER) {
froms = coinData.getFrom();
byte[] fromSource;
byte[] utxoFromTxHash;
byte[] utxoFromIndex;
int txHashSize = tx.getHash().size();
Coin fromOfFromCoin;
for (Coin from : froms) {
fromSource = from.getOwner();
utxoFromTxHash = new byte[txHashSize];
utxoFromIndex = new byte[fromSource.length - txHashSize];
System.arraycopy(fromSource, 0, utxoFromTxHash, 0, txHashSize);
System.arraycopy(fromSource, txHashSize, utxoFromIndex, 0, utxoFromIndex.length);
fromOfFromCoin = from.getFrom();
if (fromOfFromCoin == null) {
Transaction sourceTx = null;
try {
sourceTx = ledgerService.getTx(NulsDigestData.fromDigestHex(Hex.encode(utxoFromTxHash)));
} catch (Exception e) {
throw new NulsRuntimeException(e);
}
if (sourceTx == null) {
return Result.getFailed(TransactionErrorCode.TX_NOT_EXIST);
}
fromOfFromCoin = sourceTx.getCoinData().getTo().get((int) new VarInt(utxoFromIndex, 0).value);
}
// 非合约地址在合约账本中不处理
if (!ContractUtil.isLegalContractAddress(fromOfFromCoin.getOwner())) {
continue;
}
from.setFrom(fromOfFromCoin);
from.setTempOwner(fromOfFromCoin.getOwner());
from.setKey(asString(fromSource));
deleteFroms.add(from);
fromList.add(fromSource);
}
}
// save utxo - to
List<Coin> tos = coinData.getTo();
List<Coin> contractTos = new ArrayList<>();
List<Entry<byte[], byte[]>> toList = new ArrayList<>();
byte[] txHashBytes;
try {
txHashBytes = tx.getHash().serialize();
} catch (IOException e) {
throw new NulsRuntimeException(e);
}
Coin to;
byte[] toAddress;
byte[] outKey;
for (int i = 0, length = tos.size(); i < length; i++) {
to = tos.get(i);
// toAddress = to.getOwner();
// 非合约地址在合约账本中不处理
toAddress = to.getAddress();
if (!ContractUtil.isLegalContractAddress(toAddress)) {
continue;
}
try {
outKey = ArraysTool.concatenate(txHashBytes, new VarInt(i).encode());
to.setTempOwner(toAddress);
to.setKey(asString(outKey));
contractTos.add(to);
toList.add(new Entry<byte[], byte[]>(outKey, to.serialize()));
} catch (IOException e) {
throw new NulsRuntimeException(e);
}
}
Result<List<Entry<byte[], byte[]>>> result = contractUtxoStorageService.batchSaveAndDeleteUTXO(toList, fromList);
if (result.isFailed() || result.getData() == null) {
return Result.getFailed();
}
// 刷新余额
contractBalanceManager.refreshBalance(contractTos, deleteFroms);
}
return Result.getSuccess();
}
use of io.nuls.kernel.exception.NulsRuntimeException in project nuls by nuls-io.
the class ContractUtxoServiceImpl method deleteUtxoOfTransaction.
@Override
public Result deleteUtxoOfTransaction(Transaction tx) {
if (tx == null) {
return Result.getFailed(KernelErrorCode.NULL_PARAMETER);
}
CoinData coinData = tx.getCoinData();
byte[] txHashBytes;
try {
txHashBytes = tx.getHash().serialize();
} catch (IOException e) {
throw new NulsRuntimeException(e);
}
if (coinData != null) {
// delete utxo - to
List<Coin> tos = coinData.getTo();
List<Coin> contractTos = new ArrayList<>();
List<byte[]> toList = new ArrayList<>();
byte[] outKey;
Coin to;
byte[] toAddress;
for (int i = 0, length = tos.size(); i < length; i++) {
to = tos.get(i);
// toAddress = to.();
toAddress = to.getAddress();
if (!ContractUtil.isLegalContractAddress(toAddress)) {
continue;
}
outKey = ArraysTool.concatenate(txHashBytes, new VarInt(i).encode());
to.setTempOwner(toAddress);
to.setKey(asString(outKey));
contractTos.add(to);
toList.add(outKey);
}
// save - from
List<Entry<byte[], byte[]>> fromList = new ArrayList<>();
List<Coin> froms = new ArrayList<>();
if (tx.getType() == ContractConstant.TX_TYPE_CONTRACT_TRANSFER) {
froms = coinData.getFrom();
int txHashSize = tx.getHash().size();
byte[] fromSource;
byte[] utxoFromHash;
byte[] utxoFromIndex;
Transaction sourceTx;
Coin sourceTxCoinTo;
for (Coin from : froms) {
fromSource = from.getOwner();
utxoFromHash = new byte[txHashSize];
utxoFromIndex = new byte[fromSource.length - txHashSize];
System.arraycopy(fromSource, 0, utxoFromHash, 0, txHashSize);
System.arraycopy(fromSource, txHashSize, utxoFromIndex, 0, utxoFromIndex.length);
try {
sourceTx = ledgerService.getTx(NulsDigestData.fromDigestHex(Hex.encode(utxoFromHash)));
} catch (Exception e) {
continue;
}
if (sourceTx == null) {
return Result.getFailed(TransactionErrorCode.TX_NOT_EXIST);
}
sourceTxCoinTo = sourceTx.getCoinData().getTo().get((int) new VarInt(utxoFromIndex, 0).value);
if (!ContractUtil.isLegalContractAddress(sourceTxCoinTo.getAddress())) {
continue;
}
from.setFrom(sourceTxCoinTo);
from.setTempOwner(sourceTxCoinTo.getAddress());
from.setKey(asString(fromSource));
try {
fromList.add(new Entry<byte[], byte[]>(fromSource, sourceTxCoinTo.serialize()));
} catch (IOException e) {
throw new NulsRuntimeException(e);
}
}
}
// 函数将返回在数据库中存在的to
Result<List<Entry<byte[], byte[]>>> result = contractUtxoStorageService.batchSaveAndDeleteUTXO(fromList, toList);
if (result.isFailed() || result.getData() == null) {
return Result.getFailed();
}
// 回滚余额, 找到已删除的from 加回去, 筛选出已保存的to 减掉
contractBalanceManager.refreshBalance(froms, contractTos);
}
return Result.getSuccess();
}
Aggregations