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();
}
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);
}
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);
}
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);
}
}
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());
}
}
Aggregations