-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
[agg_v2] Adding aggregator_v2.move with sequential (fallback) logic #10397
Conversation
@@ -123,4 +123,9 @@ impl<'a, 'b, 'c, 'd> SafeNativeContext<'a, 'b, 'c, 'd> { | |||
pub fn aggregator_snapshots_enabled(&self) -> bool { | |||
self.get_feature_flags().is_aggregator_snapshots_enabled() | |||
} | |||
|
|||
/// TODO: decide if we want to have two flags or merge with aggregator_snapshots_enabled. |
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 are introducing new native functions that need to be gated.
since aggregator_snapshots_enabled was never enabled, we can either:
- decide not to enable it before v1.8, and combine aggregator_api_enabled into it.
- if we want to enable in point release for v1.7, we would need to add a new flag instead.
/// | ||
/// Currently supported types for Element are u64 and u128. | ||
/// EAGGREGATOR_ELEMENT_TYPE_NOT_SUPPORTED raised if called with a different type. | ||
public native fun create_unbounded_aggregator<IntElement: copy + drop>(): Aggregator<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.
Does this have to be a native function? It can simply call create_aggregator with an appropriate max_value right?
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 don't think it can be done, because the type is generic.
i.e. something like this doesn't compile:
public fun create_unbounded_aggregator<IntElement: copy + drop>(): Aggregator<IntElement> {
if (type_info::type_of<IntElement>() == type_info::type_of<u64>()) {
create_aggregator(MAX_U64)
} else if (type_info::type_of<IntElement>() == type_info::type_of<u128>()) {
create_aggregator(MAX_U128)
} else {
abort error::invalid_argument(EUNSUPPORTED_AGGREGATOR_TYPE);
}
}
this compiles:
if (type_info::type_of<Element>() == type_info::type_of<u64>()) {
this doesn't:
return create_aggregator(MAX_U64)
when return type of the function is : Aggregator
Compiler could probably infer something, but even in C++/rust not sure that would pass. Not sure if there is a different way to write this.
} | ||
|
||
#[test(fx = @std)] | ||
public fun test_string_concat2(fx: &signer) { |
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.
Do these test cases succeed now? They weren't successful when I merged the aggregator snapshot changes in main.
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 was a bug in how features were handled in the harness, that was fixed. I'll recheck , but I think they pass now
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 I imagined something, they still don't work.
@@ -39,94 +50,418 @@ fn is_string_type(context: &SafeNativeContext, type_arg: &Type) -> SafeNativeRes | |||
Ok(false) | |||
} | |||
|
|||
/// Given the list of native function arguments and a type, returns a tuple of its |
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: We are only giving one native function argument.
e854e01
to
475d73f
Compare
) -> SafeNativeResult<SnapshotValue> { | ||
match self { | ||
SnapshotType::U128 => Ok(SnapshotValue::Integer(safely_pop_arg!(args, u128))), | ||
SnapshotType::U64 => Ok(SnapshotValue::Integer(safely_pop_arg!(args, u64) as u128)), |
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.
Note for the future: SnapshotValue is replaced by DelayedFieldValue right?
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.
no - SnapshotValue encompasses types that AggregatorSnapshot can take
DelayedFieldValue is list of Delayed Fields (today aggregator, snapshot delta and snapshot derived. tomorrow maybe more).
this code is identical on aggregators_v2 branch - https://github.com/aptos-labs/aptos-core/blob/aggregators_v2/aptos-move/framework/src/natives/aggregator_natives/aggregator_v2.rs#L143
} | ||
|
||
impl SnapshotToStringFormula { | ||
pub fn apply_to(&self, base: u128) -> Vec<u8> { |
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.
What is we are deriving the snapshot from aggregator_u64? Are we still going to treat u64 as u128 when creating string snapshot?
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 always go to u128, and cast to appropriate type when return to move, for code simplicity.
And all this is identical on aggregator_v2 branch - https://github.com/aptos-labs/aptos-core/blob/aggregators_v2/aptos-move/aptos-aggregator/src/types.rs#L322
// TODO: aggregator_v2 branch will introduce these in different places in code | ||
|
||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub enum SnapshotValue { |
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 are going to land aggregator_v2 branch on main in a week anyway. What are we benefitting by landing these stuff here in main now, and changing them again after landing aggregator_v2?
@@ -201,11 +201,17 @@ crate::gas_schedule::macros::define_gas_parameters!( | |||
[aggregator_destroy_base: InternalGas, "aggregator.destroy.base", 10000], | |||
[aggregator_factory_new_aggregator_base: InternalGas, "aggregator_factory.new_aggregator.base", 10000], | |||
|
|||
[aggregator_v2_snapshot_base: InternalGas, {11.. => "aggregator_v2.snapshot.base"}, 6000], |
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 reminder to fix the gas feature version here
475d73f
to
c255306
Compare
/// | ||
/// Currently supported types for Element are u64 and u128. | ||
/// EAGGREGATOR_ELEMENT_TYPE_NOT_SUPPORTED raised if called with a different type. | ||
public native fun create_aggregator<IntElement: copy + drop>(max_value: IntElement): Aggregator<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.
if we only support u64 and u128, I think it's better to write constructors explicitly and leave other functions generic
fun create_u64_aggregator(max_value: u64): Aggregator<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.
why?
usage here seems just fine - https://github.com/aptos-labs/aptos-core/pull/9972/files#diff-7026c328622536165825a6f5dcaf13764bd475489ecba30ba4716dfdc4acc1e9
and set of types we support is something we can expand on in the future.
f10fc4a
to
57e67a5
Compare
Self-contained logic that can be landed on main, and so ecosystem PRs can land independently of the rest of the aggregator changes Copied from aggregators_v2 branch Fixing tests and more comments gas fixes and limit to string length
57e67a5
to
65b233d
Compare
const EAGGREGATOR_OVERFLOW: u64 = 1; | ||
|
||
/// The value of aggregator underflows (goes below zero). Raised by uncoditional sub() call | ||
const EAGGREGATOR_UNDERFLOW: u64 = 2; |
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.
@igor-aptos what was 3 and 4?
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 think that was from v1 aggregators, to disambiguate.
though I see only 3 there now:
const ENOT_SUPPORTED: u64 = 3;
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.
because rest are consistent:
/// The value of aggregator overflows. Raised by native code.
const EAGGREGATOR_OVERFLOW: u64 = 1;
/// The value of aggregator underflows (goes below zero). Raised by native code.
const EAGGREGATOR_UNDERFLOW: u64 = 2;
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.
ENOT_SUPPORTED is never used I think
|
||
/// Creates new aggregator, with given 'max_value'. | ||
/// | ||
/// Currently supported types for Element are u64 and u128. |
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.
Element --> IntElement?
public native fun try_add<IntElement>(aggregator: &mut Aggregator<IntElement>, value: IntElement): bool; | ||
|
||
// Adds `value` to aggregator, uncoditionally. | ||
// If addition would exceed the max_value, EAGGREGATOR_OVERFLOW exception will be thrown |
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: missing . in docstring
public native fun try_sub<IntElement>(aggregator: &mut Aggregator<IntElement>, value: IntElement): bool; | ||
|
||
// Adds `value` to aggregator, uncoditionally. | ||
// If subtraction would result in a negative value, EAGGREGATOR_UNDERFLOW exception will be thrown |
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.
ditto
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.
Also, adds --> subtracts
// } | ||
#[test] | ||
#[expected_failure(abort_code = 0x030009, location = Self)] | ||
public fun test_copy_not_yet_supported() { |
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.
why public functions? here and before/after as well
Ok((id, limit)) | ||
}, | ||
Type::U64 => { | ||
// Get aggregator information and a value to add. |
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.
same here
}, | ||
)]))) | ||
}, | ||
// ty_arg cannot be Integer, if value is String |
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.
what is ty_arg
here?
) -> SafeNativeResult<SmallVec<[Value; 1]>> { | ||
abort_if_not_enabled!(context); | ||
|
||
debug_assert_eq!(args.len(), 0); |
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.
Should we assert we have a single type arg
let result_value = { | ||
let math = BoundedMath::new(agg_max_value); | ||
match math.unsigned_subtract(agg_value, input) { | ||
Ok(sum) => { |
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.
sum --> diff/difference?
|
||
let prefix = string_to_bytes(safely_pop_arg!(args, Struct))?; | ||
|
||
if prefix.len() + suffix.len() > CONCAT_PREFIX_AND_SUFFIX_MAX_LENGTH { |
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 think I asked on some other PR before, this sum is always < max u64
03c003f
to
c21d104
Compare
c21d104
to
aa4be7d
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
✅ Forge suite
|
✅ Forge suite
|
✅ Forge suite
|
Self-contained logic that can be landed on main, and so ecosystem PRs can land independently of the rest of the aggregator changes
once aggregator backend execution logic lands, this will be a fallback logic used until separate aggregator execution flag is turned on.
Copied from aggregators_v2 branch
Description
Test Plan