Open DrZoltanFazekas opened 3 days ago
I believe an easy solution discussed was to apply the rewards as the first state change in the block. This would be a 1-line change (move the apply_rewards()
call inside execute_block()
up above the transaction execution section) and would effectively use the state of the previous block for the rewards and committee, before any of the current block's changes
We saw nodes panicking because they tried to unwrap
None
in https://github.com/Zilliqa/zq2/blob/main/zilliqa/src/consensus.rs#L677 to apply rewards of a staker whom we removed from the validator set through a transaction callingdeposit::tempRemoveStaker()
in the current block.https://github.com/Zilliqa/zq2/pull/1120 changes the way we determine the leader in
apply_rewards()
. It was based on the previous block and not the current block's state before: https://github.com/Zilliqa/zq2/blob/main/zilliqa/src/consensus.rs#L632-L634With this change we would pick a different leader for the current block in case the actual block proposer were removed from the validator set in the current block. I think this is wrong since the actual proposer was selected from the validator set based on the previous block's state before the current block was proposed. The fact that the current block's proposer is removed from the validator set in the current block should only have an impact on the leader selection of the subsequent blocks.
Related to that, there is another problem because we're trying to get the reward address of the leader in https://github.com/Zilliqa/zq2/blob/main/zilliqa/src/consensus.rs#L640 and the reward addresses of the cosigners in https://github.com/Zilliqa/zq2/blob/main/zilliqa/src/consensus.rs#L652 (which was the problem we ran into) based on the current block's state, but their
pub_key
does not exist anymore in the deposit contract's current state since our transaction executed in the current block removed it.As discussed, we would need to fetch the reward addresses based on the previous block's state in which the deposit contract had the respective
pub_key
before they were removed in the current block.