Search code examples
hyperledger-sawtooth

Protocol message had invalid UTF-8


Has anyone tried the sawtooth-java-sdk v1.0.3 to create events on the Hyperledger Sawtooth?

I am getting the following exception

com.google.protobuf.InvalidProtocolBufferException: Protocol message had invalid UTF-8.
    at com.google.protobuf.InvalidProtocolBufferException.invalidUtf8(InvalidProtocolBufferException.java:148) ~[protobuf-java-3.6.1.jar:na]
    at com.google.protobuf.CodedInputStream$ArrayDecoder.readStringRequireUtf8(CodedInputStream.java:841) ~[protobuf-java-3.6.1.jar:na]
    at sawtooth.sdk.protobuf.Event.<init>(Event.java:49) ~[sawtooth-sdk-protos-v0.1.3.jar:na]
    at sawtooth.sdk.protobuf.Event$1.parsePartialFrom(Event.java:1677) ~[sawtooth-sdk-protos-v0.1.3.jar:na]
    at sawtooth.sdk.protobuf.Event$1.parsePartialFrom(Event.java:1671) ~[sawtooth-sdk-protos-v0.1.3.jar:na]
    at com.google.protobuf.AbstractParser.parsePartialFrom(AbstractParser.java:105) ~[protobuf-java-3.6.1.jar:na]
    at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:125) ~[protobuf-java-3.6.1.jar:na]
    at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:130) ~[protobuf-java-3.6.1.jar:na]
    at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:49) ~[protobuf-java-3.6.1.jar:na]
    at sawtooth.sdk.protobuf.Event.parseFrom(Event.java:994) ~[sawtooth-sdk-protos-v0.1.3.jar:na]
    at my.events.EventListener.run(EventListener.java:257) ~[classes/:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
    at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

This is how I am creating the event in the TransactionHandler#apply()

ByteString eventdata = ByteString.copyFrom("This is a test....".getBytes("UTF-8"));
Map<String, String> attributesMap = new HashMap<String, String>();
attributesMap.put("address", address);
attributesMap.put("namespace", address.substring(0,6));
Collection<Map.Entry<String, String>> attributes = attributesMap.entrySet();
state.addEvent("rootevent/myevent", attributes, eventdata);

Here's my Event Listener code:

byte[] resp = socket.recv(0);
message = Message.parseFrom(resp);
sawToothEvent = Event.parseFrom(message.getContent());

Event.parseFrom throws the exception.


Solution

  • The events come in within an EventList, as opposed to a single bare Event. So it should be more like

    byte[] resp = socket.recv(0);
    message = Message.parseFrom(resp);
    evtList = EventList.parseFrom(message.getContent());
    for (Event evt : evtList.getEventsList()) {
      ...
    }