Search in sources :

Example 1 with Result

use of io.nuls.kernel.model.Result in project nuls by nuls-io.

the class CallContractTxProcessor method onRollback.

@Override
public Result onRollback(CallContractTransaction tx, Object secondaryData) {
    try {
        // 回滚代币转账交易
        byte[] txHashBytes = null;
        try {
            txHashBytes = tx.getHash().serialize();
        } catch (IOException e) {
            Log.error(e);
        }
        ContractResult contractResult = tx.getContractResult();
        if (contractResult == null) {
            contractResult = contractService.getContractExecuteResult(tx.getHash());
        }
        CallContractData txData = tx.getTxData();
        byte[] senderContractAddressBytes = txData.getContractAddress();
        Result<ContractAddressInfoPo> senderContractAddressInfoResult = contractAddressStorageService.getContractAddressInfo(senderContractAddressBytes);
        ContractAddressInfoPo po = senderContractAddressInfoResult.getData();
        if (po != null) {
            if (contractResult != null) {
                // 处理合约执行失败 - 没有transferEvent的情况, 直接从数据库中删除
                if (!contractResult.isSuccess()) {
                    if (ContractUtil.isTransferMethod(txData.getMethodName())) {
                        contractTokenTransferStorageService.deleteTokenTransferInfo(ArraysTool.concatenate(txData.getSender(), txHashBytes, new VarInt(0).encode()));
                    }
                }
                List<String> events = contractResult.getEvents();
                int size = events.size();
                // 目前只处理Transfer事件
                String event;
                ContractAddressInfoPo contractAddressInfo;
                if (events != null && size > 0) {
                    for (int i = 0; i < size; i++) {
                        event = events.get(i);
                        // 按照NRC20标准,TransferEvent事件中第一个参数是转出地址-from,第二个参数是转入地址-to, 第三个参数是金额
                        ContractTokenTransferInfoPo tokenTransferInfoPo = ContractUtil.convertJsonToTokenTransferInfoPo(event);
                        if (tokenTransferInfoPo == null) {
                            continue;
                        }
                        String contractAddress = tokenTransferInfoPo.getContractAddress();
                        if (StringUtils.isBlank(contractAddress)) {
                            continue;
                        }
                        if (!AddressTool.validAddress(contractAddress)) {
                            continue;
                        }
                        byte[] contractAddressBytes = AddressTool.getAddress(contractAddress);
                        if (ArraysTool.arrayEquals(senderContractAddressBytes, contractAddressBytes)) {
                            contractAddressInfo = po;
                        } else {
                            Result<ContractAddressInfoPo> contractAddressInfoResult = contractAddressStorageService.getContractAddressInfo(contractAddressBytes);
                            contractAddressInfo = contractAddressInfoResult.getData();
                        }
                        if (contractAddressInfo == null) {
                            continue;
                        }
                        // 事件不是NRC20合约的事件
                        if (!contractAddressInfo.isNrc20()) {
                            continue;
                        }
                        // 回滚token余额
                        this.rollbackContractToken(tokenTransferInfoPo);
                        contractTokenTransferStorageService.deleteTokenTransferInfo(ArraysTool.concatenate(tokenTransferInfoPo.getFrom(), txHashBytes, new VarInt(i).encode()));
                        contractTokenTransferStorageService.deleteTokenTransferInfo(ArraysTool.concatenate(tokenTransferInfoPo.getTo(), txHashBytes, new VarInt(i).encode()));
                    }
                }
            }
        }
        // 删除子交易从全网账本
        // 删除子交易从合约账本
        // 删除子交易从本地账本
        List<ContractTransferTransaction> contractTransferTxList = this.extractContractTransferTxs(contractResult);
        if (contractTransferTxList != null && !contractTransferTxList.isEmpty()) {
            // 用于回滚本地账本
            List<Transaction> txList = new ArrayList<>();
            for (ContractTransferTransaction transferTx : contractTransferTxList) {
                try {
                    txList.add(transferTx);
                    Result result = ledgerService.rollbackTx(transferTx);
                    if (result.isFailed()) {
                        Log.error("rollback contract transfer tx from ledger error. msg: {}", result.getMsg());
                        return result;
                    }
                    result = contractService.rollbackContractTransferTx(transferTx);
                    if (result.isFailed()) {
                        Log.error("rollback contract transfer tx from contract ledger error. msg: {}", result.getMsg());
                        return Result.getFailed();
                    }
                } catch (Exception e) {
                    Log.error("rollback contract transfer tx error. msg: {}", e.getMessage());
                    return Result.getFailed();
                }
            }
            Result result = accountLedgerService.rollbackTransactions(txList);
            if (result.isFailed()) {
                Log.error("rollback contract transfer tx from account ledger error. msg: {}", result.getMsg());
                return Result.getFailed();
            }
        }
        // 删除合约调用交易的UTXO
        contractUtxoService.deleteUtxoOfTransaction(tx);
        // 删除合约执行结果
        contractService.deleteContractExecuteResult(tx.getHash());
    } catch (Exception e) {
        Log.error("rollback call contract tx error.", e);
        return Result.getFailed();
    }
    return Result.getSuccess();
}
Also used : ContractResult(io.nuls.contract.dto.ContractResult) VarInt(io.nuls.kernel.utils.VarInt) ArrayList(java.util.ArrayList) IOException(java.io.IOException) CallContractData(io.nuls.contract.entity.txdata.CallContractData) IOException(java.io.IOException) ContractResult(io.nuls.contract.dto.ContractResult) ValidateResult(io.nuls.kernel.validate.ValidateResult) Result(io.nuls.kernel.model.Result) ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) ContractTransferTransaction(io.nuls.contract.entity.tx.ContractTransferTransaction) CallContractTransaction(io.nuls.contract.entity.tx.CallContractTransaction) Transaction(io.nuls.kernel.model.Transaction) ContractTransferTransaction(io.nuls.contract.entity.tx.ContractTransferTransaction) ContractTokenTransferInfoPo(io.nuls.contract.dto.ContractTokenTransferInfoPo)

