Skip to content

Commit

Permalink
fix: bugs relating to internal function calls that use the same secre…
Browse files Browse the repository at this point in the history
…t state variable in orchestration and circuits
  • Loading branch information
lydiagarms committed May 17, 2024
1 parent 53d8faa commit e430c46
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 10 deletions.
2 changes: 0 additions & 2 deletions src/transformers/visitors/checks/unsupportedVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,6 @@ export default {
}
});
});
console.log(internalFunctionStateVarList);
console.log(secretStateVarList);
},
},
};
63 changes: 59 additions & 4 deletions src/transformers/visitors/circuitInternalFunctionCallVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,62 @@ import NodePath from '../../traverse/NodePath.js';
import { FunctionDefinitionIndicator } from '../../traverse/Indicator.js';
import buildNode from '../../types/orchestration-types.js'



// We need to ensure that parameters appear in the same order as in the .mjs file if the same state variables are used in multiple function calls.
// All parameters relating to the same state variable should be grouped together.
const reorderParameters = (parameterList: any) => {
parameterList.forEach((param, index) => {
parameterList.forEach((newParam, newIndex) => {
if (param.name === newParam.name && param.bpType === 'nullification' && newParam.bpType === 'nullification') {
if (newIndex > index && param.isAccessed && !param.isNullified && (newParam.isNullified || !newParam.isAccessed) ){
parameterList[index] = newParam;
}
}
if (param.name === newParam.name && param.bpType === 'oldCommitmentExistence' && newParam.bpType === 'oldCommitmentExistence') {
if (newIndex > index && (!param.isWhole || !param.initialisationRequired) && (newParam.isWhole && newParam.initialisationRequired) ){
parameterList[index] = newParam;
}
}
});
});
let newBPName: string;
let currentIndex: number;
let newCommitment = {};
parameterList.forEach((param, index) => {
if (param.name != newBPName && param.bpType){
newBPName = param.name;
currentIndex = index;
newCommitment[newBPName] = newCommitment[newBPName] ? newCommitment[newBPName] : [];
newCommitment[newBPName].push({"firstIndex": currentIndex, "isNewCommitment": false });
}
if (param.bpType === 'newCommitment'){
newCommitment[newBPName][newCommitment[newBPName].length -1].isNewCommitment = true;
newCommitment[newBPName][newCommitment[newBPName].length -1].newCommitmentIndex = index;
}
if (param.bpType === 'mapping'){
newCommitment[newBPName][newCommitment[newBPName].length -1].mappingIndex = index;
}
if (param.bpType === 'oldCommitmentExistence'){
newCommitment[newBPName][newCommitment[newBPName].length -1].oldCommitmentIndex = index;
}
});
let elementsToAdd = [];
Object.keys(newCommitment).forEach((varName) => {
if (newCommitment[varName][0].isNewCommitment === false && newCommitment[varName].length > 1){
let isSwapped = false;
newCommitment[varName].forEach((element) => {
if (element.isNewCommitment === true && !isSwapped){
let newIndex = newCommitment[varName][0].oldCommitmentIndex +1 || newCommitment[varName][0].mappingIndex+1 || newCommitment[varName][0].firstIndex +1;
let oldIndex = element.newCommitmentIndex;
elementsToAdd.push({"element": parameterList[oldIndex], "NewIndex": newIndex});
}
});
}
});
elementsToAdd.sort((a, b) => b.NewIndex - a.NewIndex );
elementsToAdd.forEach((element) => {
parameterList.splice(element.NewIndex, 0, element.element);
});
}

// let interactsWithSecret = false; // Added globaly as two objects are accesing it

