Search in sources :

Example 26 with VarInt

use of io.nuls.kernel.utils.VarInt 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();
}
Also used : VarInt(io.nuls.kernel.utils.VarInt) ArrayList(java.util.ArrayList) NulsRuntimeException(io.nuls.kernel.exception.NulsRuntimeException) IOException(java.io.IOException) NulsRuntimeException(io.nuls.kernel.exception.NulsRuntimeException) IOException(java.io.IOException) Entry(io.nuls.db.model.Entry) ArrayList(java.util.ArrayList) List(java.util.List)

Example 27 with VarInt

use of io.nuls.kernel.utils.VarInt 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();
}
Also used : VarInt(io.nuls.kernel.utils.VarInt) ArrayList(java.util.ArrayList) NulsRuntimeException(io.nuls.kernel.exception.NulsRuntimeException) IOException(java.io.IOException) NulsRuntimeException(io.nuls.kernel.exception.NulsRuntimeException) IOException(java.io.IOException) Entry(io.nuls.db.model.Entry) ArrayList(java.util.ArrayList) List(java.util.List)

Example 28 with VarInt

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

the class ContractTxServiceImpl method saveUnConfirmedTokenTransfer.

private Result<byte[]> saveUnConfirmedTokenTransfer(CallContractTransaction tx, String sender, String contractAddress, String methodName, String[][] args) {
    try {
        byte[] senderBytes = AddressTool.getAddress(sender);
        byte[] contractAddressBytes = AddressTool.getAddress(contractAddress);
        Result<ContractAddressInfoPo> contractAddressInfoResult = contractAddressStorageService.getContractAddressInfo(contractAddressBytes);
        ContractAddressInfoPo po = contractAddressInfoResult.getData();
        if (po != null && po.isNrc20() && ContractUtil.isTransferMethod(methodName)) {
            byte[] txHashBytes = tx.getHash().serialize();
            byte[] infoKey = ArraysTool.concatenate(senderBytes, txHashBytes, new VarInt(0).encode());
            ContractTokenTransferInfoPo tokenTransferInfoPo = new ContractTokenTransferInfoPo();
            if (ContractConstant.NRC20_METHOD_TRANSFER.equals(methodName)) {
                String to = args[0][0];
                String tokenValue = args[1][0];
                BigInteger token = new BigInteger(tokenValue);
                Result result = contractBalanceManager.subtractContractToken(sender, contractAddress, token);
                if (result.isFailed()) {
                    return result;
                }
                contractBalanceManager.addContractToken(to, contractAddress, token);
                tokenTransferInfoPo.setFrom(senderBytes);
                tokenTransferInfoPo.setTo(AddressTool.getAddress(to));
                tokenTransferInfoPo.setValue(token);
            } else {
                String from = args[0][0];
                // 转出的不是自己的代币(代币授权逻辑),则不保存token待确认交易,因为有调用合约的待确认交易
                if (!sender.equals(from)) {
                    return Result.getSuccess();
                }
                String to = args[1][0];
                String tokenValue = args[2][0];
                BigInteger token = new BigInteger(tokenValue);
                Result result = contractBalanceManager.subtractContractToken(from, contractAddress, token);
                if (result.isFailed()) {
                    return result;
                }
                contractBalanceManager.addContractToken(to, contractAddress, token);
                tokenTransferInfoPo.setFrom(AddressTool.getAddress(from));
                tokenTransferInfoPo.setTo(AddressTool.getAddress(to));
                tokenTransferInfoPo.setValue(token);
            }
            tokenTransferInfoPo.setName(po.getNrc20TokenName());
            tokenTransferInfoPo.setSymbol(po.getNrc20TokenSymbol());
            tokenTransferInfoPo.setDecimals(po.getDecimals());
            tokenTransferInfoPo.setTime(tx.getTime());
            tokenTransferInfoPo.setContractAddress(contractAddress);
            tokenTransferInfoPo.setBlockHeight(tx.getBlockHeight());
            tokenTransferInfoPo.setTxHash(txHashBytes);
            tokenTransferInfoPo.setStatus((byte) 0);
            Result result = contractTokenTransferStorageService.saveTokenTransferInfo(infoKey, tokenTransferInfoPo);
            if (result.isFailed()) {
                return result;
            }
            return Result.getSuccess().setData(infoKey);
        }
        return Result.getSuccess();
    } catch (Exception e) {
        Log.error(e);
        Result result = Result.getFailed(ContractErrorCode.CONTRACT_TX_CREATE_ERROR);
        result.setMsg(e.getMessage());
        return result;
    }
}
Also used : ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) VarInt(io.nuls.kernel.utils.VarInt) BigInteger(java.math.BigInteger) ContractTokenTransferInfoPo(io.nuls.contract.dto.ContractTokenTransferInfoPo) NulsException(io.nuls.kernel.exception.NulsException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) ContractResult(io.nuls.contract.dto.ContractResult) CoinDataResult(io.nuls.account.ledger.model.CoinDataResult)

Example 29 with VarInt

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

the class BlockHeaderStorageServiceImpl method removeBlockHerader.

private Result removeBlockHerader(byte[] hashBytes) {
    if (null == hashBytes) {
        return Result.getFailed(KernelErrorCode.NULL_PARAMETER);
    }
    BlockHeaderPo blockHeaderPo = getBlockHeaderPo(hashBytes);
    if (null == blockHeaderPo) {
        return Result.getSuccess();
    }
    dbService.delete(ProtocolStorageConstant.DB_NAME_BLOCK_HEADER_INDEX, new VarInt(blockHeaderPo.getHeight()).encode());
    try {
        dbService.put(ProtocolStorageConstant.DB_NAME_BLOCK_HEADER_INDEX, bestBlockKey, blockHeaderPo.getPreHash().serialize());
    } catch (IOException e) {
        Log.error(e);
    }
    return dbService.delete(ProtocolStorageConstant.DB_NAME_BLOCK_HEADER, hashBytes);
}
Also used : VarInt(io.nuls.kernel.utils.VarInt) IOException(java.io.IOException) BlockHeaderPo(io.nuls.protocol.storage.po.BlockHeaderPo)

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