Skip to content

Commit

Permalink
Merge pull request #309 from algorandfoundation/fix/op_assign_in_box
Browse files Browse the repository at this point in the history
fix: operator assignment on array values in boxes
  • Loading branch information
joe-p authored Dec 31, 2023
2 parents 910534f + a08ea59 commit 5aba682
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 2 deletions.
6 changes: 6 additions & 0 deletions src/lib/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3077,6 +3077,12 @@ export default class Compiler {
const { type, valueType } = storageProp;
const action = type === 'box' && !this.isDynamicType(valueType) ? 'replace' : 'set';

// Honestly not sure why I needed to add this after b89ddc6c24d6102f9e890a0e76222de7e0ca79b5 (0.67.2)
// But it works...
if (type === 'box' && this.teal[this.currentProgram].at(-1)?.teal.startsWith('replace3')) {
this.teal[this.currentProgram].pop();
}

this.handleStorageAction({
node,
name: storageName!,
Expand Down
10 changes: 8 additions & 2 deletions tests/abi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ async function runMethod(appClient: ApplicationClient, name: string, methodArgs:
let fundAmount = 0;
let callType: 'call' | 'optIn' = 'call';

if (name.includes('Storage') || name.includes('RefAccount')) {
if (name.includes('Storage') || name.includes('RefAccount') || name.includes('InBox')) {
fundAmount = 127_400;
callType = 'optIn';
if (name.includes('Storage') || name.includes('RefAccount')) callType = 'optIn';
}
return commonRunMethod({ appClient, boxes, method: name, methodArgs, fundAmount, callType });
}
Expand Down Expand Up @@ -784,5 +784,11 @@ describe('ABI', function () {

expect(await runMethod(appClient, 'plusEqualsObjValue')).toEqual([3n, 5n]);
});

test('plusEqualsObjValueInBox', async () => {
const { appClient } = await compileAndCreate('plusEqualsObjValueInBox');

expect(await runMethod(appClient, 'plusEqualsObjValueInBox')).toEqual([3n, 5n]);
});
});
});
10 changes: 10 additions & 0 deletions tests/contracts/abi.algo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1252,3 +1252,13 @@ class ABITestPlusEqualsObjValue extends Contract {
return a;
}
}

