use of io.nuls.kernel.exception.NulsRuntimeException in project nuls by nuls-io.
the class CreateAgentTransaction method clone.
@Override
public CreateAgentTransaction clone() {
CreateAgentTransaction tx = new CreateAgentTransaction();
try {
tx.parse(serialize(), 0);
} catch (Exception e) {
throw new NulsRuntimeException(e);
}
tx.setBlockHeight(blockHeight);
tx.setStatus(status);
tx.setHash(hash);
tx.setSize(size);
Agent agent = tx.getTxData();
agent.setBlockHeight(txData.getBlockHeight());
agent.setDelHeight(txData.getDelHeight());
agent.setTime(txData.getTime());
agent.setTxHash(txData.getTxHash());
agent.setStatus(txData.getStatus());
agent.setTotalDeposit(txData.getTotalDeposit());
agent.setCreditVal(txData.getCreditVal());
return tx;
}
use of io.nuls.kernel.exception.NulsRuntimeException in project nuls by nuls-io.
the class AccountLedgerServiceImpl method getCoinData.
@Override
public CoinDataResult getCoinData(byte[] address, Na amount, int size, Na price) {
if (null == price) {
throw new NulsRuntimeException(KernelErrorCode.PARAMETER_ERROR);
}
lock.lock();
try {
List<Coin> coinList = balanceManager.getCoinListByAddress(address);
coinList = coinList.stream().filter(coin1 -> coin1.usable() && !Na.ZERO.equals(coin1.getNa())).sorted(CoinComparator.getInstance()).collect(Collectors.toList());
CoinDataResult coinDataResult = CoinDataTool.getCoinData(address, amount, size, price, coinList);
return coinDataResult;
} finally {
lock.unlock();
}
}
use of io.nuls.kernel.exception.NulsRuntimeException in project nuls by nuls-io.
the class AccountLedgerServiceImpl method estimateFee.
@Override
public Result estimateFee(byte[] address, Na price) {
if (null == price) {
throw new NulsRuntimeException(KernelErrorCode.PARAMETER_ERROR);
}
Transaction tx = new TransferTransaction();
tx.setTime(TimeService.currentTimeMillis());
lock.lock();
try {
// 获取这个地址的所有coin的总大小
List<Coin> coinList = balanceManager.getCoinListByAddress(address);
if (coinList.isEmpty()) {
// 没有可用余额
return Result.getFailed(TransactionErrorCode.DATA_ERROR);
}
tx.setCoinData(null);
// 默认coindata中to为38 +备注+签名
int txSize = tx.size() + 38 + TxRemarkValidator.MAX_REMARK_LEN;
int targetSize = TxMaxSizeValidator.MAX_TX_SIZE - txSize;
Collections.sort(coinList, CoinComparatorDesc.getInstance());
int size = tx.size() + 38;
// 将所有余额从大到小排序后,累计未花费的余额
byte signType = 0;
int txNum = 1;
for (int i = 0; i < coinList.size(); i++) {
Coin coin = coinList.get(i);
if (!coin.usable()) {
continue;
}
if (coin.getNa().equals(Na.ZERO)) {
continue;
}
size += coin.size();
if (i == 127) {
size += 1;
}
/**
* 判断是否是脚本验证UTXO
*/
if (signType != 3) {
if ((signType & 0x01) == 0 && coin.getTempOwner().length == 23) {
signType = (byte) (signType | 0x01);
size += P2PHKSignature.SERIALIZE_LENGTH;
} else if ((signType & 0x02) == 0 && coin.getTempOwner().length != 23) {
signType = (byte) (signType | 0x02);
size += P2PHKSignature.SERIALIZE_LENGTH;
}
}
if (size > targetSize * txNum) {
// 大于一个tx的size 所以需要另一个tx装
size += txSize;
txNum++;
signType = 0;
}
}
Na fee = TransactionFeeCalculator.getFee(size, price);
return Result.getSuccess().setData(fee);
} catch (Exception e) {
return Result.getFailed(TransactionErrorCode.DATA_ERROR);
} finally {
lock.unlock();
}
}
use of io.nuls.kernel.exception.NulsRuntimeException in project nuls by nuls-io.
the class AccountLedgerServiceImpl method getCoinDataMultipleAdresses.
private CoinDataResult getCoinDataMultipleAdresses(List<MultipleAddressTransferModel> fromList, Na amount, int size, Na price) {
// 获取多个地址的utxo排序
List<Coin> coinListUTXO = new ArrayList<>();
for (int j = 0; j < fromList.size(); j++) {
byte[] address = fromList.get(j).getAddress();
List<Coin> coinList = balanceManager.getCoinListByAddress(address);
coinListUTXO.addAll(coinList);
}
if (null == price) {
throw new NulsRuntimeException(KernelErrorCode.PARAMETER_ERROR);
}
lock.lock();
try {
CoinDataResult coinDataResult = new CoinDataResult();
coinDataResult.setEnough(false);
coinListUTXO = coinListUTXO.stream().filter(coin1 -> coin1.usable() && !Na.ZERO.equals(coin1.getNa())).sorted(CoinComparator.getInstance()).collect(Collectors.toList());
if (coinListUTXO.isEmpty()) {
return coinDataResult;
}
List<Coin> coins = new ArrayList<>();
Na values = Na.ZERO;
// 累加到足够支付转出额与手续费
// 需要找零的地址,找零是找给最后一个utxo的账户
byte[] changeAddress = null;
for (int i = 0; i < coinListUTXO.size(); i++) {
Coin coin = coinListUTXO.get(i);
coins.add(coin);
size += coin.size();
if (i == 127) {
size += 1;
}
// 每次累加一条未花费余额时,需要重新计算手续费
Na fee = TransactionFeeCalculator.getFee(size, price);
values = values.add(coin.getNa());
/**
* 判断是否是脚本验证UTXO
*/
int signType = coinDataResult.getSignType();
if (signType != 3) {
if ((signType & 0x01) == 0 && coin.getTempOwner().length == 23) {
coinDataResult.setSignType((byte) (signType | 0x01));
size += P2PHKSignature.SERIALIZE_LENGTH;
} else if ((signType & 0x02) == 0 && coin.getTempOwner().length != 23) {
coinDataResult.setSignType((byte) (signType | 0x02));
size += P2PHKSignature.SERIALIZE_LENGTH;
}
}
// 需要判断是否找零,如果有找零,则需要重新计算手续费
if (values.isGreaterThan(amount.add(fee))) {
changeAddress = coin.getTempOwner();
Na change = values.subtract(amount.add(fee));
Coin changeCoin = new Coin();
if (changeAddress[2] == NulsContext.P2SH_ADDRESS_TYPE) {
changeCoin.setOwner(SignatureUtil.createOutputScript(changeAddress).getProgram());
} else {
changeCoin.setOwner(changeAddress);
}
changeCoin.setNa(change);
fee = TransactionFeeCalculator.getFee(size + changeCoin.size(), price);
if (values.isLessThan(amount.add(fee))) {
continue;
}
changeCoin.setNa(values.subtract(amount.add(fee)));
if (!changeCoin.getNa().equals(Na.ZERO)) {
coinDataResult.setChange(changeCoin);
}
}
coinDataResult.setFee(fee);
if (values.isGreaterOrEquals(amount.add(fee))) {
coinDataResult.setEnough(true);
coinDataResult.setCoinList(coins);
break;
}
}
return coinDataResult;
} finally {
lock.unlock();
}
}
use of io.nuls.kernel.exception.NulsRuntimeException in project nuls by nuls-io.
the class AccountLedgerServiceImpl method getMutilCoinData.
@Override
public CoinDataResult getMutilCoinData(byte[] address, Na amount, int size, Na price) {
if (null == price) {
throw new NulsRuntimeException(KernelErrorCode.PARAMETER_ERROR);
}
lock.lock();
try {
CoinDataResult coinDataResult = new CoinDataResult();
coinDataResult.setEnough(false);
List<Coin> coinList = ledgerService.getAllUtxo(address);
coinList = coinList.stream().filter(coin1 -> coin1.usable() && !Na.ZERO.equals(coin1.getNa())).sorted(CoinComparator.getInstance()).collect(Collectors.toList());
if (coinList.isEmpty()) {
return coinDataResult;
}
List<Coin> coins = new ArrayList<>();
Na values = Na.ZERO;
// 累加到足够支付转出额与手续费
for (int i = 0; i < coinList.size(); i++) {
Coin coin = coinList.get(i);
coins.add(coin);
size += coin.size();
if (i == 127) {
size += 1;
}
// 每次累加一条未花费余额时,需要重新计算手续费
Na fee = TransactionFeeCalculator.getFee(size, price);
values = values.add(coin.getNa());
// 需要判断是否找零,如果有找零,则需要重新计算手续费
if (values.isGreaterThan(amount.add(fee))) {
Na change = values.subtract(amount.add(fee));
Coin changeCoin = new Coin();
changeCoin.setOwner(SignatureUtil.createOutputScript(address).getProgram());
// changeCoin.setOwner(address);
changeCoin.setNa(change);
fee = TransactionFeeCalculator.getFee(size + changeCoin.size(), price);
if (values.isLessThan(amount.add(fee))) {
continue;
}
changeCoin.setNa(values.subtract(amount.add(fee)));
if (!changeCoin.getNa().equals(Na.ZERO)) {
coinDataResult.setChange(changeCoin);
}
}
coinDataResult.setFee(fee);
if (values.isGreaterOrEquals(amount.add(fee))) {
coinDataResult.setEnough(true);
coinDataResult.setCoinList(coins);
break;
}
}
return coinDataResult;
} finally {
lock.unlock();
}
}
Aggregations