Example 2 with Result

use of io.nuls.kernel.model.Result in project nuls by nuls-io.

the class ContractUtxoStorageServiceImpl method batchSaveAndDeleteUTXO.

@Override
public Result<List<Entry<byte[], byte[]>>> batchSaveAndDeleteUTXO(List<Entry<byte[], byte[]>> utxosToSave, List<byte[]> utxosToDelete) {
    BatchOperation batch = dbService.createWriteBatch(ContractStorageConstant.DB_NAME_CONTRACT_LEDGER_UTXO);
    List<Entry<byte[], byte[]>> deleteUtxoEntryList = new ArrayList<>();
    byte[] deleteUtxo;
    if (utxosToDelete != null) {
        for (byte[] key : utxosToDelete) {
            batch.delete(key);
        }
    }
    if (utxosToSave != null) {
        for (Entry<byte[], byte[]> entry : utxosToSave) {
            batch.put(entry.getKey(), entry.getValue());
        }
    }
    Result batchResult = batch.executeBatch();
    if (batchResult.isFailed()) {
        return batchResult;
    }
    return Result.getSuccess().setData(deleteUtxoEntryList);
}
Also used : Entry(io.nuls.db.model.Entry) ArrayList(java.util.ArrayList) BatchOperation(io.nuls.db.service.BatchOperation) Result(io.nuls.kernel.model.Result)

Example 3 with Result

use of io.nuls.kernel.model.Result in project nuls by nuls-io.

the class DownloadUtils method getBlockByHash.

