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

[kiosk] Kiosk+ (again) #9709

Merged
merged 16 commits into from
Mar 24, 2023
Merged

[kiosk] Kiosk+ (again) #9709

merged 16 commits into from
Mar 24, 2023

Conversation

damirka
Copy link
Contributor

@damirka damirka commented Mar 22, 2023

Description

  • adds item: ID to the TransferRequest
  • removes metadata: Bag as redundant and rather complicated to manage
  • collectible nuked until a better solution is ready (requires a bit of refactoring)
  • removes all policies - moves them to tests for the time being
  • improves testing for everything kiosk-related
  • exposes uid and uid_mut (for owner) of the TransferPolicy so that it can contain app-specific data
  • Kiosk now has a custom setting "no taking" - disables take function

Test Plan

  • tests are in place
  • many cases are tested upfront

Type of Change (Check all that apply)

  • user-visible impact
  • breaking change for a client SDKs
  • breaking change for FNs (FN binary must upgrade)
  • breaking change for validators or node operators (must upgrade binaries)
  • breaking change for on-chain data layout
  • necessitate either a data wipe or data migration

Release notes

  • finalizes Kiosk and TransferPolicy modules

@damirka damirka requested review from amnn and sblackshear March 22, 2023 17:33
@damirka damirka requested a review from randall-Mysten as a code owner March 22, 2023 17:33
@damirka damirka self-assigned this Mar 22, 2023
@damirka damirka requested a review from ronny-mysten as a code owner March 22, 2023 17:33
@vercel
Copy link

vercel bot commented Mar 22, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

3 Ignored Deployments
Name Status Preview Comments Updated
explorer ⬜️ Ignored (Inspect) Visit Preview Mar 24, 2023 at 9:07PM (UTC)
explorer-storybook ⬜️ Ignored (Inspect) Visit Preview Mar 24, 2023 at 9:07PM (UTC)
wallet-adapter ⬜️ Ignored (Inspect) Mar 24, 2023 at 9:07PM (UTC)

@damirka
Copy link
Contributor Author

damirka commented Mar 22, 2023

Also includes the changes from #9604 by @nmboavida.

Copy link
Member

@amnn amnn left a comment

Choose a reason for hiding this comment

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

I like the change overall, but have some questions (inline) on how the witnesses that kiosk actions produce are intended to be used!

assert!(object::id(self) == cap.for, ENotOwner);
self.item_count = self.item_count + 1;
dof::add(&mut self.id, Item { id: object::id(&item) }, item)
dof::add(&mut self.id, Item { id: object::id(&item) }, item);
PlacedWitness {}
Copy link
Member

Choose a reason for hiding this comment

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

Asking because it popped into my head: Is it worth including the placed item's id in the witness?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Agreed with Ashok--unless the type in question is a singleton, I think we will always need to remember the ID/check it. Otherwise, it seems hard to avoid issues where someone "reuses" a witness for a different instance of T (+ hard to reason about what the consequences might be).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ID in the witness won't be much help - we don't have the ID of the item in the TransferRequest so there's no way to compare it. TransferPolicy relies solely on type, and creating IDs everywhere can lead to "abuse of power" on the creator end.


#[test]
#[expected_failure(abort_code = sui::witness_policy::ERuleNotFound)]
fun test_wrong_proof() {
Copy link
Member

Choose a reason for hiding this comment

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

Is this policy supposed to be used with the witnesses that come from Kiosk? If so I still don't quite see how we can prevent someone from creating a witness from actions on one instance and then using it as proof on another witness.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good question.

Given that TransferPolicy affects all items of a type T, and kiosk witnesses are also returned "typed", only an item of type T can result in KioskWitness. To cheat on this system, one has to put / list another item T. And that is okay.

While implementing I considered two main applications:

  1. TransferPolicy has "allow_taking" set to "false". Once placed into the Kiosk, items can't be taken. The only thing that can happen to them is list-sell (simple) or PurchaseCap-grab (more complex). However, we can't lock items in the purchase function - its signature is purchase() :(T, TransferRequest<T>). Hence we need to find a way to "force" user to put it into kiosk - and the "PlacedWitness" in the Kiosk allows us to achieve that.

  2. We issue a "key-only" type, eg Collectible has key. To sell the Collectible, we need to turn it into a transferable type "TradableCollectible" - but we need a guarantee that it was listed / placed into the Kiosk. PlacedWitness or ListedWitness again help. Once sold, we can issue a rule for a TransferPolicy which will force the TradableCollectible to be turned into non-transferable Collectible again.

/// performed (eg item was put back to the `Kiosk` after a sell).
///
/// Defaults to `true`.
allow_taking: bool
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a specific witness_policy we can recommend here for someone that wants very strict enforcement?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed this part completely in favor of "kiosk::has_item" check. Should be better and more understandable to execute.

assert!(object::id(self) == cap.for, ENotOwner);
self.item_count = self.item_count + 1;
dof::add(&mut self.id, Item { id: object::id(&item) }, item)
dof::add(&mut self.id, Item { id: object::id(&item) }, item);
PlacedWitness {}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Agreed with Ashok--unless the type in question is a singleton, I think we will always need to remember the ID/check it. Otherwise, it seems hard to avoid issues where someone "reuses" a witness for a different instance of T (+ hard to reason about what the consequences might be).

@vercel vercel bot temporarily deployed to Preview – explorer-storybook March 24, 2023 08:19 Inactive
@damirka damirka changed the title [kiosk] New ActionWitness pattern + proof-lock policy [kiosk] Kiosk: no metadata; item ID to Request Mar 24, 2023
@damirka damirka changed the title [kiosk] Kiosk: no metadata; item ID to Request [kiosk] Kiosk+ (again) Mar 24, 2023
Copy link
Member

@amnn amnn left a comment

Choose a reason for hiding this comment

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

LGTM! (@damirka and I chatted offline about paring this down to a minimal feature set, explaining the new red lines)

@damirka damirka merged commit 9b41517 into main Mar 24, 2023
@damirka damirka deleted the kiosk-forever branch March 24, 2023 21:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants