Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
Bounty Pallet: add
approve_bounty_with_curator
call tobounties
pallet #5961Bounty Pallet: add
approve_bounty_with_curator
call tobounties
pallet #5961Changes from 8 commits
83f249b
209aefb
a4aa9ea
158c92a
f8397f3
c1ea1bb
f09b5b1
727e8fb
233576c
904b7eb
adfd661
7573387
bc3a06f
b41a632
7923a4e
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
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 we need a new status? why cannot it be exactly the same behaviour as a batch of
approve_bounty
andpropose_curator
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.
@muharem Because there still needs some time to pass when bounty is funded because as I understand only at beginning of the block bounties are funded. There could be a time when bounty is approved but funds are not available for some time. So, if we were to jump to a Funded status we would be trying to fund the bounty right away taking from the treasury, and if we don't have funds we can't fund bounty and propose a curator yet. So we have status that bounty is ApprovedWithCurator to be able to approve the bounty without having funds yet.
Correct me if I'm wrong in this
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.
you are 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’m not very familiar with the code, but having multiple statuses with similar meanings seems like a potential code smell.
How about modifying
Approved
with the fieldmaybe_curator: Option<AccountId>
? Probably we want to avoid any breaking change (which is totally understandable)? Though any indexer now needs to support theApprovedWithCurator
status as well, so I guess breaking change in this scenario is better.I leave the judgement to you guys. Though it would be great to have some doc explaining expected lifecycle of a bounty (I couldn't find one).
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.
As a maintainer of this code, I wish to modify the existing status.
But my thought was - better non breaking change, all clients keep working. new feature available only to the clients adopting the new status.
@TarikGul @Tbaut @ERussel what you think?
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.
Generally speaking, breaking changes should be avoided if possible (when discussing downstream clients, and tools), and if they are necessary then they should be correctly communicated in a changelog - and/or runtime release docs.
Even though this would be a tall task, I totally agree. I would love to see more documentation on this front.
Atleast from the perspective of PJS - everything is dynamically generated from the metadata now. That being said the static typing (not to be confused with the dynamic generation at runtime) requires a few longer steps to get the types reflected in the PJS libraries - generate the static types - fix any required changes - release the api - then update all deps downstream.
If I am not mistaken the PAPI descriptors do a way better job at supplying the types (But I am no expert - yet :))
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 want to make this effort future-proof, and bring it up to date with #4722, we should be asking ourselves:
BountyStatus
is the status enum that the internal logic of the pallet would need to care about. Is it even reasonable to expose this to the users?For example, if we are to design a
fn status_of(bounty) -> BountyStatus
as a view function, what would the return type be?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'm sorry that I'm late to the party. Modifying
Approved
to be anOption<AccountId>
would have been a better way to go IMO.The reason is simple: if a DApp has not been updated to take into account the new variant, then if they receive the variant "
ApprovedWithCurator
" the DApp will almost surely blow up, because they don't know how to deal with that variant.On the other hand, modifying the
Approved
variant to support an optional value, may prevent some DApps from blowing up (sure, they may not take into account the value of the variant, but perhaps they don't need to). Also, at least with PAPI, it makes it much simpler for DApp developers to adapt to the change on their DApps.Long story short: adding new variants on enums that are used as inputs is a good way to prevent breaking changes on DApps. However, adding new variants on enums that are used as outputs is a guaranteed way to trigger breaking changes on DApps.
New variants on read enums: bad.
New variants on write enums: good.
I'm sorry that I'm sharing this after the PR has been merged.
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.
This means the impact can be different for dapps and indexers. We need to learn more about it and document. It seems like we really can improve the status quo.
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 really fail to understand why this change is better for indexers.
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.
This call seems like is an example of #5958.
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.
But just looking at the diff, and knowing little about this pallet, I disagree with this statement.
If this call was purely an equivalent of
batch(approve, propose)
, then:approve().and(propose)
. Perhaps this would be less efficient, but it should be functionally the same.BountyStatus
variant.So perhaps this PR is actually doing more than just introducing a shorthand for combining two existing atomic operations?
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.
The issue is ( #5961 (comment) ) that after bounty is approved some time must pass until bounty reaches
Funded
status because bounty fundings happen in the beginning of every block.The only way for this to be atomic is if with approval we try to fund the bounty right away, from
Funded
then it could go toCuratorProposed
state, but there may not be enough money in the treasury and such action will revert.I'm open to simpler solutions which may keep the flow backwards compatible with previous version.
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.
Thanks for explaining! The current solution is good, I was mainly interested in the relationship between this and #5958.
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 we need to emit both events? Is
BountyApproved
inferable fromCuratorProposed
?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 we need to emit both, because this function does logically what
approve_bounty
andpropose_curator
does, and they emit these events separately.Yes,
BountyApproved
could be inferred fromCuratorProposed
in the state machine,CuratorProposed
can happen only after bounty is approved. But then I think people would need to start assuming implementation details of how this pallet works when indexing.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.
Wouldn't
maybe_curator: Option<AccountId>
break existing which usedApproved
enum? I think it would add at least 1 byte for the option ofApproved
whether it isNone
orSome
, with these changes we leave the rest of the enums unmodified and people would only need to add support for the new oneThere 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.
Only ask this since events are expensive and stored in state of each block. But of course if you have a good reason to emit both, go for it.
Is breaking change always bad? Especially since old clients may have unexpected side effects, i.e. just miss the approved (
ApprovedWithCurator
) status altogether if they depend on the existingApproved
status.Also types are dynamically generated from substrate metadata and potentially for js clients this might not even be a breaking change.
P.S.: None of this is a huge deal tbh. I’m comfortable with either approach, as long as we’re mindful of the tradeoffs.