public static Block getBlockByHash(NulsDigestData hash, Node node) {
    if (hash == null || node == null) {
        return null;
    }
    GetBlockMessage message = new GetBlockMessage(hash);
    Future<Block> future = ProtocolCacheHandler.addGetBlockByHashRequest(hash);
    Future<NulsDigestData> reactFuture = ProtocolCacheHandler.addRequest(hash);
    Result result = messageBusService.sendToNode(message, node, false);
    // Log.error("start request:"+new Date().toLocaleString()+" ::: "+hash);
    if (!result.isSuccess()) {
        ProtocolCacheHandler.removeBlockByHashFuture(hash);
        ProtocolCacheHandler.removeRequest(hash);
        return null;
    }
    try {
        reactFuture.get(1L, TimeUnit.SECONDS);
        Block block = future.get(30L, TimeUnit.SECONDS);
        return block;
    } catch (Exception e) {
        Log.error(node.getId(), e);
        return null;
    } finally {
        ProtocolCacheHandler.removeBlockByHashFuture(hash);
        ProtocolCacheHandler.removeRequest(hash);
    }
}
Also used : Block(io.nuls.kernel.model.Block) NulsDigestData(io.nuls.kernel.model.NulsDigestData) IOException(java.io.IOException) Result(io.nuls.kernel.model.Result)

Example 4 with Result

use of io.nuls.kernel.model.Result in project nuls by nuls-io.

the class ForwardTxMessageHandler method onMessage.

@Override
public void onMessage(ForwardTxMessage message, Node fromNode) {
    if (message == null || fromNode == null || !fromNode.isHandShake() || null == message.getMsgBody()) {
        return;
    }
    NulsDigestData hash = message.getMsgBody();
    boolean consains = TransactionDuplicateRemoval.mightContain(hash);
    if (consains) {
        return;
    }
    TransactionDuplicateRemoval.insert(hash);
    GetTxMessage getTxMessage = new GetTxMessage();
    getTxMessage.setMsgBody(hash);
    Result result = messageBusService.sendToNode(getTxMessage, fromNode, true);
    if (result.isFailed()) {
        return;
    }
}
Also used : GetTxMessage(io.nuls.protocol.message.GetTxMessage) NulsDigestData(io.nuls.kernel.model.NulsDigestData) Result(io.nuls.kernel.model.Result)

Example 5 with Result

use of io.nuls.kernel.model.Result in project nuls by nuls-io.

the class GetBlocksByHashHandler method sendNotFound.

private void sendNotFound(NulsDigestData hash, Node node) {
    NotFoundMessage message = new NotFoundMessage();
    NotFound data = new NotFound(MessageDataType.BLOCKS, hash);
    message.setMsgBody(data);
    Result result = this.messageBusService.sendToNode(message, node, true);
    if (result.isFailed()) {
        Log.warn("send BLOCK NotFound failed:" + node.getId() + ", hash:" + hash);
    }
}
Also used : NotFound(io.nuls.protocol.model.NotFound) Result(io.nuls.kernel.model.Result)

Aggregations

Result (io.nuls.kernel.model.Result)70 NulsException (io.nuls.kernel.exception.NulsException)16 IOException (java.io.IOException)15 NulsRuntimeException (io.nuls.kernel.exception.NulsRuntimeException)12 ValidateResult (io.nuls.kernel.validate.ValidateResult)11 AccountPo (io.nuls.account.storage.po.AccountPo)7 RpcClientResult (io.nuls.kernel.model.RpcClientResult)7 ArrayList (java.util.ArrayList)7 Account (io.nuls.account.model.Account)6 NulsDigestData (io.nuls.kernel.model.NulsDigestData)5 Test (org.junit.Test)5 CryptoException (io.nuls.core.tools.crypto.Exception.CryptoException)4 BatchOperation (io.nuls.db.service.BatchOperation)4 Address (io.nuls.kernel.model.Address)4 Block (io.nuls.kernel.model.Block)4 BlockHeader (io.nuls.kernel.model.BlockHeader)4 Transaction (io.nuls.kernel.model.Transaction)4 Node (io.nuls.network.model.Node)4 NotFound (io.nuls.protocol.model.NotFound)4 ApiOperation (io.swagger.annotations.ApiOperation)4