-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
[Spec] add boogie native for aggregator_v2 #14881
base: main
Are you sure you want to change the base?
Conversation
⏱️ 2h 4m total CI duration on this PR
|
69a1fa9
to
6536135
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #14881 +/- ##
===========================================
- Coverage 72.8% 59.7% -13.1%
===========================================
Files 2400 853 -1547
Lines 485208 208289 -276919
===========================================
- Hits 353490 124541 -228949
+ Misses 131718 83748 -47970 ☔ View full report in Codecov by Sentry. |
let supply = global<ConcurrentSupply>(collection_addr); | ||
let post supply_post = global<ConcurrentSupply>(collection_addr); | ||
aborts_if exists<ConcurrentSupply>(collection_addr) && | ||
aggregator_v2::spec_get_value(supply.current_supply) + 1 > aggregator_v2::spec_get_max_value(supply.current_supply); |
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.
Can we make line breaks better here? Shouldn't be over 100 characters
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.
done
&& $IsEqual'{{S}}'(s1->$max_value, s2->$max_value) | ||
} | ||
|
||
{% if S == "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.
Ther seems to be a bit of duplication in this if-else? Could we perhaps loop over the various types instead>
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 refactored the template here to reduce duplication.
@@ -194,7 +194,7 @@ module aptos_framework::aggregator_v2 { | |||
/// Concatenates `before`, `snapshot` and `after` into a single string. | |||
/// snapshot passed needs to have integer type - currently supported types are u64 and u128. | |||
/// Raises EUNSUPPORTED_AGGREGATOR_SNAPSHOT_TYPE if called with another type. | |||
/// If length of prefix and suffix together exceed 256 bytes, ECONCAT_STRING_LENGTH_TOO_LARGE is raised. | |||
/// If length of prefix and suffix together exceed 1024 bytes, ECONCAT_STRING_LENGTH_TOO_LARGE is raised. |
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.
another typo: exceed
--> exceeds
"object_instances".to_string(), | ||
true, | ||
)], | ||
module_instance_names: vec![ |
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.
Seems like module_instances
can be factored out? It is duplicated across multiple files causing more changes
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.
done
spec fun spec_read_derived_string(snapshot: DerivedStringSnapshot): String { | ||
snapshot.value | ||
} | ||
|
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.
nit: this extra line is not needed?
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.
done
spec native fun spec_get_max_value<IntElement>(aggregator: Aggregator<IntElement>): IntElement; | ||
// Uninterpreted spec function that translates the value inside aggregator into corresponding string representation | ||
spec fun spec_get_string_value<IntElement>(aggregator: AggregatorSnapshot<IntElement>): String; | ||
spec fun spec_read_snapshot<IntElement>(snapshot: AggregatorSnapshot<IntElement>): IntElement { |
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.
nit: for consistency can also use get
instead of read
in these names? So we get aggregator value, get snapshot integer value, etc.
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 used read
here because there are corresponding APIs read_snapshot
and read_derived_string
.
pragma opaque; | ||
include AbortsIfIntElement<IntElement>; | ||
ensures [abstract] result.value == spec_get_value(aggregator); |
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.
Question, why here we need to call a spec native for aggregator, and not aggregator.value? Is it because the spec is intrinsic? Cause technically for sub for example you can say: aggregator.value = old(aggregator).value - amount if no overflow, etc. or does the spec not support these kind of things because of generic types?
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.
yeah, when the spec of a struct is intrinsic, we cannot directly get access to its field. The reason of using intrinsics for spec is because generic types do not support +
and -
.
@@ -209,6 +209,199 @@ module aptos_framework::aggregator_v2 { | |||
/// DEPRECATED, use derive_string_concat() instead. always raises EAGGREGATOR_FUNCTION_NOT_YET_SUPPORTED. | |||
public native fun string_concat<IntElement>(before: String, snapshot: &AggregatorSnapshot<IntElement>, after: String): AggregatorSnapshot<String>; | |||
|
|||
#[verify_only] |
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 was not aware we had these attributes, so this can be used for spec testing? Nice to know!
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.
yeah, with this attribute, the function is only visible for verification.
let x = try_add(&mut agg, 5); | ||
spec { | ||
assert x; | ||
assert is_at_least(agg, 5); |
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.
Curious why at least and not exact equality?
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 use this assertion to test the native implementation for the API is_at_least
.
This stack of pull requests is managed by Graphite. Learn more about stacking. Join @rahxephon89 and the rest of your teammates on Graphite |
9d4bead
to
da06c6d
Compare
Description
This PR adds native implementation of aggregator_v2 in the Move prover.
How Has This Been Tested?
aggregator_v2.move
.collection.move
inaptos-token-objects
.Key Areas to Review
#...
, only the abort_if conditions are specified, need to make sure it is correct.Type of Change
Which Components or Systems Does This Change Impact?
Checklist