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

Introduce and Implement VestedTransfer Trait #5630

Open
wants to merge 21 commits into
base: master
Choose a base branch
from

Conversation

shawntabrizi
Copy link
Member

This PR introduces a VestedTransfer Trait, which handles making a transfer while also applying a vesting schedule to that balance.

This can be used in pallets like the Treasury pallet, where now we can easily introduce a vested_spend extrinsic as an alternative to giving all funds up front.

We implement () for the VestedTransfer trait, which just returns an error, and allows anyone to opt out from needing to use or implement this trait.

This PR also updates the logic of do_vested_transfer to remove the "pre-check" which was needed before we had a default transactional layer in FRAME.

Finally, I also fixed up some bad formatting in the test.rs file.

@shawntabrizi shawntabrizi requested a review from a team as a code owner September 6, 2024 19:07
@shawntabrizi shawntabrizi changed the title Introduce VestedTransfer Trait Introduce and Implement VestedTransfer Trait Sep 6, 2024
@shawntabrizi
Copy link
Member Author

After this PR, I would like to open a PR to Treasury pallet to enable the option to do a vested_spend, and see how opengov uses it.

@shawntabrizi shawntabrizi added T1-FRAME This PR/Issue is related to core FRAME, the framework. T2-pallets This PR/Issue is related to a particular pallet. labels Sep 6, 2024
bkchr
bkchr previously approved these changes Sep 6, 2024
Copy link
Member

@bkchr bkchr left a comment

Choose a reason for hiding this comment

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

Generally okay, but some things need to change.

substrate/frame/vesting/src/lib.rs Outdated Show resolved Hide resolved
&target,
schedule.locked(),
schedule.per_block(),
schedule.starting_block(),
);
debug_assert!(res.is_ok(), "Failed to add a schedule when we had to succeed.");
)?;
Copy link
Member

Choose a reason for hiding this comment

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

This means that everyone calling this will need to use transactional to revert the changes if there is an error.

Copy link
Member Author

Choose a reason for hiding this comment

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

everyone in frame uses transactional? what am I missing?

All code inside the runtime now assume we can error at any point in the code. when this was written, it wasn't the case, hence the need to "double check"

Copy link
Contributor

Choose a reason for hiding this comment

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

But VestedTransfer::vested_transfer function is not a pallet call. If someone implements an error recovery logic it can get messy I suppose.

Maybe it is standard practice now, but I would add a small comment on top of do_vesting_transfer that the storage is dirty in case the method becomes public in the future.
And in the doc of VestedTransfer::vested_transfer I would also write that the storage can be dirty when error is returned.

Copy link
Member

Choose a reason for hiding this comment

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

But VestedTransfer::vested_transfer function is not a pallet call. If someone implements an error recovery logic it can get messy I suppose.

Exactly. If someone handles the error, it will not be transactional. Or you do the transactional handling explicitly in the implementation of the trait.

Copy link
Member Author

@shawntabrizi shawntabrizi Sep 11, 2024

Choose a reason for hiding this comment

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

Thanks, I really didn't consider this. I have explicitly added a transactional layer to the trait implementation.

I feel there must be many traits in Polkadot SDK which are vulnerable to the same problem, right?

Copy link
Member Author

@shawntabrizi shawntabrizi Sep 11, 2024

Choose a reason for hiding this comment

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

Okay i brought back this check, not looking to cause an issue in Polkadot due to small optimization.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that in general people should probably rarely recover from a dispatch error, and it would be simpler to require the caller to rollback.

Maybe we can make a transition with a new type: DispatchErrorDirty or DispatchErrorToRollback which means that the storage is dirty and should be rollbacked to handle the error manually.

Or maybe everybody already assume that a DispatchError can have a dirty storage.

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah this kind of direction would be nice overall imo

@bkchr bkchr dismissed their stale review September 6, 2024 21:57

Just wanted to comment

@paritytech-review-bot paritytech-review-bot bot requested a review from a team September 6, 2024 21:57
substrate/frame/vesting/src/lib.rs Show resolved Hide resolved
&target,
schedule.locked(),
schedule.per_block(),
schedule.starting_block(),
);
debug_assert!(res.is_ok(), "Failed to add a schedule when we had to succeed.");
)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that in general people should probably rarely recover from a dispatch error, and it would be simpler to require the caller to rollback.

Maybe we can make a transition with a new type: DispatchErrorDirty or DispatchErrorToRollback which means that the storage is dirty and should be rollbacked to handle the error manually.

Or maybe everybody already assume that a DispatchError can have a dirty storage.

substrate/frame/vesting/src/lib.rs Outdated Show resolved Hide resolved
shawntabrizi and others added 2 commits September 14, 2024 14:08
Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T1-FRAME This PR/Issue is related to core FRAME, the framework. T2-pallets This PR/Issue is related to a particular pallet.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants