AT: Impossible to create an AT with exactly 1 code page or data page
When the AT bytecode is exactly 256 bytes, it is impossible do deploy it.
This happens because the actual algorithm implementation for creationBytes does not allow this situation to happen. If the creation byte position 20 is zero, then it is suposed that codebytes is zero length. But in the case codebyte is 256 length, the position 20 and 21 would need to be set [0x00, 0x01] (to be 256), so being detected wrongly as zero.
The same would occur if 256 pages were allowed, because the integer to be starting on position 20 would be [0x00, 0x00, 0x01].
A possible fix is to correct the creation bytes to be only a short value on that position and also for the data pages, at least for the at version 3.
To test, just try to deploy this bytecode (256 bytes long) 0403000000010300000005000000000000000103000000050000000000000001030000000500000000000000010300000005000000000000000103000000050000000000000001030000000500000000000000010300000005000000000000000103000000050000000000000001030000000500000000000000010300000005000000000000000103000000050000000000000001030000000500000000000000010300000005000000000000000103000000050000000000000001030000000500000000000000010300000005000000000000000103000000050000000000000001030000000500000000000000010300000005000000000000007f7f7f28
This is a valid bytecode.
This situation only happen when the bytes length is 256 and dataPages / codePages is equal 1. So this patch fixes the problem.
--- a/src/brs/at/AtController.java
+++ b/src/brs/at/AtController.java
@@ -160,6 +160,9 @@ public abstract class AtController {
b.getLong();
int codeLen = getLength(codePages, b);
+ if (codeLen == 0 && codePages == 1) {
+ codeLen = 256;
+ }
if (codeLen < minCodePages || codeLen > codePages * 256) {
throw new AtException(AtError.INCORRECT_CODE_LENGTH.getDescri
ption());
}
@@ -167,6 +170,9 @@ public abstract class AtController {
b.get(code, 0, codeLen);
int dataLen = getLength(dataPages, b);
+ if (dataLen == 0 && dataPages == 1 && b.capacity() - b.position()
== 256) {
+ dataLen = 256;
+ }
if (dataLen < 0 || dataLen > dataPages * 256) {
throw new AtException(AtError.INCORRECT_DATA_LENGTH.getDescri
ption());
}
Thanks, we need to also wrap this with a fork block, can be SMART_ATS so we don't have any issues. Can you prepare a PR? If not, I can try to integrate this.
It looks like there is a side effect with this. If the codeLen is purposefully set as 0, then it will be replaced by 256 and produces a lot of problems later. We have a patch here 0a468826b1eae67a6751eb49cca1c7f957b4a7ce to handle the sync problems this generates. Maybe it should be revisited later.