diff --git a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java index 986ecd643..e5efe5684 100644 --- a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java +++ b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java @@ -16,6 +16,7 @@ package org.fisco.bcos.sdk.abi; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import org.fisco.bcos.sdk.abi.wrapper.ABICodecJsonWrapper; import org.fisco.bcos.sdk.abi.wrapper.ABICodecObject; @@ -25,6 +26,7 @@ import org.fisco.bcos.sdk.abi.wrapper.ABIObjectFactory; import org.fisco.bcos.sdk.abi.wrapper.ContractABIDefinition; import org.fisco.bcos.sdk.crypto.CryptoSuite; +import org.fisco.bcos.sdk.model.EventLog; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -317,7 +319,7 @@ public List decodeMethodByInterfaceToString( return decodeMethodByIdToString(ABI, methodId, output); } - public List decodeEvent(String ABI, String eventName, String output) + public List decodeEvent(String ABI, String eventName, EventLog log) throws ABICodecException { ContractABIDefinition contractABIDefinition = abiDefinitionFactory.loadABI(ABI); List events = contractABIDefinition.getEvents().get(eventName); @@ -329,10 +331,12 @@ public List decodeEvent(String ABI, String eventName, String output) + contractABIDefinition.getEvents().keySet()); } for (ABIDefinition abiDefinition : events) { - ABIObject outputObject = abiObjectFactory.createInputObject(abiDefinition); + ABIObject inputObject = abiObjectFactory.createEventInputObject(abiDefinition); ABICodecObject abiCodecObject = new ABICodecObject(); try { - return abiCodecObject.decodeJavaObject(outputObject, output); + List params = abiCodecObject.decodeJavaObject(inputObject, log.getData()); + List topics = log.getTopics(); + return mergeEventParamsAndTopics(abiDefinition, params, topics); } catch (Exception e) { logger.error(" exception in decodeEventToObject : {}", e.getMessage()); } @@ -343,15 +347,17 @@ public List decodeEvent(String ABI, String eventName, String output) throw new ABICodecException(errorMsg); } - public List decodeEventByTopic(String ABI, String eventTopic, String output) + public List decodeEventByTopic(String ABI, String eventTopic, EventLog log) throws ABICodecException { ContractABIDefinition contractABIDefinition = abiDefinitionFactory.loadABI(ABI); ABIDefinition abiDefinition = contractABIDefinition.getABIDefinitionByEventTopic(eventTopic); - ABIObject outputObject = abiObjectFactory.createOutputObject(abiDefinition); + ABIObject inputObject = abiObjectFactory.createEventInputObject(abiDefinition); ABICodecObject abiCodecObject = new ABICodecObject(); try { - return abiCodecObject.decodeJavaObject(outputObject, output); + List params = abiCodecObject.decodeJavaObject(inputObject, log.getData()); + List topics = log.getTopics(); + return mergeEventParamsAndTopics(abiDefinition, params, topics); } catch (Exception e) { logger.error(" exception in decodeEventByTopicToObject : {}", e.getMessage()); } @@ -362,14 +368,14 @@ public List decodeEventByTopic(String ABI, String eventTopic, String out throw new ABICodecException(errorMsg); } - public List decodeEventByInterface(String ABI, String eventSignature, String output) + public List decodeEventByInterface(String ABI, String eventSignature, EventLog log) throws ABICodecException { FunctionEncoder functionEncoder = new FunctionEncoder(cryptoSuite); String methodId = functionEncoder.buildMethodId(eventSignature); - return decodeEventByTopic(ABI, methodId, output); + return decodeEventByTopic(ABI, methodId, log); } - public List decodeEventToString(String ABI, String eventName, String output) + public List decodeEventToString(String ABI, String eventName, EventLog log) throws ABICodecException { ContractABIDefinition contractABIDefinition = abiDefinitionFactory.loadABI(ABI); List events = contractABIDefinition.getEvents().get(eventName); @@ -381,10 +387,12 @@ public List decodeEventToString(String ABI, String eventName, String out + contractABIDefinition.getEvents().keySet()); } for (ABIDefinition abiDefinition : events) { - ABIObject outputObject = abiObjectFactory.createOutputObject(abiDefinition); + ABIObject inputObject = abiObjectFactory.createEventInputObject(abiDefinition); ABICodecJsonWrapper abiCodecJsonWrapper = new ABICodecJsonWrapper(); try { - return abiCodecJsonWrapper.decode(outputObject, output); + List params = abiCodecJsonWrapper.decode(inputObject, log.getData()); + List topics = log.getTopics(); + return mergeEventParamsAndTopicsToString(abiDefinition, params, topics); } catch (Exception e) { logger.error(" exception in decodeEventToString : {}", e.getMessage()); } @@ -395,15 +403,17 @@ public List decodeEventToString(String ABI, String eventName, String out throw new ABICodecException(errorMsg); } - public List decodeEventByTopicToString(String ABI, String eventTopic, String output) + public List decodeEventByTopicToString(String ABI, String eventTopic, EventLog log) throws ABICodecException { ContractABIDefinition contractABIDefinition = abiDefinitionFactory.loadABI(ABI); ABIDefinition abiDefinition = contractABIDefinition.getABIDefinitionByEventTopic(eventTopic); - ABIObject outputObject = abiObjectFactory.createOutputObject(abiDefinition); + ABIObject inputObject = abiObjectFactory.createEventInputObject(abiDefinition); ABICodecJsonWrapper abiCodecJsonWrapper = new ABICodecJsonWrapper(); try { - return abiCodecJsonWrapper.decode(outputObject, output); + List params = abiCodecJsonWrapper.decode(inputObject, log.getData()); + List topics = log.getTopics(); + return mergeEventParamsAndTopicsToString(abiDefinition, params, topics); } catch (Exception e) { logger.error(" exception in decodeEventByTopicToString : {}", e.getMessage()); } @@ -415,9 +425,43 @@ public List decodeEventByTopicToString(String ABI, String eventTopic, St } public List decodeEventByInterfaceToString( - String ABI, String eventSignature, String output) throws ABICodecException { + String ABI, String eventSignature, EventLog log) throws ABICodecException { FunctionEncoder functionEncoder = new FunctionEncoder(cryptoSuite); String methodId = functionEncoder.buildMethodId(eventSignature); - return decodeEventByTopicToString(ABI, methodId, output); + return decodeEventByTopicToString(ABI, methodId, log); + } + + private List mergeEventParamsAndTopics( + ABIDefinition abiDefinition, List params, List topics) { + List ret = new ArrayList<>(); + int paramIdx = 0; + int topicIdx = 1; + for (ABIDefinition.NamedType namedType : abiDefinition.getInputs()) { + if (namedType.isIndexed()) { + ret.add(topics.get(topicIdx)); + topicIdx++; + } else { + ret.add(params.get(paramIdx)); + paramIdx++; + } + } + return ret; + } + + private List mergeEventParamsAndTopicsToString( + ABIDefinition abiDefinition, List params, List topics) { + List ret = new ArrayList<>(); + int paramIdx = 0; + int topicIdx = 1; + for (ABIDefinition.NamedType namedType : abiDefinition.getInputs()) { + if (namedType.isIndexed()) { + ret.add(topics.get(topicIdx)); + topicIdx++; + } else { + ret.add(params.get(paramIdx)); + paramIdx++; + } + } + return ret; } } diff --git a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ABIObjectFactory.java b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ABIObjectFactory.java index 4eaa6875b..2e83cb97e 100644 --- a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ABIObjectFactory.java +++ b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ABIObjectFactory.java @@ -38,6 +38,27 @@ private static ABIObject createObject( return null; } + public static ABIObject createEventInputObject(ABIDefinition abiDefinition) { + return creatEventObjectWithOutIndexed(abiDefinition.getInputs()); + } + + public static ABIObject creatEventObjectWithOutIndexed( + List namedTypes) { + try { + ABIObject abiObject = new ABIObject(ABIObject.ObjectType.STRUCT); + + for (ABIDefinition.NamedType namedType : namedTypes) { + if (!namedType.isIndexed()) { + abiObject.getStructFields().add(buildTypeObject(namedType)); + } + } + return abiObject; + } catch (Exception e) { + logger.error("namedTypes: {}, e: ", namedTypes, e); + } + return null; + } + /** * build ABIObject by raw type name * diff --git a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ContractABIDefinition.java b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ContractABIDefinition.java index 0df6431cc..a8b9fc9cb 100644 --- a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ContractABIDefinition.java +++ b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ContractABIDefinition.java @@ -62,7 +62,7 @@ public Map getEventTopicToEvents() { return eventTopicToEvents; } - public void setEvectTopicToEvents(Map eventTopicToEvents) { + public void setEventTopicToEvents(Map eventTopicToEvents) { this.eventTopicToEvents = eventTopicToEvents; } @@ -94,6 +94,10 @@ public void addEvent(String name, ABIDefinition abiDefinition) { List abiDefinitions = events.get(name); abiDefinitions.add(abiDefinition); logger.info(" name: {}, abi: {}", name, abiDefinition); + + // calculate method id and add abiDefinition to eventTopicToEvents + String methodId = abiDefinition.getMethodId(cryptoSuite); + eventTopicToEvents.put(methodId, abiDefinition); } public ABIDefinition getABIDefinitionByMethodId(String methodId) { diff --git a/sdk-abi/src/test/java/org/fisco/bcos/sdk/test/abi/ABIEventTest.java b/sdk-abi/src/test/java/org/fisco/bcos/sdk/test/abi/ABIEventTest.java index c9cd59f28..2d6c2e7f5 100644 --- a/sdk-abi/src/test/java/org/fisco/bcos/sdk/test/abi/ABIEventTest.java +++ b/sdk-abi/src/test/java/org/fisco/bcos/sdk/test/abi/ABIEventTest.java @@ -1,6 +1,8 @@ package org.fisco.bcos.sdk.test.abi; +import java.util.ArrayList; import java.util.List; +import org.fisco.bcos.sdk.model.EventLog; import org.fisco.bcos.sdk.abi.ABICodec; import org.fisco.bcos.sdk.abi.ABICodecException; import org.junit.Assert; @@ -16,7 +18,8 @@ public class ABIEventTest { public void testDecode() { ABICodec abiCodec = new ABICodec(Utils.getCryptoSuite()); try { - List list = abiCodec.decodeEvent(abi, "LogSetValues", encoded); + EventLog log = new EventLog(encoded, new ArrayList<>()); + List list = abiCodec.decodeEvent(abi, "LogSetValues", log); Assert.assertEquals(list.size(), 3); Assert.assertEquals(list.get(0).toString(), "20"); Assert.assertEquals( diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/channel/ChannelMsgHandler.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/channel/ChannelMsgHandler.java index 8b9e24f81..14bc3b843 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/channel/ChannelMsgHandler.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/channel/ChannelMsgHandler.java @@ -237,6 +237,7 @@ public void onResponse(Response response) { ctx, EnumChannelProtocolVersion.VERSION_1, nodeVersion.getResult().getSupportedVersion()); + addPeerHost(ctx); } disconnect = false; } catch (Exception e) { @@ -246,9 +247,6 @@ public void onResponse(Response response) { if (disconnect) { ctx.disconnect(); ctx.close(); - } else { - String host = ChannelVersionNegotiation.getPeerHost(ctx); - addAvailablePeer(host, ctx); } } }; @@ -327,6 +325,8 @@ public void onResponse(Response response) { if (disconnect) { ctx.disconnect(); ctx.close(); + } else { + addPeerHost(ctx); } } }; @@ -334,4 +334,9 @@ public void onResponse(Response response) { ctx.writeAndFlush(message); addSeq2CallBack(seq, callback); } + + private void addPeerHost(ChannelHandlerContext ctx) { + String host = ChannelVersionNegotiation.getPeerHost(ctx); + addAvailablePeer(host, ctx); + } } diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/model/EventLog.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/model/EventLog.java index ffb7e718c..266b9dca6 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/model/EventLog.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/model/EventLog.java @@ -56,6 +56,11 @@ public EventLog( this.topics = topics; } + public EventLog(String data, List topics) { + this.data = data; + this.topics = topics; + } + @JsonIgnore public boolean isRemoved() { return removed; diff --git a/src/integration-test/java/org/fisco/bcos/sdk/eventsub/SubscribeTest.java b/src/integration-test/java/org/fisco/bcos/sdk/eventsub/SubscribeTest.java index a1f2f6b55..f9c4a6825 100644 --- a/src/integration-test/java/org/fisco/bcos/sdk/eventsub/SubscribeTest.java +++ b/src/integration-test/java/org/fisco/bcos/sdk/eventsub/SubscribeTest.java @@ -76,7 +76,7 @@ public void testEventSubModule() { String[] o = {"0x1", "0x2", "0x3"}; List a = Arrays.asList(o); paramsSetValues.add(a); - paramsSetValues.add("set values 字符串"); + paramsSetValues.add("test"); TransactionResponse transactionResponse = manager.sendTransactionAndGetResponse( contractAddress, abi, "setValues", paramsSetValues); @@ -125,11 +125,14 @@ public void onReceiveLog(int status, List logs) { + log.getData()); ABICodec abiCodec = new ABICodec(client.getCryptoSuite()); try { - List list = - abiCodec.decodeEvent(abi, "LogSetValues", log.getData()); + List list = abiCodec.decodeEvent(abi, "LogSetValues", log); logger.debug("decode event log content, " + list); Assert.assertEquals("20", list.get(0).toString()); - Assert.assertEquals("set values 字符串", list.get(2).toString()); + Assert.assertEquals("test", list.get(2).toString()); + List list1 = + abiCodec.decodeEventByInterface( + abi, "LogSetValues(int256,address[],string)", log); + Assert.assertEquals(3, list1.size()); } catch (ABICodecException e) { logger.error("decode event log error, " + e.getMessage()); } diff --git a/src/integration-test/java/org/fisco/bcos/sdk/transaction/decoder/EventDecodeTest.java b/src/integration-test/java/org/fisco/bcos/sdk/transaction/decoder/EventDecodeTest.java index f49d344f6..280efe612 100644 --- a/src/integration-test/java/org/fisco/bcos/sdk/transaction/decoder/EventDecodeTest.java +++ b/src/integration-test/java/org/fisco/bcos/sdk/transaction/decoder/EventDecodeTest.java @@ -21,6 +21,8 @@ import org.fisco.bcos.sdk.abi.ABICodec; import org.fisco.bcos.sdk.client.Client; import org.fisco.bcos.sdk.model.ConstantConfig; +import org.fisco.bcos.sdk.model.EventLog; +import org.fisco.bcos.sdk.model.TransactionReceipt; import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionProcessor; import org.fisco.bcos.sdk.transaction.manager.TransactionProcessorFactory; import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse; @@ -60,11 +62,10 @@ public void testDecode() throws Exception { System.out.println(response.getReturnMessage()); return; } - List list = - abiCodec.decodeEvent( - abi, - "LogInit", - response.getTransactionReceipt().getLogs().get(0).getData()); + + TransactionReceipt.Logs log = response.getTransactionReceipt().getLogs().get(0); + EventLog eventLog = new EventLog(log.getData(), log.getTopics()); + List list = abiCodec.decodeEvent(abi, "LogInit", eventLog); Assert.assertEquals("test2", list.get(1)); Map> map = response.getEventResultMap(); Assert.assertEquals("test2", map.get("LogInit").get(1));