-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Swati/internal function #329
Changes from 16 commits
2430289
2a444f9
4864c58
e28f6d1
beb16ca
0ae4fc3
ad53bd5
5f59d82
3ac2d07
ab334fc
fba991a
c726e13
8d52c8d
939d636
eba1990
7aa2f99
da77414
5b5e461
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -98,8 +98,9 @@ const internalCallVisitor = { | |
state.currentIndex = index; | ||
traverseNodesFast(node, adjustNamesVisitor, state); | ||
} | ||
|
||
}); | ||
|
||
if(state.expNode) state.newStatementList.push(state.expNode); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this now obsolete? |
||
state.newPostStatementList = cloneDeep(childNode.body.postStatements); | ||
state.newPostStatementList.forEach(node => { | ||
if(node.nodeType === 'MembershipWitness'){ | ||
|
@@ -213,6 +214,14 @@ const internalCallVisitor = { | |
file.nodes.forEach(childNode => { | ||
if(childNode.nodeType === 'FunctionDefinition') { | ||
childNode.parameters.modifiedStateVariables = joinWithoutDupes(childNode.parameters.modifiedStateVariables, state.newParametersList); | ||
const modifiedNodes = childNode.parameters.modifiedStateVariables.map(node => node.name); | ||
const decNode = childNode.body.preStatements.filter(node => node.nodeType === 'VariableDeclarationStatement'); | ||
!JSON.stringify(decNode).includes(JSON.stringify(state.decNode)) ? | ||
state.decNode?.forEach((decNode, decIndex) => { | ||
// if the function doesn't modifies the returned variable don't include it | ||
if(state.decNode && !(modifiedNodes.includes(decNode.declarations[0].name))) | ||
childNode.body.preStatements.splice(decIndex+1, 0, decNode); | ||
}): ''; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The name decNode is used twice here in the for loop and also declared on line 218, could we use a different name for one? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. changed the name |
||
if(childNode.decrementedSecretStates) | ||
childNode.decrementedSecretStates = [...new Set([...childNode.decrementedSecretStates, ...newdecrementedSecretStates])]; | ||
childNode.body.preStatements.forEach(node => { | ||
|
@@ -267,7 +276,8 @@ const internalCallVisitor = { | |
let newVarDecs = []; | ||
childNode.body.statements.forEach((node1, index1)=> { | ||
state.varNames = []; | ||
if (!(node1.expression && node1.expression?.nodeType === 'InternalFunctionCall')){ | ||
// check the node except the InternalFunctionCall node and new created public node with id = 0 as we created it | ||
if (!((node1.expression && node1.expression?.nodeType === 'InternalFunctionCall') || (node1.initialValue && node1.initialValue?.nodeType === 'InternalFunctionCall') || node1.id === 0)){ | ||
SwatiEY marked this conversation as resolved.
Show resolved
Hide resolved
|
||
traverseNodesFast(node1, findVarVisitor, state); | ||
} | ||
state.varNames.forEach((varName) => { | ||
|
@@ -306,22 +316,34 @@ const internalCallVisitor = { | |
childNode.body.statements[id-1] = statenode; | ||
node.body.statements.forEach(kidNode =>{ | ||
if(kidNode.nodeType === 'ExpressionStatement'&& kidNode.expression.name === state.internalFncName[index]) { | ||
kidNode.expression = Object.assign(kidNode.expression,statenode.initialValue); | ||
//When Internal function is inside for-loop, it exit under Expression Statement, we replace the function call with expression from the called function | ||
if (kidNode.expression.operator) { | ||
const newExpressionNode = Object.assign(cloneDeep(kidNode.expression), statenode.initialValue); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still dont' get exactly what is happening here? What does kidNode.expression.operator correspond to? Isn't this normally defined? kidNode remains in node.body.statements so doesn't this lead to a duplicate? |
||
node.body.statements.push(newExpressionNode); | ||
} else { | ||
Object.assign(kidNode.expression, statenode.initialValue); | ||
} | ||
} | ||
|
||
}); | ||
childNode.body.statements[id-1].initialValue =undefined; | ||
childNode.body.statements[id-1].initialValue = undefined; | ||
} else{ | ||
node.body.statements.forEach(kidNode =>{ | ||
if(kidNode.nodeType === 'ExpressionStatement'&& kidNode.expression.name === state.internalFncName[index]) { | ||
kidNode.expression = Object.assign(kidNode.expression,statenode.expression); | ||
node.body.statements.forEach(kidNode => { | ||
if(kidNode.nodeType === 'ExpressionStatement' && kidNode.expression.name === state.internalFncName[index]) { | ||
if(kidNode.expression.operator) { | ||
lydiagarms marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// If the internal function modifies the same state variable, we need to copy over the statements in the calling function | ||
const newExpressionNode = Object.assign(cloneDeep(kidNode.expression), statenode.expression); | ||
node.body.statements.push(newExpressionNode); | ||
} | ||
kidNode.expression = Object.assign(kidNode.expression, statenode.expression); | ||
} | ||
}); | ||
} | ||
} | ||
}); | ||
}); | ||
// remove multiple variable declarations | ||
childNode.body.statements.forEach((node1, index1)=> { | ||
childNode.body.statements.forEach((node1, index1) => { | ||
let isDecDeleted = false; | ||
if(node1.nodeType === 'VariableDeclarationStatement'){ | ||
childNode.body.statements.forEach((node2, index2)=> { | ||
|
@@ -342,7 +364,7 @@ const internalCallVisitor = { | |
if(statenode.nodeType === 'VariableDeclarationStatement'){ | ||
childNode.body.statements[id-1] = statenode; | ||
node.body.statements.forEach(kidNode =>{ | ||
if(kidNode.nodeType === 'ExpressionStatement'&& kidNode.expression.name === state.internalFncName[index]) { | ||
if(kidNode.nodeType === 'ExpressionStatement' && kidNode.expression.name === state.internalFncName[index]) { | ||
kidNode.expression = Object.assign(kidNode.expression,statenode.initialValue); | ||
node.body.statements?.splice(node.body.statements.indexOf(kidNode)+1, 0, state.newStatementList[stateid+1]); | ||
} | ||
|
@@ -382,7 +404,7 @@ const internalCallVisitor = { | |
} | ||
}); | ||
}); | ||
node.privateStates = Object.assign(node.privateStates,statenode.privateStates); | ||
node.privateStates = Object.assign(node.privateStates, statenode.privateStates); | ||
} | ||
}); | ||
break; | ||
|
@@ -397,15 +419,15 @@ const internalCallVisitor = { | |
} | ||
}); | ||
}); | ||
node.privateStates = Object.assign(node.privateStates,statenode.privateStates); | ||
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); | ||
node.privateStates = Object.assign(node.privateStates, statenode.privateStates); | ||
} | ||
}); | ||
break; | ||
|
@@ -422,6 +444,7 @@ const internalCallVisitor = { | |
}); | ||
node.privateStates = Object.assign(node.privateStates,generateProofNode.privateStates); | ||
node.parameters = [...new Set([...node.parameters ,...generateProofNode.parameters])]; | ||
state.returnPara ? node.parameters = [...new Set([...node.parameters, ...state.returnPara])]: node.parameters; | ||
break; | ||
} | ||
case 'SendTransaction': { | ||
|
@@ -498,7 +521,7 @@ FunctionCall: { | |
} | ||
} | ||
else | ||
isCircuit = true; | ||
isCircuit = true; | ||
} | ||
} | ||
}); | ||
|
@@ -507,10 +530,51 @@ FunctionCall: { | |
state.circuitImport.push('true'); | ||
else | ||
state.circuitImport.push('false'); | ||
const newNode = buildNode('InternalFunctionCall', { | ||
let newNode; | ||
if(parent.nodeType === 'VariableDeclarationStatement') { | ||
if(!functionReferncedNode.node.returnParameters.parameters[0]._newASTPointer.isSecret) { | ||
const decNode = buildNode('VariableDeclarationStatement') | ||
decNode.declarations.push(functionReferncedNode.node.returnParameters.parameters[0]._newASTPointer); | ||
decNode.interactsWithSecret = true; | ||
decNode.declarations[0].declarationType = 'state'; | ||
decNode.declarations[0].isAccessed = true; | ||
decNode.declarations[0].interactsWithSecret = true; | ||
state.decNode ??= []; | ||
const decNodeNames = state.decNode.map(node => node.declarations[0].name); | ||
decNodeNames.includes(decNode.declarations[0].name) ? state.decNode : state.decNode.push(decNode); | ||
} | ||
const returnPara = functionReferncedNode.node.returnParameters.parameters[0].name; | ||
let includeExpressionNode = false; | ||
// this functions checks if the parent node interact with secret in the calling function or not | ||
callingfnDefIndicators[parent.declarations[0].id].interactsWith.forEach( node => { | ||
if(node.key != 'arguments' && node.interactsWithSecret) | ||
includeExpressionNode = true; | ||
}) | ||
functionReferncedNode.node.body.statements.forEach(exp => { | ||
// If the return para interacts with public only in the internal function but with secret in calling function we need this expression in calling function | ||
if(exp?.expression.leftHandSide?.name === returnPara && !exp.expression.leftHandSide.interactsWithSecret){ | ||
state.initNode = buildNode('BinaryOperation', { | ||
lydiagarms marked this conversation as resolved.
Show resolved
Hide resolved
|
||
leftExpression: exp._newASTPointer.expression.rightHandSide.leftExpression, | ||
operator: exp._newASTPointer.expression.rightHandSide.operator, | ||
rightExpression: exp._newASTPointer.expression.rightHandSide.rightExpression, | ||
}); | ||
} | ||
newNode = buildNode('InternalFunctionCall', { | ||
name: returnPara, | ||
internalFunctionInteractsWithSecret: internalFunctionInteractsWithSecret, | ||
}); | ||
if(includeExpressionNode && state.initNode) { | ||
newNode.expression = state.initNode; | ||
} | ||
|
||
parent._newASTPointer.interactsWithSecret ? state.returnPara = returnPara : ' '; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have the same issue as elsewhere here with state.returnPara being overwritten? |
||
}) | ||
} else { | ||
newNode = buildNode('InternalFunctionCall', { | ||
name: node.expression.name, | ||
internalFunctionInteractsWithSecret: internalFunctionInteractsWithSecret, | ||
}); | ||
} | ||
node._newASTPointer = newNode ; | ||
if (Array.isArray(parent._newASTPointer[path.containerName])) { | ||
parent._newASTPointer[path.containerName].push(newNode); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have to be careful here as well. Say we have indexes (2,5) stored in deleted indexes, and we delete index 2 first then the element from index 5 is now in index 4 so the wrong index gets deleted. We need to go through the indexes in reverse order from highest to lowest.