Skip to content

Commit

Permalink
Merge pull request #238 from EYBlockchain/lydia/incrementation_error
Browse files Browse the repository at this point in the history
Lydia/incrementation error
  • Loading branch information
SwatiEY authored Apr 25, 2024
2 parents 2d15e7a + 9a4a89d commit ddfb158
Show file tree
Hide file tree
Showing 16 changed files with 629 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ class BoilerplateGenerator {
if (!mappingKeyIndicator.keyPath.isMsg() &&
(mappingKeyIndicator.keyPath.node.nodeType === 'Literal'|| mappingKeyIndicator.keyPath.isLocalStackVariable() || !mappingKeyIndicator.keyPath.isSecret))
this.mappingKeyTypeName = 'local';

this.mappingName = this.indicators.name;
this.name = `${this.mappingName}_${mappingKeyName}`.replaceAll('.', 'dot').replace('[', '_').replace(']', '');

Expand Down
12 changes: 11 additions & 1 deletion src/boilerplate/orchestration/javascript/raw/toOrchestration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,18 @@ export const generateProofBoilerplate = (node: any) => {
const msgValueParamAndMappingKey = stateNode.isMapping && (node.parameters.includes('msgValue') || output.join().includes('_msg_stateVarId_key.integer')) && stateNode.stateVarId[1] === 'msg';

const constantMappingKey = stateNode.isMapping && (+stateNode.stateVarId[1] || stateNode.stateVarId[1] === '0');

// Check if the mapping is already included in the parameters
let name: string;
let state: any;
let isIncluded = false;
for ([name, state] of Object.entries(node.privateStates)) {
if (stateNode.stateVarId[0] === state.stateVarId[0] && stateName != name && node.parameters.includes(state.stateVarId[1]) ) {
isIncluded = true;
}
}
const stateVarIdLines =
stateNode.isMapping && !node.parameters.includes(stateNode.stateVarId[1]) && !msgSenderParamAndMappingKey && !msgValueParamAndMappingKey && !constantMappingKey
stateNode.isMapping && !(node.parameters.includes(stateNode.stateVarId[1])) && !(node.parameters.includes(stateNode.stateVarId[2])) && !isIncluded && !msgSenderParamAndMappingKey && !msgValueParamAndMappingKey && !constantMappingKey
? [`\n\t\t\t\t\t\t\t\t${stateName}_stateVarId_key.integer,`]
: [];
// we add any extra params the circuit needs
Expand Down
4 changes: 2 additions & 2 deletions src/codeGenerators/circuit/zokrates/toCircuit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ function codeGenerator(node: any) {

case 'ParameterList': {
const paramList = CircuitBP.uniqueify(node.parameters.flatMap(codeGenerator));

// we also need to identify and remove duplicate params prefixed with conflicting 'public'/'private' keywords (prioritising 'public')
const slicedParamList = paramList.map(p =>
p.replace('public ', '').replace('private ', ''),
Expand Down Expand Up @@ -170,7 +169,8 @@ function codeGenerator(node: any) {

case 'Block': {
const preStatements = CircuitBP.uniqueify(node.preStatements.flatMap(codeGenerator));
const statements = CircuitBP.uniqueify(node.statements.flatMap(codeGenerator));
// TO DO: We don't remove duplicate statements below because of duplicate statements in the contract. This could cause issues.
const statements = node.statements.flatMap(codeGenerator);
const postStatements = CircuitBP.uniqueify(node.postStatements.flatMap(codeGenerator));
return [...preStatements, ...statements, ...postStatements].join('\n\n');
}
Expand Down
3 changes: 2 additions & 1 deletion src/codeGenerators/contract/solidity/toContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ function codeGenerator(node: any) {
const preStatements: string = node.preStatements.flatMap(codeGenerator);
const statements: string = node.statements.flatMap(codeGenerator);
const postStatements: string = node.postStatements.flatMap(codeGenerator);
return [...preStatements, ...statements, ...postStatements].join('\n');
//We have changed the order here so that statements is after poststatements because we need the statements to appear after proof generation. This could cause issues.
return [...preStatements, ...postStatements, ...statements].join('\n');
}
case 'ExpressionStatement':{
return codeGenerator(node.expression);
Expand Down
40 changes: 28 additions & 12 deletions src/codeGenerators/orchestration/nodejs/toOrchestration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ const getAccessedValue = (name: string) => {
*/
const getPublicValue = (node: any) => {
if (node.nodeType !== 'IndexAccess')
return `\nlet ${node.name} = generalise(await instance.methods.${codeGenerator(node)}().call());`;
// In the _init variable we save the initial value of the variable for use later.
return `\nlet ${node.name} = generalise(await instance.methods.${codeGenerator(node)}().call());\n let ${node.name}_init = ${node.name};`;
return `\nconst ${node.name} = generalise(await instance.methods.${codeGenerator(node.baseExpression, { lhs: true} )}(${codeGenerator(node.indexExpression, { contractCall: true })}).call());`;
};

Expand Down Expand Up @@ -83,7 +84,7 @@ export default function codeGenerator(node: any, options: any = {}): any {
}
if (node.declarations[0].isStruct) return `\n let ${codeGenerator(node.declarations[0])} = {}; \n${codeGenerator(node.initialValue)};`;
return `\nlet ${codeGenerator(node.initialValue)};`;
} else if (node.declarations[0].isAccessed && !node.declarations[0].isSecret) {
} else if (node.declarations[0].isAccessed && !node.declarations[0].isSecret) {
return `${getPublicValue(node.declarations[0])}`
} else if (node.declarations[0].isAccessed) {
return `${getAccessedValue(node.declarations[0].name)}`;
Expand Down Expand Up @@ -126,16 +127,31 @@ export default function codeGenerator(node: any, options: any = {}): any {
return " ";

case 'Assignment':
if (['+=', '-=', '*='].includes(node.operator)) {
return `${codeGenerator(node.leftHandSide, {
lhs: true,
})} = ${codeGenerator(node.leftHandSide)} ${node.operator.charAt(
0,
)} ${codeGenerator(node.rightHandSide)}`;
// To ensure the left hand side is always a general number, we generalise it here (excluding the initialisation in a for loop).
if (!node.isInitializationAssignment && node.rightHandSide.subType !== 'generalNumber'){
if (['+=', '-=', '*='].includes(node.operator)) {
return `${codeGenerator(node.leftHandSide, {
lhs: true,
})} = generalise(${codeGenerator(node.leftHandSide)} ${node.operator.charAt(
0,
)} ${codeGenerator(node.rightHandSide)})`;
}
return `${codeGenerator(node.leftHandSide, { lhs: true })} ${
node.operator
} generalise(${codeGenerator(node.rightHandSide)})`;
} else {
if (['+=', '-=', '*='].includes(node.operator)) {
return `${codeGenerator(node.leftHandSide, {
lhs: true,
})} = ${codeGenerator(node.leftHandSide)} ${node.operator.charAt(
0,
)} ${codeGenerator(node.rightHandSide)}`;
}
return `${codeGenerator(node.leftHandSide, { lhs: true })} ${
node.operator
} ${codeGenerator(node.rightHandSide)}`;
}
return `${codeGenerator(node.leftHandSide, { lhs: true })} ${
node.operator
} ${codeGenerator(node.rightHandSide)}`;


case 'BinaryOperation':
return `${codeGenerator(node.leftExpression, { lhs: options.condition })} ${
Expand Down Expand Up @@ -192,7 +208,7 @@ export default function codeGenerator(node: any, options: any = {}): any {

case 'UnaryOperation':
// ++ or -- on a parseInt() does not work
return `generalise(${node.subExpression.name}.integer${node.operator})`;
return `parseInt(${node.subExpression.name}.integer,10)${node.operator[0]}1`;

case 'Literal':
return node.value;
Expand Down
9 changes: 4 additions & 5 deletions src/transformers/visitors/checks/incrementedVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ export default {
const { operator, leftHandSide, rightHandSide } = node;
const lhsSecret = !!scope.getReferencedBinding(leftHandSide)?.isSecret;


if (['bool', 'address'].includes(leftHandSide.typeDescriptions.typeString)) {
markParentIncrementation(path, state, false, false, leftHandSide);
const lhsBinding = scope.getReferencedBinding(leftHandSide)
Expand Down Expand Up @@ -272,27 +273,25 @@ export default {
}

// a *= something, a /= something
// OR lhs non-secret - we don't care about those
if (
operator === '%=' ||
operator === '/=' ||
operator === '*=' ||
!lhsSecret
operator === '*='
) {
markParentIncrementation(path, state, false, false, leftHandSide);
return;
}

// after +=, -=, %=, *=, /=, we can only deal with =
if (operator !== '=' && operator !== '+=' && operator !== '-=')
if ((operator !== '=' && operator !== '+=' && operator !== '-=') && lhsSecret)
throw new TODOError(
`Operator '${operator}' not yet supported. Please open an issue.`,
node,
);

// then, it depends what's on the RHS of the assignment, so we continue
// we save the LHS node to help us later
state.incrementedIdentifier = leftHandSide.baseExpression || leftHandSide;
if (lhsSecret) state.incrementedIdentifier = leftHandSide.baseExpression || leftHandSide;
},
},

Expand Down
Loading

0 comments on commit ddfb158

Please sign in to comment.