Search in sources :

Example 1 with Transaction

use of io.nuls.kernel.model.Transaction 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 Transaction

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

the class GetTxGroupHandler method onMessage.

@Override
public void onMessage(GetTxGroupRequest message, Node fromNode) {
    if (message == null || fromNode == null) {
        return;
    }
    GetTxGroupParam getTxGroupParam = message.getMsgBody();
    if (getTxGroupParam == null || getTxGroupParam.getTxHashList() == null || getTxGroupParam.getTxHashList().size() > 10000) {
        return;
    }
    NulsDigestData requestHash = null;
    try {
        requestHash = NulsDigestData.calcDigestData(getTxGroupParam.serialize());
    } catch (IOException e) {
        Log.error(e);
        return;
    }
    TxGroupMessage txGroupMessage = new TxGroupMessage();
    TxGroup txGroup = new TxGroup();
    List<Transaction> txList = new ArrayList<>();
    for (NulsDigestData hash : getTxGroupParam.getTxHashList()) {
        Transaction tx = transactionService.getTx(hash);
        if (tx != null) {
            txList.add(tx);
        } else {
            Log.error("GetTxGroupHandler NULL TX=========================================hash: " + hash.getDigestHex());
            return;
        }
    }
    if (txList.isEmpty()) {
        Log.error("ASK:{}, {}", fromNode, getTxGroupParam.getTxHashList().get(0));
        return;
    }
    txGroup.setTxList(txList);
    txGroup.setRequestHash(requestHash);
    txGroupMessage.setMsgBody(txGroup);
    messageBusService.sendToNode(txGroupMessage, fromNode, true);
}
Also used : TxGroup(io.nuls.protocol.model.TxGroup) Transaction(io.nuls.kernel.model.Transaction) GetTxGroupParam(io.nuls.protocol.model.GetTxGroupParam) ArrayList(java.util.ArrayList) NulsDigestData(io.nuls.kernel.model.NulsDigestData) IOException(java.io.IOException) TxGroupMessage(io.nuls.protocol.message.TxGroupMessage)

Example 3 with Transaction

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

the class TransactionMessageHandler method onMessage.

@Override
public void onMessage(TransactionMessage message, Node fromNode) {
    Transaction tx = message.getMsgBody();
    if (null == tx) {
        return;
    }
    if (tx.isSystemTx()) {
        return;
    }
    NulsDigestData hash = tx.getHash();
    TransactionDuplicateRemoval.insert(hash);
    transactionService.newTx(tx);
}
Also used : Transaction(io.nuls.kernel.model.Transaction) NulsDigestData(io.nuls.kernel.model.NulsDigestData)

Example 4 with Transaction

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

the class NulsVersionHandler method startElement.

