-
Notifications
You must be signed in to change notification settings - Fork 12
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
Call emitInitiateChange
function by validator
#71
Comments
@DemiMarie please clarify, will the Parity trigger the validator set changing (and call For example,
Then imagine that at some block it returns the same set but in another order:
Will it be considered as a new set? (and call |
changeRequestCount()
getter instead of getPendingValidators()
changeRequestCount()
getter instead of getPendingValidators()
@varasev I am having trouble figuring out the answer, sorry. The code in question is very confusing. If the order doesn’t matter, I suggest explicitly sorting the return values in Rust code. |
@varasev Parity will call Can |
@DemiMarie We have the issue #49. As far as I understand, you implemented this in #53. The question is: For example,
Then imagine that at some block it returns the same set but in another order:
Will it be considered by Parity as a new set according to #49? |
They are indeed read from the contract in order. And However, there is currently no code that tries to detect validator set changes at all, because there's nothing in Aura that's triggered by them: Calling let is_epoch_begin = chain.epoch_transition(best_header.number(), h).is_some(); However, This comment and early return I don't understand at all: I think we always need to care for epochs?? For some reason, So back to the store of pending transitions: These are also passed in by the caller, and in this case use So: My guess is that we're calling |
Exactly, the The docs on https://wiki.parity.io/Validator-Set.html say that finalizeChange And finalizeChange I repeat here just in case what I wrote in our Slack channel: According to Parity docs and AFAIK the
According to #49 all we need to do is to use I implemented the next fix in the contracts: #71 (comment) In my implementation, the order of validators returned by If The contracts expect that the different order of the same set of validators in I asked the question #71 (comment) to make sure that Parity will re-apply the inner set of validators and call |
Yes, that's the problem: Every block with an |
@afck I have not done tests, but from reading the code, it seems clear that Is there some reason that we cannot just use the |
We can't use |
Isn't that the old problem with the log events: that we're currently making the call that initiates the validator set change as a system call and not a transaction, so that it can't log events? Would it be feasible to compare the returned validator list with the existing one here, and return (Edit: Ninja'd by three seconds! 😁) |
Another thought: can we make |
@afck I can try to figure out where to find the existing one. It is feasible if and only if I can find the old validator set. |
@DemiMarie It would be easier if we just used The main thing is that the contract expects that |
So, the algorithm must be the next, I think:
|
@varasev is it okay for |
That way, I can just write a |
We already have such a flag:
Parity should request and get the updated validator set in two cases:
The algorithm with Do you have a better idea? |
changeRequestCount()
getter instead of getPendingValidators()
changeRequestCount()
getter along with getPendingValidators()
@varasev |
Ok, we can go another way: Each validator will call The contracts set So, all the validator has to do for this in Parity code is to send a regular transaction with zero gas price for calling
|
changeRequestCount()
getter along with getPendingValidators()
emitInitiateChange
function by validator
@varasev is it harmful to call |
@varasev does that mean that I can revert the changes in Parity about not using |
I've just added
Yes, we should revert all the changes made within #49. |
@varasev Can |
@DemiMarie Yes, in the case when there is nothing to do, We could replace function emitInitiateChange() external {
require(isValidator(msg.sender));
require(emitInitiateChangeCallable());
(address[] memory newSet, bool newStakingEpoch) = _dequeuePendingValidators();
if (newSet.length > 0) {
emit InitiateChange(blockhash(block.number - 1), newSet);
_setInitiateChangeAllowed(false);
_setQueueValidators(newSet, newStakingEpoch);
}
} In this case the function will |
That would be great: We wouldn't need to change the epoch transition code. 👍
(So: Maybe this approach just works, and is easiest to implement; but we need to dig through the Parity code to make sure these three points are fine.) |
I think there is nothing wrong if the calling of
Yes, it's better to make the call in
Ideally yes, it's a good idea. But if the current validator doesn't call |
@varasev My understanding is that somebody needs to call |
Actually, we don't need the next condition: https://github.com/poanetwork/pos-contracts/blob/ca0b98040ed9d04b52b1ceabd2c6adc60d123d63/contracts/abstracts/ValidatorSetBase.sol#L93 I removed that: poanetwork/posdao-contracts@19a4136 So, now anybody (not only validator) can call
The |
Right, so for now we should just make a constant call to (*) I still suspect that this is an unnecessary indirection and there's probably a more direct way to add the transaction to the current open block without adding it to the queue, but I haven't quite figured that out yet. I added my thoughs as #75. |
It is now called by the new method `ValidatorSet::on_new_block()`. Closes #71
Fixed. |
It is now called by the new method `ValidatorSet::on_new_block()`. Closes #71
It is now called by the new method `ValidatorSet::on_new_block()`. Closes #71
It is now called by the new method `ValidatorSet::on_new_block()`. Closes #71
It is now called by the new method `ValidatorSet::on_new_block()`. Closes #71
It is now called by the new method `ValidatorSet::on_new_block()`. Closes #71
It is now called by the new method `ValidatorSet::on_new_block()`. Closes #71
It is now called by the new method `ValidatorSet::on_new_block()`. Closes #71
It is now called by the new method `ValidatorSet::on_new_block()`. Closes #71
It is now called by the new method `ValidatorSet::on_new_block()`. Closes #71
(related to #49)
I've missed one detail:
There can be a case when the validator set is not changed at the beginning of new staking epoch (due to delegators did nothing during the finished staking epoch).
The
getPendingValidators()
getter will return the same set in that case, and as a result, thefinalizeChange()
function won't be called by Parity (because the set wasn't changed).But we need to call
finalizeChange()
anyway when the new staking epoch begins.Can we use the
changeRequestCount()
getter instead ofgetPendingValidators()
? Its value is incremented each time when the set of validators is changed or when the new staking epoch begins.The text was updated successfully, but these errors were encountered: