Skip to content

Commit

Permalink
Merge pull request #289 from EYBlockchain/lydia/require
Browse files Browse the repository at this point in the history
Lydia/require
  • Loading branch information
lydiagarms authored Jul 4, 2024
2 parents 215f823 + 0f6c895 commit 39d3b1b
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 35 deletions.
16 changes: 14 additions & 2 deletions src/codeGenerators/orchestration/nodejs/toOrchestration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export default function codeGenerator(node: any, options: any = {}): any {
if (!node.initialValue.nodeType) return `\nlet ${codeGenerator(node.declarations[0])};`
// local var dec
if (node.initialValue.nodeType === 'Literal' && !node.isInitializationExpression) return `\nlet ${codeGenerator(node.declarations[0])} = generalise(${codeGenerator(node.initialValue)});`;
return `\nlet ${codeGenerator(node.declarations[0])} = ${codeGenerator(node.initialValue)};`;
return `\nlet ${codeGenerator(node.declarations[0])} = generalise(${codeGenerator(node.initialValue)});`;
}
return `\nlet ${codeGenerator(node.initialValue)};`;
}
Expand Down Expand Up @@ -239,7 +239,19 @@ export default function codeGenerator(node: any, options: any = {}): any {
case 'MemberAccess':
if (options?.lhs) return `${node.name}.${node.memberName}`;
return codeGenerator({ nodeType: 'Identifier', name: `${node.name}.${node.memberName}`, subType: node.subType });


case 'RequireStatement':
if (!node.message[0]){
return `if(!(${codeGenerator(node.condition[0])})){
throw new Error(
"Require statement not satisfied."
);}\n`;
}
return `if(!(${codeGenerator(node.condition[0])})){
throw new Error(
"Require statement not satisfied: ${node.message[0].value}"
);}\n`;

case 'Folder':
case 'File':
case 'EditableCommitmentCommonFilesBoilerplate':
Expand Down
4 changes: 3 additions & 1 deletion src/transformers/visitors/toCircuitVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1325,7 +1325,9 @@ let childOfSecret = path.getAncestorOfType('ForStatement')?.containsSecret;
enter(path: NodePath) {
const { node, parent , parentPath } = path;
const { value } = node;

if (parentPath.isRequireStatement() && node.kind === 'string'){
return;
};
if (node.kind !== 'number' && node.kind !== 'bool' && !path.getAncestorOfType('Return'))
throw new Error(
`Only literals of kind "number" are currently supported. Found literal of kind '${node.kind}'. Please open an issue.`,
Expand Down
4 changes: 3 additions & 1 deletion src/transformers/visitors/toContractVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ const findCustomInputsVisitor = (thisPath: NodePath, thisState: any) => {
if(thisState.variableName.includes(indicator.node.name))
thisState.customInputs.push({name: 'newCommitments['+(thisState.variableName.indexOf(indicator.node.name))+']', typeName: {name: 'uint256'}, isReturn: true, isCommitment: true});
}

// for some reason, node.interactsWithSecret has disappeared here but not in toCircuit
// below: we have a public state variable we need as a public input to the circuit
// local variable decs and parameters are dealt with elsewhere
Expand Down Expand Up @@ -849,6 +848,9 @@ DoWhileStatement: {
const subState = { interactsWithSecret: false };
path.traversePathsFast(interactsWithSecretVisitor, subState);
if (subState.interactsWithSecret) {
if (path.isRequireStatement()){
NodePath.getPath(node.arguments[0]).traversePathsFast(findCustomInputsVisitor, state);
}
state.skipSubNodes = true;
return;
}
Expand Down
48 changes: 27 additions & 21 deletions src/transformers/visitors/toOrchestrationVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,6 @@ const visitor = {
if (!newNodes.generateProofNode.parameters.includes(input.name))
newNodes.generateProofNode.parameters.push(input.name);
})

delete state.publicInputs; // reset
}
if (state.constructorStatements && state.constructorStatements[0] && node.kind === 'constructor') newFunctionDefinitionNode.body.statements.unshift(...state.constructorStatements);
Expand Down Expand Up @@ -1442,24 +1441,21 @@ const visitor = {
return;
}
}
if (node.expression.expression?.name !== 'require') {
// We no longer check indicator?.interactsWithSecret because in most cases interactsWithSecret is set to true in addPublicInput anyway.
// The cases where this doesn't happen in AddPublicInput are where we don't want to add the statement to the newAST anyway.
const newNode = buildNode(node.nodeType, {
interactsWithSecret: interactsWithSecret,
//|| indicator?.interactsWithSecret,
oldASTId: node.id,
});

node._newASTPointer = newNode;
if (Array.isArray(parent._newASTPointer) || (!path.isInSubScope() && Array.isArray(parent._newASTPointer[path.containerName]))) {
parent._newASTPointer.push(newNode);
} else if (Array.isArray(parent._newASTPointer[path.containerName])) {
parent._newASTPointer[path.containerName].push(newNode);
} else {
parent._newASTPointer[path.containerName] = newNode;
}
}
// We no longer check indicator?.interactsWithSecret because in most cases interactsWithSecret is set to true in addPublicInput anyway.
// The cases where this doesn't happen in AddPublicInput are where we don't want to add the statement to the newAST anyway.
const newNode = buildNode(node.nodeType, {
interactsWithSecret: interactsWithSecret,
//|| indicator?.interactsWithSecret,
oldASTId: node.id,
});
node._newASTPointer = newNode;
if (Array.isArray(parent._newASTPointer) || (!path.isInSubScope() && Array.isArray(parent._newASTPointer[path.containerName]))) {
parent._newASTPointer.push(newNode);
} else if (Array.isArray(parent._newASTPointer[path.containerName])) {
parent._newASTPointer[path.containerName].push(newNode);
} else {
parent._newASTPointer[path.containerName] = newNode;
}
},

