-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Introduce deployment variable limit and cost #2431
Conversation
5de1115
to
d2f8d1e
Compare
You'll need to reflect |
…tant calculations
…g over those limits Lower MAX_DEPLOYMENT_VARIABLES Initialize circuit gadget constants before synthesis Update test expectation
d2f8d1e
to
1db96dd
Compare
@@ -118,7 +118,9 @@ pub trait Network: | |||
/// The cost in microcredits per constraint for the deployment transaction. | |||
const SYNTHESIS_FEE_MULTIPLIER: u64 = 25; // 25 microcredits per constraint | |||
/// The maximum number of constraints in a deployment. | |||
const MAX_DEPLOYMENT_LIMIT: u64 = 1 << 20; // 1,048,576 constraints | |||
const MAX_DEPLOYMENT_CONSTRAINTS: u64 = 1 << 20; // 1,048,576 constraints |
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.
if the limit is 1 << 20
, is it reasonable to assume that we would never expect 1 << 64
to be supported? u32
might be a better pick in that case, and IIRC that could have a performance impact on some of the R1CS operations (if the Variable
was also capped at 1 << 32
)
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.
Constraints won't exceed u32 anytime soon, especially as our SRS only supports 1 << 28
. Perhaps constant variables might end up being more. The circuit
crate stores most data as u32, and its only a small amount of counters anyway, so at this point its not worth the rewrite I think.
@@ -49,6 +49,8 @@ pub trait DeploymentStorage<N: Network>: Clone + Send + Sync { | |||
type VerifyingKeyMap: for<'a> Map<'a, (ProgramID<N>, Identifier<N>, u16), VerifyingKey<N>>; | |||
/// The mapping of `(program ID, function name, edition)` to `certificate`. | |||
type CertificateMap: for<'a> Map<'a, (ProgramID<N>, Identifier<N>, u16), Certificate<N>>; | |||
/// The mapping of `(program ID, function name, edition)` to `variable count`. | |||
type VariableCountMap: for<'a> Map<'a, (ProgramID<N>, Identifier<N>, u16), u64>; |
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.
this is not strictly related to this PR, but I wonder if, in case of several maps containing composite/large keys, it would make sense to have composite values too (e.g. a single map of (ProgramID<N>, Identifier<N>, u16)
to (VerifyingKey<N>, Certificate<N>, u64)
), reducing the number of queries and storage space dedicated to keys
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.
Indeed that sounds like an area worthy of optimization
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 understand the defense-in-depth argument, however is putting a variable limit maybe going too far.
It's said that 300k
should be sufficient but what's the basis of that assumption of sufficiency?
If there are programs which need more variables to more innocent arithmetic operations, this prevents them from operating - this problem will be especially acute for people writing programs in Leo as it tends to lead to many more variables than programs written natively in Aleo instructions.
My main concern with this is that how the circuit creates variables under the hood is effectively opaque to most users (minus those who are familiar with the circuits) and will create a bad UX as users pull out their hair trying to find out why their deployments are failing.
Good questions.
The limit is 1M, same as the constraint limit, because synthesizing variables and constraints for our existing gadgets go hand in hand. If you grep in snarkVM for
This was also the case for the constraint limit. If you have alternative design ideas let me know. I agree we should report the reason of failure: https://github.com/AleoHQ/snarkOS/issues/2962 |
The design should have variable count in the verifying key. It is error prone to have it defined as an accessory, like in this PR. AFAIK, the It would be helpful to know why this design was chosen, and whether it was validated on a snarkOS devnet. |
I did consider it. From this PR's README: "we cannot add num_constants to CircuitInfo, constants are not a known quantity at the Varuna level. That's why I added the value to the Deployment object." Adding more context:
But go wild if you want to do it anyway.
Not yet, otherwise I would/should have mentioned in the PR README or one of the comments.
I see, that looks like a potential issue. A simpler way around could be to unify just those 2 functions |
Thanks for the insight. We're currently discussing using https://github.com/AleoHQ/snarkVM/pull/2444 as the replacement PR. |
Closing in favor of #2444 |
Motivation
Even though we limit program size and number of constraints, @d0cd identified that it is possible for someone to create huge constants in programs. During deployment verification, an attacker can make a validator take forever or use a lot of memory, without paying for it, because we don't limit or price constants.
The solution is to limit constants similarly to how we limit the number of constraints.
Some design considerations:
Deployment
object. Given that we price deployments by their size, the cost for deployments is increased by 0.01 aleo credit per function. Technically, we could only track the constants and not the total number of variables in the deployment, but I fear its less understandable for outside developers.Test Plan
Adding two tests, one testing the variable limit, and one testing manipulation of reported variables.
Related PRs
Similar to: https://github.com/AleoHQ/snarkVM/pull/2271