@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    super.startElement(uri, localName, qName, attributes);
    // 读取模块配置的协议
    if (INCLUD.equals(qName)) {
        String xmlName = attributes.getValue(INCLUD_SRC);
        XmlLoader.loadXml(xmlName, new ProtocolVersionHandler());
    }
    // 读取版本协议
    if (PROTOCOL.equals(qName)) {
        protocolContainer = new ProtocolContainer();
        String version = attributes.getValue(PROTOCOL_VERSION);
        String percent = attributes.getValue(PROTOCOL_PERCENT);
        String delay = attributes.getValue(PROTOCOL_DELAY);
        if (!StringUtils.isNumeric(version) || !StringUtils.isNumeric(percent) || !StringUtils.isNumeric(delay)) {
            Log.error(KernelErrorCode.CONFIG_ERROR.getMsg());
            throw new SAXException();
        }
        protocolContainer.setVersion(Integer.parseInt(version.trim()));
        protocolContainer.setPercent(Integer.parseInt(percent.trim()));
        protocolContainer.setDelay(Integer.parseInt(delay.trim()));
        String extend = attributes.getValue(PROTOCOL_EXTEND);
        if (StringUtils.isNotBlank(extend) && !StringUtils.isNumeric(percent)) {
            Log.error(KernelErrorCode.CONFIG_ERROR.getMsg());
            throw new SAXException();
        }
        extendTS = StringUtils.isBlank(extend) ? null : Integer.parseInt(extend.trim());
        String block = attributes.getValue(PROTOCOL_BLOCK);
        if (StringUtils.isNotBlank(block)) {
            Class blockClass = null;
            try {
                blockClass = Class.forName(block.trim());
                protocolContainer.setBlockClass(blockClass);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                throw new SAXException();
            }
        } else {
            if (null != extendTS) {
                ProtocolContainer parentPC = NulsVersionManager.getProtocolContainer(extendTS);
                if (null == parentPC || null == parentPC.getBlockClass()) {
                    throw new SAXException();
                }
                protocolContainer.setBlockClass(parentPC.getBlockClass());
            } else {
                Log.error(KernelErrorCode.CONFIG_ERROR.getMsg());
                throw new SAXException();
            }
        }
        discardsTx = new HashMap<>();
        discardsMsg = new HashMap<>();
    }
    // 失效Tx协议
    if (PROTOCOL_TX_DISCARD.equals(qName)) {
        String discard = attributes.getValue(REF);
        if (!NulsVersionManager.containsTxId(discard)) {
            throw new SAXException(discard);
        }
        Class txCLass = NulsVersionManager.getTxProtocol(discard.trim());
        Transaction tx = null;
        try {
            tx = (Transaction) txCLass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        discardsTx.put(tx.getType(), txCLass);
    }
    // 新生效Tx协议
    if (PROTOCOL_TX.equals(qName)) {
        String txId = attributes.getValue(REF);
        if (!NulsVersionManager.containsTxId(txId)) {
            throw new SAXException(txId);
        }
        Class txCLass = NulsVersionManager.getTxProtocol(txId);
        Transaction tx = null;
        try {
            tx = (Transaction) txCLass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        protocolContainer.putTransaction(tx.getType(), txCLass);
    }
    // 失效的msg协议
    if (PROTOCOL_MSG_DISCARD.equals(qName)) {
        String msgId = attributes.getValue(REF);
        if (!NulsVersionManager.containsMessageId(msgId)) {
            throw new SAXException(msgId);
        }
        Class txCLass = NulsVersionManager.getMessageProtocol(msgId);
        BaseMessage msg = null;
        try {
            msg = (BaseMessage) txCLass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        String moduleId = String.valueOf(msg.getHeader().getModuleId());
        String type = String.valueOf(msg.getHeader().getMsgType());
        String key = moduleId + "-" + type;
        discardsMsg.put(key, txCLass);
    }
    // 新生效的msg协议
    if (PROTOCOL_MSG.equals(qName)) {
        String msgId = attributes.getValue(REF);
        if (!NulsVersionManager.containsMessageId(msgId)) {
            throw new SAXException(msgId);
        }
        Class txCLass = NulsVersionManager.getMessageProtocol(msgId);
        BaseMessage msg = null;
        try {
            msg = (BaseMessage) txCLass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        String moduleId = String.valueOf(msg.getHeader().getModuleId());
        String type = String.valueOf(msg.getHeader().getMsgType());
        String key = moduleId + "-" + type;
        protocolContainer.putMessage(key, txCLass);
    }
}
Also used : Transaction(io.nuls.kernel.model.Transaction) BaseMessage(io.nuls.protocol.message.base.BaseMessage) SAXException(org.xml.sax.SAXException)

Example 5 with Transaction

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

the class GetTxMessageHandler method onMessage.

@Override
public void onMessage(GetTxMessage message, Node fromNode) {
    if (message == null || fromNode == null || null == message.getMsgBody()) {
        return;
    }
    Transaction tx = transactionService.getTx(message.getMsgBody());
    if (null == tx) {
        return;
    }
    TransactionMessage txMessage = new TransactionMessage();
    txMessage.setMsgBody(tx);
    Result result = messageBusService.sendToNode(txMessage, fromNode, true);
    if (!result.isSuccess()) {
        Log.error("send error to node : " + fromNode.getId());
    }
}
Also used : TransactionMessage(io.nuls.protocol.message.TransactionMessage) Transaction(io.nuls.kernel.model.Transaction) Result(io.nuls.kernel.model.Result)

Aggregations

Transaction (io.nuls.kernel.model.Transaction)38 NulsDigestData (io.nuls.kernel.model.NulsDigestData)12 ArrayList (java.util.ArrayList)11 Test (org.junit.Test)8 NulsException (io.nuls.kernel.exception.NulsException)7 ValidateResult (io.nuls.kernel.validate.ValidateResult)7 NulsRuntimeException (io.nuls.kernel.exception.NulsRuntimeException)6 IOException (java.io.IOException)5 HashSet (java.util.HashSet)5 Result (io.nuls.kernel.model.Result)4 TransferTransaction (io.nuls.protocol.model.tx.TransferTransaction)4 CreateAgentTransaction (io.nuls.consensus.poc.protocol.tx.CreateAgentTransaction)3 RedPunishTransaction (io.nuls.consensus.poc.protocol.tx.RedPunishTransaction)3 NulsByteBuffer (io.nuls.kernel.utils.NulsByteBuffer)3 UnconfirmedTxPo (io.nuls.account.ledger.storage.po.UnconfirmedTxPo)2 StopAgentTransaction (io.nuls.consensus.poc.protocol.tx.StopAgentTransaction)2 AgentPo (io.nuls.consensus.poc.storage.po.AgentPo)2 Coin (io.nuls.kernel.model.Coin)2 TransactionProcessor (io.nuls.kernel.processor.TransactionProcessor)2 Alias (io.nuls.account.model.Alias)1