-
Notifications
You must be signed in to change notification settings - Fork 273
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
Prefix notation for logical compound conditions #3140
Prefix notation for logical compound conditions #3140
Conversation
8d16f25
to
ed9121f
Compare
Since the convo on #3058 stalled, I just want to confirm: Are we OK with proceeding with a format which is not (easily) checkable on-chain? |
One thing for sure is that the infix format (current status quo) is something that needed to be removed/deprecated. Other options can be explored/discussed, but the current conditions format could not remain due to the ambiguity of logical operations and the ongoing technical debt of also supporting infix. Moving from infix notation to prefix notation wasn't too bad of a lift. #3058 was mainly about infix vs prefix, and expanded into a discussion about the language used for conditions. Totally understandable since they are in the same realm, but ultimately the condition language itself is a much broader discussion than intended for that issue, and perhaps we can continue that higher level conversation in a more focused issue since there are still many unknowns to resolve/consider:
Filed #3144 to continue that discussion. |
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.
I really like this prefix syntax for compound conditions. In my opinion, the code is pretty much clean in this way and error-proof. Great work. Just some thoughts in my review.
I do not see any inconvenience for multicall using this format. Actually, the simplicity of this code is better for implementing multicall. |
…ogical conditions.
…ate_condition_lingo`.
…propagated but gets reraised as InvalidConditionLingo.
…erators. Co-authored-by: David Núñez <david@nucypher.com>
3e482b1
to
42cf842
Compare
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.
LGTM! ✌️
|
||
ciphertext = self.encrypt_for_dkg(plaintext=plaintext, | ||
conditions=conditions) | ||
def encrypt_for_dkg_and_produce_decryption_request( |
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.
Needs a better name IMO, but outside the scope of this PR.
import json | ||
from typing import List | ||
|
||
from nucypher_core import ReencryptionRequest, Conditions | ||
|
||
from nucypher.policy.conditions.lingo import ConditionLingo | ||
|
||
|
||
def _serialize_rust_lingos(lingos: List[Conditions]) -> Conditions: | ||
lingo_lists = list() | ||
for lingo in lingos: | ||
if lingo: | ||
lingo = json.loads((str(lingo))) | ||
lingo_lists.append(lingo) | ||
rust_lingos = Conditions(json.dumps(lingo_lists)) | ||
return rust_lingos | ||
|
||
|
||
def _deserialize_rust_lingos(reenc_request: ReencryptionRequest): | ||
"""Shim for nucypher-core lingos""" | ||
json_lingos = json.loads(str(reenc_request.conditions)) | ||
lingo = [ConditionLingo.from_list(lingo) if lingo else None for lingo in json_lingos] | ||
return lingo |
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.
Such a relief to finally realize this removal!
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.
Excellent PR 👏🏻 I'm in favor of merging, although since this is mission-critical code that has gained complexity (rightfully so) and the conditions format is predictable we might be able to develop a fuzzing strategy to ensure logical correctness in all possible cases.
_operator = data["operator"] | ||
except KeyError: | ||
raise InvalidLogicalOperator(f"Invalid operator data: {data}") | ||
class CompoundAccessControlCondition(AccessControlCondition): |
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.
Not specific to this PR:
- Should we put a ceiling on the number of elements in conditions? Something in the order of ~100. We could short-circuit it too: evaluate the first 100, and if there exists another then return
False
. - Seems like a possible DoS vector. WDYT?
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.
That's a very sensible restriction, in fact I'd make the ceiling much lower, perhaps 5-10 elements since each call adds o(n) runtime at minimum, and maps directly onto node operational costs. Even beyond that, we may consider some form of rate limiting. All of which needs to be addressed in another PR IMO.
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.
Nice thought!
We can potentially limit the length of the list of conditions, and raise an InvalidCondition
exception if too long during object creation/schema validation.
I'd rather do that than allow the object to be created then fail during execution because it is too long - could be too confusing to the user. That being said, technically you can work around it by having repeated nested compound conditions each with operands under the limit.
So maybe some kind of overall count needs to be calculated during creation...?
Some good thoughts here. Let's tackle it in another PR.
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.
There's definitely both client and server validation involved there, I think this is often the case with the condition module as a whole.
I agree that's material for another contribution. I'll be interested in scoping this, also for the purpose of implementation in nucypher-ts
.
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.
👍 - filed #3148.
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.
Just to throw is out there, another way to enforce a limitation is by capping the number of bytes.
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.
Just a couple of questions.
LGTM 🎉
Type of PR:
Required reviews:
What this does:
Replaces infix notation with prefix notation for logical combinations of conditions.
Issues fixed/closed:
Fixes #3058
Why it's needed:
This is needed to disambiguate logical groupings as outlined in #3058 .
For example:
Notes for reviewers:
This will have downstream effect on
nucypher-ts
, and how logical operators are used there - nucypher/taco-web#224