Skip to content
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

[framework] implement immovable objects #13175

Merged
merged 1 commit into from
May 10, 2024
Merged

[framework] implement immovable objects #13175

merged 1 commit into from
May 10, 2024

Conversation

davidiw
Copy link
Contributor

@davidiw davidiw commented May 2, 2024

Make it so that objects can be made immovable via the constructor ref. Even if other entities have access to the constructor ref.

Add the functionality to fungible asset to make immovable stores by default for assets that opt into the behavior.

Also offer a root_owner function to determine the deepest node that owns a nested object.

See aptos-foundation/AIPs#414

Description

Type of Change

  • New feature
  • Bug fix
  • Breaking change
  • Performance improvement
  • Refactoring
  • Dependency update
  • Documentation update
  • Tests

Which Components or Systems Does This Change Impact?

  • Validator Node
  • Full Node (API, Indexer, etc.)
  • Move/Aptos Virtual Machine
  • Aptos Framework
  • Aptos CLI/SDK
  • Developer Infrastructure
  • Other (specify)

How Has This Been Tested?

Lots of unit tests

Key Areas to Review

There's really not that much code...

Checklist

  • I have read and followed the CONTRIBUTING doc
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I identified and added all stakeholders and component owners affected by this change as reviewers
  • I tested both happy and unhappy path of the functionality
  • I have made corresponding changes to the documentation

Copy link

trunk-io bot commented May 2, 2024

⏱️ 2h 12m total CI duration on this PR
Job Cumulative Duration Recent Runs
rust-targeted-unit-tests 45m 🟩🟩
rust-move-unit-coverage 39m 🟩🟩
rust-move-tests 20m 🟩🟩
rust-lints 11m 🟩🟩
run-tests-main-branch 8m 🟩🟩
general-lints 4m 🟩🟩
check-dynamic-deps 2m 🟩🟩
semgrep/ci 47s 🟩🟩
file_change_determinator 22s 🟩🟩
file_change_determinator 20s 🟩🟩
permission-check 10s 🟩🟩
permission-check 7s 🟩🟩
permission-check 6s 🟩🟩
permission-check 5s 🟩🟩

🚨 1 job on the last run was significantly faster/slower than expected

Job Duration vs 7d avg Delta
rust-targeted-unit-tests 23m 15m +55%

settingsfeedbackdocs ⋅ learn more about trunk.io

Copy link
Contributor

@gregnazario gregnazario left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine to me.

Do we want to use Immovable as a name? Mixing movable and transferable to mean the same thing is weird. Especially since you can move resources to the object

@davidiw
Copy link
Contributor Author

davidiw commented May 2, 2024

There's object transfer and fa transfer, nomenclature is hard 😬

Copy link

codecov bot commented May 2, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 57.6%. Comparing base (1af48e9) to head (6766805).
Report is 25 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff            @@
##             main   #13175    +/-   ##
========================================
  Coverage    57.5%    57.6%            
========================================
  Files         833      834     +1     
  Lines      198121   198399   +278     
========================================
+ Hits       113999   114334   +335     
+ Misses      84122    84065    -57     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@igor-aptos
Copy link
Contributor

Currently, if you first call to enable ungated transfer, can to make it immovable doesn't do anything. Should we move the check to one of transfer implementation functions?

"Move" is also overloaded a lot. Can we just be more explicit? CannotChangeOwner, or ImmutableOwner, or something like that?

@davidiw
Copy link
Contributor Author

davidiw commented May 2, 2024

Currently, if you first call to enable ungated transfer, can to make it immovable doesn't do anything. Should we move the check to one of transfer implementation functions?

Did you type this on a phone :P

I might be missing your point, this locks all possible transfers of the object after it has been set immovable. I'm not sure there's a logical error, we can always surface different errors and have more checks if we want to be more pedantic.

I'll update the AIP and think about the name...
Frozen, Immovable, Untransferable sound okay
ImmutableOwner is more explicit but sounds ... lame 🤔

}

/// Returns true if the FA is untransferable.
public fun is_immovable<T: key>(metadata: Object<T>): bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth adding #[view] above?

@@ -234,6 +240,19 @@ module aptos_framework::fungible_asset {
object::object_from_constructor_ref<Metadata>(constructor_ref)
}

/// Set that only untransferable stores can be create for this fungible asset.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Set that only untransferable stores can be create for this fungible asset.
/// Set that only untransferable stores can be created for this fungible asset.

@@ -120,6 +122,10 @@ module aptos_framework::fungible_asset {
project_uri: String,
}

#[resource_group_member(group = aptos_framework::object::ObjectGroup)]
/// Defnes a fungible asset stores as being untransferable at the object layer.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Defnes a fungible asset stores as being untransferable at the object layer.
/// Defines a fungible asset store as being untransferable at the object layer.

@@ -120,6 +122,10 @@ module aptos_framework::fungible_asset {
project_uri: String,
}

#[resource_group_member(group = aptos_framework::object::ObjectGroup)]
/// Defines a fungible asset stores as being untransferable at the object layer.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took me a minute to understand this is on FungibleAsset , saying that all of their FungibleStore's are immutable.

