pinax-network / firehose-antelope

Firehose implementation for Antelope
Apache License 2.0
8 stars 1 forks source link

reader crash on EOS block 144532479 #92

Closed matthewdarwin closed 1 year ago

matthewdarwin commented 1 year ago

023-10-08T01:52:05.533Z ERRO (reader-node-stdin) reading from console logs {"error": "unable to marshal to binary form: string field contains invalid UTF-8"}

fschoell commented 1 year ago

I think I found the issue: This is happening on block 144532479 when decoding the database operations of the registry.sx contract. My assumption is that the ABI is not matching the contract, but it's a very unlikely case where it's still able to decode without error (total length and flags are probably matching but actual fields are not?). The result of the decoding is gibberish though, so it produces an invalid utf-8 string which then fails when the block is marshalled into the protobufs.

I've extracted the ABI at the block number and the problematic row data and put it into a test case on eos-go, see here: https://github.com/pinax-network/eos-go/blob/a3a8129ba8a5d86f7dd60e3eab0db37a678561b7/abidecoder_test.go#L293-L438

If you check out the branch and run it locally it will produce this:

# go test -v -run Test_DecodeTableRowGibberish ./...
=== RUN   Test_DecodeTableRowGibberish
decoded table row {"pair_ids":[{"key":"U�*_ղ�","value":26}],"source":{"contract":"...5anu4d52k4","sym":"48,\u001dEjRL\ufffdS"},"targets":[{"key":"U�*_ղ�","value":{"contract":".....p24ehek4","sym":"112,U\ufffd*_ղ\ufffd"}}]}

@YaroShkvorets do you agree with my assumption here and do you think there is a way to catch those errors?

YaroShkvorets commented 1 year ago

Yes, looks like around that time Denis changed that table structure from 2 columns to 3 columns Most likely old row was overwritten with new row or something. So decoder is trying to decode old row with new ABI.

Your fix will make the error go away but there is still a chance that decoder will produce valid string after UTF8 validity check, that could be problematic.

eos-go decoder can do a better job decoding stuff. Like here for example it should make sure precision is <= 18 and symbol_code is valid. In our case they are 48 and \u001dEjRL\ufffdS which is obviously not valid. But even then there is no guarantee.

So eos-go assumes ABI and data is always correct and probably not doing these checks for performance reasons. I've added some checks in this branch to abidecoder.go but not sure if we should merge it as it would probably slow things down a bit.

fschoell commented 1 year ago

Your fix will make the error go away but there is still a chance that decoder will produce valid string after UTF8 validity check, that could be problematic.

I mean it converts it into valid utf-8, but the values are still wrong. I'd rather have it throw an error in which case the data doesn't get deserialised into json which is better than wrong json data.

But there are also cases where it's just impossible to detect that your ABI is invalid, so not sure if we need to handle those.

So eos-go assumes ABI and data is always correct and probably not doing these checks for performance reasons. I've added some checks in this branch to abidecoder.go but not sure if we should merge it as it would probably slow things down a bit.

Would need some testing how this impacts performance.