class ABITestPlusEqualsObjValueInBox extends Contract {
bMap = BoxMap<bytes, { foo: uint64; bar: uint64 }>();

plusEqualsObjValueInBox(): { foo: uint64; bar: uint64 } {
this.bMap('bMap').value = { foo: 3, bar: 4 };
this.bMap('bMap').value.bar += 1;
return this.bMap('bMap').value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#pragma version 9

// This TEAL was generated by TEALScript v0.67.2
// https://github.com/algorandfoundation/TEALScript

// This contract is compliant with and/or implements the following ARCs: [ ARC4 ]

// The following ten lines of TEAL handle initial program flow
// This pattern is used to make it easy for anyone to parse the start of the program and determine if a specific action is allowed
// Here, action refers to the OnComplete in combination with whether the app is being created or called
// Every possible action for this contract is represented in the switch statement
// If the action is not implmented in the contract, its respective branch will be "NOT_IMPLEMENTED" which just contains "err"
txn ApplicationID
int 0
>
int 6
*
txn OnCompletion
+
switch create_NoOp NOT_IMPLEMENTED NOT_IMPLEMENTED NOT_IMPLEMENTED NOT_IMPLEMENTED NOT_IMPLEMENTED call_NoOp

NOT_IMPLEMENTED:
err

abi_route_plusEqualsObjValueInBox:
// The ABI return prefix
byte 0x151f7c75

// execute plusEqualsObjValueInBox()(uint64,uint64)
callsub plusEqualsObjValueInBox
concat
log
int 1
return

// plusEqualsObjValueInBox()(uint64,uint64)
plusEqualsObjValueInBox:
proto 0 1

// tests/contracts/abi.algo.ts:1260
// this.bMap('bMap').value = { foo: 3, bar: 4 }
byte 0x624d6170 // "bMap"
byte 0x00000000000000030000000000000004
box_put

// tests/contracts/abi.algo.ts:1261
// this.bMap('bMap').value.bar += 1
int 8
byte 0x624d6170 // "bMap"
box_get
assert
extract 8 8
btoi
int 1
+
itob
byte 0x624d6170 // "bMap"
cover 2
box_replace

// tests/contracts/abi.algo.ts:1262
// return this.bMap('bMap').value;
byte 0x624d6170 // "bMap"
box_get
assert
retsub

abi_route_createApplication:
int 1
return

create_NoOp:
method "createApplication()void"
txna ApplicationArgs 0
match abi_route_createApplication
err

call_NoOp:
method "plusEqualsObjValueInBox()(uint64,uint64)"
txna ApplicationArgs 0
match abi_route_plusEqualsObjValueInBox
err
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"hints": {
"plusEqualsObjValueInBox()(uint64,uint64)": {
"call_config": {
"no_op": "CALL"
}
},
"createApplication()void": {
"call_config": {
"no_op": "CREATE"
}
}
},
"bare_call_config": {
"no_op": "NEVER",
"opt_in": "NEVER",
"close_out": "NEVER",
"update_application": "NEVER",
"delete_application": "NEVER"
},
"schema": {
"local": {
"declared": {},
"reserved": {}
},
"global": {
"declared": {},
"reserved": {}
}
},
"state": {
"global": {
"num_byte_slices": 0,
"num_uints": 0
},
"local": {
"num_byte_slices": 0,
"num_uints": 0
}
},
"source": {
"approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCi8vIFRoaXMgVEVBTCB3YXMgZ2VuZXJhdGVkIGJ5IFRFQUxTY3JpcHQgdjAuNjcuMgovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsbWVudGVkIGluIHRoZSBjb250cmFjdCwgaXRzIHJlc3BlY3RpdmUgYnJhbmNoIHdpbGwgYmUgIk5PVF9JTVBMRU1FTlRFRCIgd2hpY2gganVzdCBjb250YWlucyAiZXJyIgp0eG4gQXBwbGljYXRpb25JRAppbnQgMAo+CmludCA2CioKdHhuIE9uQ29tcGxldGlvbgorCnN3aXRjaCBjcmVhdGVfTm9PcCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIGNhbGxfTm9PcAoKTk9UX0lNUExFTUVOVEVEOgoJZXJyCgphYmlfcm91dGVfcGx1c0VxdWFsc09ialZhbHVlSW5Cb3g6CgkvLyBUaGUgQUJJIHJldHVybiBwcmVmaXgKCWJ5dGUgMHgxNTFmN2M3NQoKCS8vIGV4ZWN1dGUgcGx1c0VxdWFsc09ialZhbHVlSW5Cb3goKSh1aW50NjQsdWludDY0KQoJY2FsbHN1YiBwbHVzRXF1YWxzT2JqVmFsdWVJbkJveAoJY29uY2F0Cglsb2cKCWludCAxCglyZXR1cm4KCi8vIHBsdXNFcXVhbHNPYmpWYWx1ZUluQm94KCkodWludDY0LHVpbnQ2NCkKcGx1c0VxdWFsc09ialZhbHVlSW5Cb3g6Cglwcm90byAwIDEKCgkvLyB0ZXN0cy9jb250cmFjdHMvYWJpLmFsZ28udHM6MTI2MAoJLy8gdGhpcy5iTWFwKCdiTWFwJykudmFsdWUgPSB7IGZvbzogMywgYmFyOiA0IH0KCWJ5dGUgMHg2MjRkNjE3MCAvLyAiYk1hcCIKCWJ5dGUgMHgwMDAwMDAwMDAwMDAwMDAzMDAwMDAwMDAwMDAwMDAwNAoJYm94X3B1dAoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czoxMjYxCgkvLyB0aGlzLmJNYXAoJ2JNYXAnKS52YWx1ZS5iYXIgKz0gMQoJaW50IDgKCWJ5dGUgMHg2MjRkNjE3MCAvLyAiYk1hcCIKCWJveF9nZXQKCWFzc2VydAoJZXh0cmFjdCA4IDgKCWJ0b2kKCWludCAxCgkrCglpdG9iCglieXRlIDB4NjI0ZDYxNzAgLy8gImJNYXAiCgljb3ZlciAyCglib3hfcmVwbGFjZQoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czoxMjYyCgkvLyByZXR1cm4gdGhpcy5iTWFwKCdiTWFwJykudmFsdWU7CglieXRlIDB4NjI0ZDYxNzAgLy8gImJNYXAiCglib3hfZ2V0Cglhc3NlcnQKCXJldHN1YgoKYWJpX3JvdXRlX2NyZWF0ZUFwcGxpY2F0aW9uOgoJaW50IDEKCXJldHVybgoKY3JlYXRlX05vT3A6CgltZXRob2QgImNyZWF0ZUFwcGxpY2F0aW9uKCl2b2lkIgoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAoJbWF0Y2ggYWJpX3JvdXRlX2NyZWF0ZUFwcGxpY2F0aW9uCgllcnIKCmNhbGxfTm9PcDoKCW1ldGhvZCAicGx1c0VxdWFsc09ialZhbHVlSW5Cb3goKSh1aW50NjQsdWludDY0KSIKCXR4bmEgQXBwbGljYXRpb25BcmdzIDAKCW1hdGNoIGFiaV9yb3V0ZV9wbHVzRXF1YWxzT2JqVmFsdWVJbkJveAoJZXJy",
"clear": "I3ByYWdtYSB2ZXJzaW9uIDk="
},
"contract": {
"name": "ABITestPlusEqualsObjValueInBox",
"desc": "",
"methods": [
{
"name": "plusEqualsObjValueInBox",
"args": [],
"desc": "",
"returns": {
"type": "(uint64,uint64)",
"desc": ""
}
},
{
"name": "createApplication",
"args": [],
"desc": "",
"returns": {
"type": "void",
"desc": ""
}
}
]
}
}
24 changes: 24 additions & 0 deletions tests/contracts/artifacts/ABITestPlusEqualsObjValueInBox.arc4.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "ABITestPlusEqualsObjValueInBox",
"desc": "",
"methods": [
{
"name": "plusEqualsObjValueInBox",
"args": [],
"desc": "",
"returns": {
"type": "(uint64,uint64)",
"desc": ""
}
},
{
"name": "createApplication",
"args": [],
"desc": "",
"returns": {
"type": "void",
"desc": ""
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#pragma version 9

0 comments on commit 5aba682

Please sign in to comment.