exit(path: NodePath, state: any) {
Expand Down Expand Up @@ -1732,8 +1728,7 @@ const visitor = {
enter(path: NodePath) {
const { node, parent } = path;
const newNode = buildNode(node.nodeType, { value: node.value });

parent._newASTPointer[path.containerName] = newNode;
path.inList ? parent._newASTPointer.push(newNode) : parent._newASTPointer[path.containerName] = newNode;
},
},

Expand Down Expand Up @@ -1788,6 +1783,17 @@ const visitor = {
FunctionCall: {
enter(path: NodePath, state: any) {
const { node, parent, scope } = path;
if (node.expression?.name === 'require') {
const newNode = buildNode('RequireStatement', {
});
parent._newASTPointer[path.containerName] = newNode;
node._newASTPointer = newNode.condition;
if (node.arguments[0]) NodePath.getPath(node.arguments[0]).traverse(visitor, state);
node._newASTPointer = newNode.message;
if (node.arguments[1]) NodePath.getPath(node.arguments[1]).traverse(visitor, state);
state.skipSubNodes = true;
return;
}
if (node.kind !== 'typeConversion') {
state.skipSubNodes = true;
return;
Expand Down
8 changes: 8 additions & 0 deletions src/types/orchestration-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,14 @@ export default function buildNode(nodeType: string, fields: any = {}): any {
name,
};
}
case 'RequireStatement': {
const {} = fields;
return {
nodeType,
condition: [],
message: [],
};
}
case 'InitialisePreimage':
case 'InitialiseKeys':
case 'ReadPreimage':
Expand Down
4 changes: 2 additions & 2 deletions test/contracts/Assign-secret-admin.zol
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ contract MyContract {
}

function setAdmin(secret address newAdmin) public {
require(msg.sender == admin);
require(msg.sender == admin, "message sender not admin");
admin = newAdmin;
}


function assign(secret uint256 param1) public {
require(msg.sender == admin);
require(msg.sender == admin, "message sender not admin");
a = param1;
}
}
16 changes: 8 additions & 8 deletions test/contracts/SimpleStruct4.zol
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,23 @@ contract Receipt {
}

function addPO(secret PO memory newpo) public {
require(newpo.owner == msg.sender);
require(POs[newpo.id].id == 0); // inv shouldnt exist
require(newpo.owner == msg.sender, "owner of new PO is not the message sender");
require(POs[newpo.id].id == 0, "PO should not exist"); // inv shouldnt exist
POs[newpo.id] = newpo;
}

function addInvoice(secret Invoice memory inv) public {
require(invoices[inv.id].id == 0); // inv shouldnt exist
require(invoices[inv.id].id == 0, "invoice does not exist"); // inv shouldnt exist
invoices[inv.id] = inv;
require(POs[inv.id].count != 0);
require(inv.amount == POs[inv.id].count * POs[inv.id].ppunit);
require(POs[inv.id].count != 0, "PO count equals 0");
require(inv.amount == POs[inv.id].count * POs[inv.id].ppunit, "amount incorrect");
}

function pay(secret uint256 id, secret uint256 amount) public {
// imagine a real payment here
require(invoices[id].amount == amount);
require(invoices[id].amount == amount, "amount incorrect");
invoices[id].amount = 0;
require(POs[id].count != 0);
require(POs[id].owner == msg.sender);
require(POs[id].count != 0, "PO count equals 0");
require(POs[id].owner == msg.sender, "owner of PO is not the message sender");
}
}
55 changes: 55 additions & 0 deletions test/contracts/require.zol
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-License-Identifier: CC0

pragma solidity ^0.8.0;

contract Assign {


struct myStruct {
uint256 prop1;
uint256 prop2;
}

secret myStruct public w;
secret uint256 public a;


uint256 public index;


function add(secret uint256 value) public {
require(a + value > 10, "a + value too low");
index++;
require(a + index > 10, "a + index too low");
known a += value;
}

function add2(secret uint256 value) public {
require(a + index > 10, "original a + index too low");
index++;
a += index;
require(a + index > 10, "new a + index too low");
known a += index + value;
}

function add1(secret uint256 value) public {
require(index < 5) ;
index++;
known a += index + value;
}



function remove(secret uint256 value) public {
require(a > 5, "original value of a is too low");
a -= value;
require(a > index, "new value of a is too low");
}

function remove1(secret uint256 value) public {
require(index < 10, "index is too high");
a -= value;
}


}
47 changes: 47 additions & 0 deletions test/contracts/require2.zol
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: CC0

pragma solidity ^0.8.0;

contract Assign {


struct myStruct {
uint256 prop1;
uint256 prop2;
}

secret myStruct public w;
secret uint256 public a;


uint256 public index;


function add(secret uint256 value, uint256 value1) public {
require(value < 10, "value too high");
index++;
value1++;
a += index;
require(value + index + value1 < 20, "value + index + value1 too high");
known a += index + value;
}

function add1(secret uint256 value) public {
require(value < 10, "value too high");
index++;
secret uint256 c = value;
require(c > 5, "c too low");
c += value;
uint256 d = 5;
require(c -d > index, "c -d too low");
a += c +d;
}

function remove(secret uint256 value) public {
a -= value;
}




}

0 comments on commit 39d3b1b

Please sign in to comment.