A weird error message in Algorand
This week I stumbled across one of those super-weird artifacts of Algorand: a poorly written exception message drove me crazy looking for solutions, until two days later I had a "Jesus moment" after reading about someone else who had run into a similar situation.
Bug? Or not bug? What is going on?
Most blockchains allow you to "add a note" with a transaction - a simple alphanumeric string. This is useful to mark individual transactions with useful data - and some entrepreneurial types have used this feature to advertise their platforms, wares and other meaningless junk.
In our case, we need to tack the platform's "transactionID" to the payment transaction: a hex 32 bytes long. By definition, hex strings are URL safe and are built as UTF-8 characters. So far so good.
But the payment does not go thru and returns an error message: "At least one signature didn't pass verification"
What the f...?
If an error says that at least one signature does not pass verification ... where do you look for answers?
In the signature that does not pass verification, right? Or in the logic or process that verifies the signature, perhaps?
So the whole Algorand module of the platform is taken down, broken apart and debugged with a very fine comb. Questions and recriminations start popping up:
- Do we have the latest version in GIT?
- Maybe the code has been changed by someone else?
- Are the dev machine and the test machine in sync?
- Where is the key master? What can he/she tell us about this? Who validates signatures? (answer: no-one, signatures are part of the wallet assignation)
- Let's try on a different machine? (this idea came from a devops guy, obvs)
- Let's try on a different indexer (this idea came from someone who does not seem to understand how blockchain works)
- Let's try coding in a different language (this idea came up from someone who does not seem to understand any code)
- Etc. Etc.
Encode your string, right?
After several hours of this slow and painful Kabuki, I hopped on the net and started digging for answers.
The first clue came up when I noticed the response code of 400 to the transaction request.
As most code warriors know, a HTTP_400 means: "hey, you sent something to me in the wrong format / size / shape and I did not like it"
Next stop: the Algorand developer portal.
Here I find that the "transaction note" must be encoded by the sender using Base64 and the field has a maximum length of 32-bytes.
In other words, the problem is that our "transaction note" is already at the maximum size allowed by Algorand (32-bytes) before Base64, and possibly got 20 or 30 percent larger after encoding. Fair enough, the devs are using a data type that's too long.
But the kicker is, the blockchain rejects the transaction -because the "transaction note" is larger than the limit of 32-bytes- and throws an error with a message about the validity of the signature for the transaction. The sender code traps this exception and it happily bubbles up to the UI, giving the user a shock.
Have we been hacked by North Korea?
Nope. We haven't. It's just that the devs at Algorand need a crash course on software design for humans.
"Elegant code does not exist: it either solves a problem or it does not."