Suggested change
/// Defines a fungible asset stores as being untransferable at the object layer.
/// Defines a FungibleAsset, such that all FungibleStores are untransferable (marked at such at the object layer).
/// All primary fungible stores are always untransferable (i.e. even without this). This applies to the secondary stores.

Copy link
Contributor

@lightmark lightmark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please see my comment


#[view]
/// Returns true if the FA is untransferable.
public fun is_untransferable<T: key>(metadata: Object<T>): bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

T can only be Metadata, right? why not make (metadata: Object<Metadata>)

@@ -120,6 +122,10 @@ module aptos_framework::fungible_asset {
project_uri: String,
}

#[resource_group_member(group = aptos_framework::object::ObjectGroup)]
/// Defines a fungible asset stores as being untransferable at the object layer.
struct Untransferable has key {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use an enum style with another struct Transferrable mutually exclusive with Untransferable so TransferRef and Untransferrable object are also mutually exclusive?
if Untransferable exists, no TransferRef will be generated.
if TransferRef is generated, Transferable will exists and you cannot make an object Untransferrable. This way we don't have to exists<Transferrable> in the following function calls because the enable_ungated_transfer is always false and we are ensured TransferRef does not exist for this object.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this may be cleaner.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That doesn't work, since either can be generated if given a ConstructorRef prior to calling set_untransferrable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoever gets called first will set a flag there which prohibits the other. So it should work

Make it so that objects can be made untransferable via the constructor ref.
Even if other entities have access to the constructor ref.

Add the functionality to fungible asset to make untransferable stores by
default for assets that opt into the behavior.

Also offer a root_owner function to determine the deepest node that owns
a nested object.
@davidiw davidiw enabled auto-merge (squash) May 9, 2024 23:59

This comment has been minimized.

This comment has been minimized.

Copy link
Contributor

✅ Forge suite compat success on 01b24e7e3548382dd25440b39a0438a993387f12 ==> 6766805bde50fa31553af6217acc2ce6358933d7

Compatibility test results for 01b24e7e3548382dd25440b39a0438a993387f12 ==> 6766805bde50fa31553af6217acc2ce6358933d7 (PR)
1. Check liveness of validators at old version: 01b24e7e3548382dd25440b39a0438a993387f12
compatibility::simple-validator-upgrade::liveness-check : committed: 5721 txn/s, latency: 5792 ms, (p50: 5100 ms, p90: 8900 ms, p99: 10000 ms), latency samples: 223120
2. Upgrading first Validator to new version: 6766805bde50fa31553af6217acc2ce6358933d7
compatibility::simple-validator-upgrade::single-validator-upgrade : committed: 1853 txn/s, latency: 15747 ms, (p50: 19300 ms, p90: 22600 ms, p99: 23100 ms), latency samples: 90800
3. Upgrading rest of first batch to new version: 6766805bde50fa31553af6217acc2ce6358933d7
compatibility::simple-validator-upgrade::half-validator-upgrade : committed: 1301 txn/s, latency: 21112 ms, (p50: 24900 ms, p90: 28800 ms, p99: 29300 ms), latency samples: 74200
4. upgrading second batch to new version: 6766805bde50fa31553af6217acc2ce6358933d7
compatibility::simple-validator-upgrade::rest-validator-upgrade : committed: 3539 txn/s, latency: 8915 ms, (p50: 9600 ms, p90: 12600 ms, p99: 12900 ms), latency samples: 145100
5. check swarm health
Compatibility test for 01b24e7e3548382dd25440b39a0438a993387f12 ==> 6766805bde50fa31553af6217acc2ce6358933d7 passed
Test Ok

This comment has been minimized.

This comment has been minimized.

Copy link
Contributor

✅ Forge suite realistic_env_max_load success on 6766805bde50fa31553af6217acc2ce6358933d7

two traffics test: inner traffic : committed: 8167 txn/s, latency: 4802 ms, (p50: 4500 ms, p90: 5700 ms, p99: 10500 ms), latency samples: 3528220
two traffics test : committed: 100 txn/s, latency: 1966 ms, (p50: 1900 ms, p90: 2100 ms, p99: 6300 ms), latency samples: 1740
Latency breakdown for phase 0: ["QsBatchToPos: max: 0.211, avg: 0.207", "QsPosToProposal: max: 0.232, avg: 0.216", "ConsensusProposalToOrdered: max: 0.449, avg: 0.400", "ConsensusOrderedToCommit: max: 0.382, avg: 0.368", "ConsensusProposalToCommit: max: 0.779, avg: 0.769"]
Max round gap was 1 [limit 4] at version 1515184. Max no progress secs was 4.876413 [limit 15] at version 1515184.
Test Ok

@davidiw davidiw disabled auto-merge May 10, 2024 21:45
@davidiw davidiw merged commit 3cad94e into main May 10, 2024
82 of 85 checks passed
@davidiw davidiw deleted the unt_fa branch May 10, 2024 21:45
@areshand areshand added the CICD:run-execution-performance-test Run execution performance test label May 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CICD:run-execution-performance-test Run execution performance test
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants