Skip to content

Commit 1955959

Browse files
committed
Do not perform final-verify check inside loops
1 parent 8517d7f commit 1955959

4 files changed

Lines changed: 17 additions & 3 deletions

File tree

packages/cashc/src/generation/GenerateTargetTraversal.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ export default class GenerateTargetTraversalWithLocation extends AstTraversal {
198198

199199
removeFinalVerifyFromFunction(functionBodyNode: Node): void {
200200
// After EnsureFinalRequireTraversal, we know that the final opcodes are either
201-
// "OP_VERIFY", "OP_CHECK{LOCKTIME|SEQUENCE}VERIFY OP_DROP" or "OP_ENDIF"
201+
// "OP_VERIFY", "OP_CHECK{LOCKTIME|SEQUENCE}VERIFY OP_DROP", "OP_ENDIF" or "OP_UNTIL"
202202

203203
const finalOp = this.output.pop() as Op;
204204
const { location, positionHint } = this.locationData.pop()!;
@@ -220,7 +220,7 @@ export default class GenerateTargetTraversalWithLocation extends AstTraversal {
220220
this.emit(finalOp, { location, positionHint: PositionHint.END });
221221

222222
// At this point there is no verification value left on the stack:
223-
// - scoped stack is cleared inside branch ended by OP_ENDIF
223+
// - scoped stack is cleared inside block ended by OP_ENDIF or OP_UNTIL
224224
// - OP_CHECK{LOCKTIME|SEQUENCE}VERIFY OP_DROP does not leave a verification value
225225
// - OP_VERIFY does not leave a verification value
226226
// so we add OP_1 to the script (indicating success)

packages/cashc/src/semantic/EnsureFinalRequireTraversal.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ function ensureFinalStatementIsRequire(statements: StatementNode[] = []): void {
5151
return;
5252
}
5353

54+
// TODO: Revisit this later, for now we allow do-while loops to not have a require() at the end
5455
if (finalStatement instanceof DoWhileNode) {
55-
ensureFinalStatementIsRequire(finalStatement.block.statements);
56+
// ensureFinalStatementIsRequire(finalStatement.block.statements);
5657
return;
5758
}
5859

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
pragma cashscript ^0.12.0;
2+
3+
contract Loopy() {
4+
function doLoop() {
5+
int inputIndex = 0;
6+
7+
// Loop over all inputs (variable length), and make sure that none of them contain tokens
8+
do {
9+
require(tx.inputs[inputIndex].tokenCategory == 0x);
10+
inputIndex = inputIndex + 1;
11+
} while (inputIndex < tx.inputs.length);
12+
}
13+
}

packages/cashc/test/compiler/FinalRequireStatementError/do_while_no_require.cash renamed to packages/cashc/test/valid-contract-files/do_while_no_require.cash

File renamed without changes.

0 commit comments

Comments
 (0)