Expand Down Expand Up @@ -121,8 +175,9 @@ const internalCallVisitor = {
})
file.nodes.forEach(childNode => {
if(childNode.nodeType === 'FunctionDefinition'){
childNode.parameters.parameters = [...new Set([...childNode.parameters.parameters, ...state.newParameterList])]
childNode.returnParameters.parameters = [...new Set([...childNode.returnParameters.parameters, ...state.newReturnParameterList])]
childNode.parameters.parameters = [...new Set([...childNode.parameters.parameters, ...state.newParameterList])];
reorderParameters(childNode.parameters.parameters);
childNode.returnParameters.parameters = [...new Set([...childNode.returnParameters.parameters, ...state.newReturnParameterList])];
if(childNode.nodeType === 'FunctionDefinition' && state.callingFncName[index].parent === 'FunctionDefinition'){
childNode.body.statements.forEach(node => {
if(node.nodeType === 'ExpressionStatement') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,13 @@ const internalCallVisitor = {
case 'InitialisePreimage' : {
state.newPreStatementList.forEach(statenode => {
if(statenode.nodeType === 'InitialisePreimage'){
Object.keys(node.privateStates).forEach(key => {
Object.keys(statenode.privateStates).forEach(newKey => {
if (key === newKey){
statenode.privateStates[newKey].accessedOnly = statenode.privateStates[newKey].accessedOnly && node.privateStates[key].accessedOnly;
}
});
});
node.privateStates = Object.assign(node.privateStates,statenode.privateStates)
}
});
Expand All @@ -219,6 +226,14 @@ const internalCallVisitor = {
case 'ReadPreimage': {
state.newPreStatementList.forEach(statenode => {
if(statenode.nodeType === 'ReadPreimage'){
Object.keys(node.privateStates).forEach(key => {
Object.keys(statenode.privateStates).forEach(newKey => {
if (key === newKey){
statenode.privateStates[newKey].accessedOnly = statenode.privateStates[newKey].accessedOnly && node.privateStates[key].accessedOnly;
statenode.privateStates[newKey].nullifierRequired = statenode.privateStates[newKey].nullifierRequired || node.privateStates[key].nullifierRequired;
}
});
});
node.privateStates = Object.assign(node.privateStates,statenode.privateStates)
}
});
Expand All @@ -227,6 +242,14 @@ const internalCallVisitor = {
case 'MembershipWitness': {
state.newPreStatementList.forEach(statenode => {
if(statenode.nodeType === 'MembershipWitness'){
Object.keys(node.privateStates).forEach(key => {
Object.keys(statenode.privateStates).forEach(newKey => {
if (key === newKey){
statenode.privateStates[newKey].accessedOnly = statenode.privateStates[newKey].accessedOnly && node.privateStates[key].accessedOnly;
statenode.privateStates[newKey].nullifierRequired = statenode.privateStates[newKey].nullifierRequired || node.privateStates[key].nullifierRequired;
}
});
});
node.privateStates = Object.assign(node.privateStates,statenode.privateStates)
}
});
Expand Down Expand Up @@ -284,25 +307,49 @@ const internalCallVisitor = {
case 'CalculateNullifier' : {
state.newPostStatementList.forEach(statenode => {
if(statenode.nodeType === 'CalculateNullifier'){
node.privateStates = Object.assign(node.privateStates,statenode.privateStates)
Object.keys(node.privateStates).forEach(key => {
Object.keys(statenode.privateStates).forEach(newKey => {
if (key === newKey){
statenode.privateStates[newKey].accessedOnly = statenode.privateStates[newKey].accessedOnly && node.privateStates[key].accessedOnly;
}
});
});
node.privateStates = Object.assign(node.privateStates,statenode.privateStates);
}
});
break;
}
case 'CalculateCommitment': {
state.newPostStatementList.forEach(statenode => {
if(statenode.nodeType === 'CalculateCommitment'){
node.privateStates = Object.assign(node.privateStates,statenode.privateStates)
if(statenode.nodeType === 'CalculateCommitment'){
node.privateStates = Object.assign(node.privateStates,statenode.privateStates);
}
});
break;
}
case 'GenerateProof': {
node.privateStates = Object.assign(node.privateStates,generateProofNode.privateStates)
Object.keys(node.privateStates).forEach(key => {
Object.keys(generateProofNode.privateStates).forEach(newKey => {
if (key === newKey){
generateProofNode.privateStates[newKey].accessedOnly = generateProofNode.privateStates[newKey].accessedOnly && node.privateStates[key].accessedOnly;
generateProofNode.privateStates[newKey].nullifierRequired = generateProofNode.privateStates[newKey].nullifierRequired || node.privateStates[key].nullifierRequired;
generateProofNode.privateStates[newKey].initialisationRequired = generateProofNode.privateStates[newKey].initialisationRequired || node.privateStates[key].initialisationRequired;
}
});
});
node.privateStates = Object.assign(node.privateStates,generateProofNode.privateStates);
node.parameters = [...new Set([...node.parameters ,...generateProofNode.parameters])];
break;
}
case 'SendTransaction': {
Object.keys(node.privateStates).forEach(key => {
Object.keys(sendTransactionNode.privateStates).forEach(newKey => {
if (key === newKey){
sendTransactionNode.privateStates[newKey].accessedOnly = sendTransactionNode.privateStates[newKey].accessedOnly && node.privateStates[key].accessedOnly;
sendTransactionNode.privateStates[newKey].nullifierRequired = sendTransactionNode.privateStates[newKey].nullifierRequired || node.privateStates[key].nullifierRequired;
}
});
});
node.privateStates = Object.assign(node.privateStates,sendTransactionNode.privateStates)
break;
}
Expand Down

0 comments on commit e430c46

Please sign in to comment.