Hi EK, can you please confirm if this was due to something the miner sent or is it an issue in only the core server? I checked the miner code and I don't see how it could send more than 32 bytes.
Took me a few days to find out, but the bug was the following:
The core server only allows a hash of max. 32 byte length in the BountyAnnouncement transaction. When something longer than that was tried to be added, the hash was simply set to null:
PiggybackedProofOfBountyAnnouncement(final ByteBuffer buffer, final byte transactionVersion)
throws NxtException.NotValidException {
super(buffer, transactionVersion);
this.workId = buffer.getLong();
final short hashSize = buffer.getShort();
if ((hashSize > 0) && (hashSize <= Constants.MAX_HASH_ANNOUNCEMENT_SIZE_BYTES)) {
this.hashAnnounced = new byte[hashSize];
buffer.get(this.hashAnnounced, 0, hashSize);
} else {
this.hashAnnounced = null;
}
}
When signing such transaction, which came in from via HTTP, everything appearently went fine ... the core server just signed the BountyAnnouncement with empty hash and submitted it. The verification worked fine as well because Attachments have no verification themselves.
The problem happened in the rebroadcast. Imagine someone originally attached 33 bytes (instead of 32) in the hash, then the hash would be nulled - hash has length zero. But the original transaction is still broadcast in its original form causing 33 extra "unexpected bytes" to be over after parsing the TX. This is what the error that you posted earlier stated.
I fixed it and learned ... variable length input sucks a lot. Tried to port many features to fixed length inputs (as you can see from my commits today).
However, 33 bytes must have come from somewhere, i.e., the miner. I suspect an extra byte for a minus sign maybe?