Search in sources :

Example 6 with VarInt

use of io.nuls.kernel.utils.VarInt in project nuls by nuls-io.

the class ContractServiceImpl method transfer.

/**
 * @param from
 * @param to
 * @param values
 * @param fee
 * @param isSendBack
 * @param orginHash
 * @param blockTime
 * @param toMaps
 * @param contractUsedCoinMap 组装时不操作toMaps, 用 contractUsedCoinMap 来检查UTXO是否已经被使用,如果已使用则跳过
 *                            (合约转账(从合约转出)不同于普通转账,普通转账有本地账本来维护UTXO,并且在打包前已经组装好UTXO,
 *                            而合约转账(从合约转出)是在打包时才组装,此时从合约账本[DB]及打包交易[toMaps]中拿到所有的utxo来组装,
 *                            用 contractUsedCoinMap 来代表已使用的UTXO)
 * @param bestHeight
 * @return
 */
private Result<ContractTransferTransaction> transfer(byte[] from, byte[] to, Na values, Na fee, boolean isSendBack, NulsDigestData orginHash, long blockTime, Map<String, Coin> toMaps, Map<String, Coin> contractUsedCoinMap, Long bestHeight) {
    try {
        if (!ContractLedgerUtil.isExistContractAddress(from)) {
            return Result.getFailed(ContractErrorCode.CONTRACT_ADDRESS_NOT_EXIST);
        }
        ContractTransferTransaction tx = new ContractTransferTransaction();
        tx.setTime(blockTime);
        CoinData coinData = new CoinData();
        List<Coin> tos = coinData.getTo();
        Coin toCoin = new Coin(to, values.subtract(fee));
        tos.add(toCoin);
        // 加入toMaps、contractUsedCoinMap组装UTXO
        // 组装时不操作toMaps, 用 contractUsedCoinMap 来检查UTXO是否已经被使用,如果已使用则跳过
        CoinDataResult coinDataResult = getContractSpecialTransferCoinData(from, values, toMaps, contractUsedCoinMap, bestHeight);
        if (!coinDataResult.isEnough()) {
            return Result.getFailed(TransactionErrorCode.INSUFFICIENT_BALANCE);
        }
        coinData.setFrom(coinDataResult.getCoinList());
        if (coinDataResult.getChange() != null) {
            tos.add(coinDataResult.getChange());
        }
        tx.setCoinData(coinData);
        byte successByte;
        byte[] remark = null;
        if (isSendBack) {
            successByte = 0;
            remark = ContractConstant.SEND_BACK_REMARK.getBytes(NulsConfig.DEFAULT_ENCODING);
        } else {
            successByte = 1;
        }
        tx.setRemark(remark);
        tx.setTxData(new ContractTransferData(orginHash, from, successByte));
        tx.setHash(NulsDigestData.calcDigestData(tx.serializeForHash()));
        // 维护合约地址连续转出交易的未花费UTXO
        byte[] txBytes = tx.getHash().serialize();
        for (int i = 0, size = tos.size(); i < size; i++) {
            if (toMaps != null) {
                toMaps.put(LedgerUtil.asString(ArraysTool.concatenate(txBytes, new VarInt(i).encode())), tos.get(i));
            }
        }
        // 合约转账(从合约转出)交易不需要签名
        return Result.getSuccess().setData(tx);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}
Also used : VarInt(io.nuls.kernel.utils.VarInt) IOException(java.io.IOException) CoinDataResult(io.nuls.account.ledger.model.CoinDataResult)

Example 7 with VarInt

use of io.nuls.kernel.utils.VarInt in project nuls by nuls-io.

the class ContractServiceImpl method rollbackToMapAndContractUsedCoinMap.

private void rollbackToMapAndContractUsedCoinMap(Transaction tx, Map<String, Coin> toMaps, Map<String, Coin> contractUsedCoinMap) {
    if (tx == null || tx.getCoinData() == null || contractUsedCoinMap == null) {
        return;
    }
    CoinData coinData = tx.getCoinData();
    List<Coin> froms = coinData.getFrom();
    List<Coin> tos = coinData.getTo();
    String key;
    for (Coin from : froms) {
        key = from.getKey();
        if (key != null) {
            contractUsedCoinMap.remove(from.getKey());
        }
    }
    try {
        byte[] txHashBytes = tx.getHash().serialize();
        for (int i = 0, size = tos.size(); i < size; i++) {
            toMaps.remove(LedgerUtil.asString(ArraysTool.concatenate(txHashBytes, new VarInt(i).encode())));
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
Also used : VarInt(io.nuls.kernel.utils.VarInt) LedgerUtil.asString(io.nuls.ledger.util.LedgerUtil.asString) NulsException(io.nuls.kernel.exception.NulsException) IOException(java.io.IOException)

Example 8 with VarInt

use of io.nuls.kernel.utils.VarInt in project nuls by nuls-io.

the class ContractUtil method getStateRoot.

public static byte[] getStateRoot(BlockHeader blockHeader) {
    if (blockHeader == null || blockHeader.getExtend() == null) {
        return null;
    }
    byte[] stateRoot = blockHeader.getStateRoot();
    if (stateRoot != null && stateRoot.length > 0) {
        return stateRoot;
    }
    try {
        byte[] extend = blockHeader.getExtend();
        if (extend.length > BLOCK_EXTENDS_DATA_FIX_LENGTH) {
            VarInt varInt = new VarInt(extend, BLOCK_EXTENDS_DATA_FIX_LENGTH);
            int lengthFieldSize = varInt.getOriginalSizeInBytes();
            int stateRootlength = (int) varInt.value;
            stateRoot = new byte[stateRootlength];
            System.arraycopy(extend, BLOCK_EXTENDS_DATA_FIX_LENGTH + lengthFieldSize, stateRoot, 0, stateRootlength);
            blockHeader.setStateRoot(stateRoot);
            return stateRoot;
        }
    } catch (Exception e) {
        Log.error("parse stateRoot error.", e);
    }
    return null;
}
Also used : VarInt(io.nuls.kernel.utils.VarInt)

Example 9 with VarInt

use of io.nuls.kernel.utils.VarInt in project nuls by nuls-io.

the class UtxoLedgerServiceImpl method rollbackUnlockTxCoinData.

@Override
public Result rollbackUnlockTxCoinData(Transaction tx) throws NulsException {
    if (tx == null || tx.getCoinData() == null) {
        return ValidateResult.getFailedResult(CLASS_NAME, LedgerErrorCode.NULL_PARAMETER);
    }
    try {
        CoinData coinData = tx.getCoinData();
        List<Coin> tos = coinData.getTo();
        boolean isExistLockUtxo = false;
        Coin needUnLockUtxo = null;
        int needUnLockUtxoIndex = 0;
        for (Coin to : tos) {
            if (to.getLockTime() == -1) {
                isExistLockUtxo = true;
                needUnLockUtxo = to;
                break;
            }
            needUnLockUtxoIndex++;
        }
        if (!isExistLockUtxo) {
            return ValidateResult.getFailedResult(CLASS_NAME, LedgerErrorCode.UTXO_STATUS_CHANGE);
        }
        byte[] txHashBytes = tx.getHash().serialize();
        Result result = utxoLedgerUtxoStorageService.saveUtxo(Arrays.concatenate(txHashBytes, new VarInt(needUnLockUtxoIndex).encode()), needUnLockUtxo);
        if (result.isFailed()) {
            throw new NulsException(result.getErrorCode());
        }
        return result;
    } catch (IOException e) {
        Log.error(e);
        throw new NulsException(KernelErrorCode.IO_ERROR);
    }
}
Also used : VarInt(io.nuls.kernel.utils.VarInt) NulsException(io.nuls.kernel.exception.NulsException) IOException(java.io.IOException) ValidateResult(io.nuls.kernel.validate.ValidateResult)

Example 10 with VarInt

use of io.nuls.kernel.utils.VarInt in project nuls by nuls-io.

the class UtxoLedgerServiceImpl method rollbackCoinData.

private Result rollbackCoinData(Transaction tx) throws IOException, NulsException {
    byte[] txHashBytes = tx.getHash().serialize();
    BatchOperation batch = utxoLedgerUtxoStorageService.createWriteBatch();
    CoinData coinData = tx.getCoinData();
    if (coinData != null) {
        // 保存utxo已花费 - from
        List<Coin> froms = coinData.getFrom();
        Coin recovery;
        for (Coin from : froms) {
            try {
                NulsByteBuffer byteBuffer = new NulsByteBuffer(from.getOwner());
                NulsDigestData fromTxHash = byteBuffer.readHash();
                int fromIndex = (int) byteBuffer.readVarInt();
                Transaction fromTx = utxoLedgerTransactionStorageService.getTx(fromTxHash);
                recovery = fromTx.getCoinData().getTo().get(fromIndex);
                recovery.setFrom(from.getFrom());
                batch.put(from.getOwner(), recovery.serialize());
            } catch (IOException e) {
                Log.error(e);
                return Result.getFailed(KernelErrorCode.IO_ERROR);
            }
        }
        // 删除utxo - to
        List<Coin> tos = coinData.getTo();
        for (int i = 0, length = tos.size(); i < length; i++) {
            byte[] owner = Arrays.concatenate(txHashBytes, new VarInt(i).encode());
            // Log.info("批量删除:" + Hex.encode(owner));
            batch.delete(owner);
        }
        // 执行批量
        Result batchResult = batch.executeBatch();
        if (batchResult.isFailed()) {
            return batchResult;
        }
    }
    return Result.getSuccess();
}
Also used : VarInt(io.nuls.kernel.utils.VarInt) BatchOperation(io.nuls.db.service.BatchOperation) IOException(java.io.IOException) NulsByteBuffer(io.nuls.kernel.utils.NulsByteBuffer) ValidateResult(io.nuls.kernel.validate.ValidateResult)

Aggregations

VarInt (io.nuls.kernel.utils.VarInt)29 IOException (java.io.IOException)24 NulsRuntimeException (io.nuls.kernel.exception.NulsRuntimeException)13 NulsException (io.nuls.kernel.exception.NulsException)11 ArrayList (java.util.ArrayList)7 ContractTokenTransferInfoPo (io.nuls.contract.dto.ContractTokenTransferInfoPo)6 ContractAddressInfoPo (io.nuls.contract.storage.po.ContractAddressInfoPo)6 ValidateResult (io.nuls.kernel.validate.ValidateResult)6 ContractResult (io.nuls.contract.dto.ContractResult)5 Entry (io.nuls.db.model.Entry)5 DepositTransaction (io.nuls.consensus.poc.protocol.tx.DepositTransaction)4 CoinDataResult (io.nuls.account.ledger.model.CoinDataResult)3 Account (io.nuls.account.model.Account)3 MultiSigAccount (io.nuls.account.model.MultiSigAccount)3 CancelDeposit (io.nuls.consensus.poc.protocol.entity.CancelDeposit)3 CancelDepositTransaction (io.nuls.consensus.poc.protocol.tx.CancelDepositTransaction)3 Result (io.nuls.kernel.model.Result)3 UnsupportedEncodingException (java.io.UnsupportedEncodingException)3 ContractTransferTransaction (io.nuls.contract.entity.tx.ContractTransferTransaction)2 CreateContractTransaction (io.nuls.contract.entity.tx.CreateContractTransaction)2