-
Notifications
You must be signed in to change notification settings - Fork 11
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
Voting Contract: vote and close uses current status #60
Conversation
3c8eeda
to
12c3af7
Compare
…ing and closing current status is used and saved
12c3af7
to
0cdf7df
Compare
Overall: really awesome you caught these problems, but I have some comments!
Got a test for 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.
Unmarking this PR as request changes
so as not to block it. Oops.
I mistakenly took this "closing twice test" as proof of that, but now I see that it was due to this check-for-rejected-status mechanism I added.
This still bothers me though. Because as I wrote in description:
I think this will be confusing and we should mitigate that, but now I don't have any idea how. |
Anyway, PR solves problem from issue and works. I referenced my problems in new issue, so this one could actually be merged. |
Does this actually happen though? The status query doesn't check the storage directly, but uses a helper that's supposed to return the current status taking expiration into account: I think the idea with this stuff is that queries use |
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.
Looks good. Just some questions / comments, and what I think is an error when closing.
return Err(ContractError::Rejected {}); | ||
} | ||
|
||
prop.update_status(&env.block); |
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 is the key thing to do. Wouldn't this have to be done in the other cases where current_status()
is being called as well? (i.e. our previous "execute proposal" fix).
That means, using current_status()
only for queries, and update_status()
for execution everywhere. And, "never" reading prop.status
directly. More consistent and robust, I think.
We can use an update_status()
impl that returns the updated status, as mentioned above (just an idea).
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 the idea with this stuff is that queries use current_status() and executions use update_status() and then everything checks out.
Yeah, you're right. I just realized, that despite status in memory not being correct, in the end it is correct for end user who uses query. We "simply" must be carefull to make sure we use that helper everywhere.
Just wrote a variant of the same above.
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 the code errors below, this status update will be discarded. And if it does not error, the status will be updated and saved later anyway. So, there's really no need to call update_status
instead of current_status
.
The bug is: not calling any of those, and reading the status directly.
Yeah, you're right. I just realized, that despite status in memory not being correct, in the end it is correct for end user who uses query. |
7a9de1f
to
1adbde0
Compare
I was just thinking that a (relatively cumbersome) way to do this would be to have / use two structs, one for state, with private members, and one for serialisation / deserialization, with pub ones. |
Yeah, that's one way to do it. I opened an issue for this: #63 |
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.
LGTM
…osals" This reverts commit e326913.
bbbd8ce
to
94daa76
Compare
closes #55
Closing and voting methods now use
current_status()
helper, which underneath can update status to Rejected.Because of that, first time closing a proposal that should be rejected could fail, because there was check in place to see, if status... is not already rejected.
To mitigate that, I used simple solution with saving status before closing, in order to detect if someone tries to close proposal first of 1+nth time.
I added extraSo that doesn't work, and I don't like it. :).save()
under each update status, since in case of early exit status update would be lost.So someone tries to vote on proposal,
update_status()
changes state toRejected
and vote is rejected, but then validator queries the proposal and sees thatstatus
was the same as before - probably just Open.I didn't change anything in
state.rs
file, simply movedimpl Proposal
so that it would be directly under its structure, instead on bottom of file for some reason.