Closed varasev closed 5 years ago
what if the last validator intentionally disconnects from the network at the end of staking epoch not to reveal his committed random number?
I'd say that also needs to be reported as misbehavior? I don't think we can even distinguish between disconnecting and just refusing to reveal.
We can't know if the validator wanted to disconnect intentionally or just lost connection, so I think the disconnection shouldn't be treated as misbehavior :thinking:
If he just lost connection and this is reported as misbehavior, the validator will be removed from the set (his stake and his stakers' stakes will be frozen for 3 months), but this seems to be too strict.
UPDATE: Considering that in AuRa the validators can launch more than one node, we assume that losing connection is an unlikely event. So, nonparticipation in revealing secret numbers due to node's disconnection will be treated by contracts as misbehavior.
I think making sure you have a stable connection is one of the responsibilities of a validator, and failure to do so should be punished. The question is to what extent, and whether we should have different kinds of penalties. (But I don't fully understand the economics behind the new contracts yet, so I'm not sure.)
I agree — with a caveat: Validators are individuals, and are generally non-technical people. They cannot be expected to maintain a complicated high-availability setup. Furthermore, they are likely connecting over residential internet with no SLA.
Unreliability should be punished far less severely than malicious behavior.
On Dec 12, 2018 9:47 AM, "Andreas Fackler" notifications@github.com wrote:
I think making sure you have a stable connection is one of the responsibilities of a validator, and failure to do so should be punished. The question is to what extent, and whether we should have different kinds of penalties.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/poanetwork/parity-ethereum/issues/51#issuecomment-446612805, or mute the thread https://github.com/notifications/unsubscribe-auth/AGGWByAPDOgE6Pnx-PEhVCkAUS2D182Cks5u4Rb2gaJpZM4ZPOJX .
Unreliability should be punished far less severely than malicious behavior.
That only works if there is not plausible way for a technically savvy entity to always mask their malicious behavior as unreliable behavior. If that's the case, only incompetent malicious nodes will ever be "caught" with a punishment worse as the "mild" one for being unreliable.
So I agree with @afck, we should err on the side of severe punishment. It's probably better to ensure that the punishment for manipulation is as mild as possible, while still being harsh enough to efficiently deter/prevent the unwanted behavior.
Edit: I just thought of a nice analogy, look how video games treat disconnects during ranked matches =).
The description was updated today :point_up_2: (the _signature
param was introduced for the commitHash
and revealSecret
functions).
The task above was simplified a bit:
A check whether or not a commit/reveal has already been made should be performed, as in the sections of the contract:
getCommit(collectRound, validator) == bytes32(0)
and
!sentReveal(collectRound, validator)
The second case (sentReveal(collectRound, validator)
) is complete, but I believe it would be beneficial to encode the fact that "commit equal 0 means no commit made yet" into a similar function isCommitted(collectRound, validator)
, which would perform said check. All this helps to avoid exposing contract internals to the clients.
As far as I understand it, we do not need the funds held in escrow like randao does, because the other validators will police potential culprits effectively?
So, breaking the changes down into bits:
null
-ish value here should disable the randomness feature.commitHash
and revealSecret
. The
precise procedure would be:
currentCollectRound()
to get the round number.isRevealPhase()
(and possibly isCommitPhase()
, for good measure)
to determine the phase.isCommitted()
/sentReveal()
; if true
skip the remaining steps.commitHash()
/revealSecret()
.it would be beneficial to encode the fact that "commit equal 0 means no commit made yet" into a similar function
isCommitted(collectRound, validator)
Ok, isCommitted
function has been added: https://github.com/poanetwork/pos-contracts/commit/8fd5c082132d448a8c0c70d1baf24728283ef2df
As far as I understand it, we do not need the funds held in escrow like randao does, because the other validators will police potential culprits effectively?
Right. The contracts will take care of it.
@mbr what instructions should we give validators, as far as ensuring that they have continuous service? The vast majority of individuals cannot afford, and do not have the knowledge to maintain, a true high-availability setup.
Can you give concrete expected availability numbers?
@DemiMarie We can recommend validators to launch more than one node (AuRa supports this) and separate them by different Internet providers (channels). E.g., for two validator's nodes: if one of the nodes disconnects, the second node will continue to work as a reserve.
@varasev That makes sense, though we will need to see how well that works in practice.
@DemiMarie It all depends on the punishment you are dishing out. You could come up with a scheme that allows some temporary "lapses", from something simple like a "three strikes and you're out" to something more sophisticated. I imagine that the implementation would take place in the smart contract though.
Since we decided that we can't use system transactions, we'll use service transactions
instead.
So, the functions commitHash
and revealSecret
must be called by regular transactions with zero gas price.
The functions' signatures and the description of this issue have been updated accordingly :point_up_2:
Some more ideas that probably don't work (feel free to ignore this, but if we can make something like this work, that would be great): I was trying to think of other ways in which we could avoid having to store any secret locally (so that we wouldn't have to store any additional information on disk just to avoid being punished if e.g. our node crashes and restarts). With our current approach, we do have a secret that we mustn't lose, and the commitment is the secret's hash.
pk, sk
is my key pair, in the commit round I would publish commit = encrypt(secret, pk)
. In the reveal phase, I would publish secret = decrypt(commit, sk)
. Unfortunately neither the sender's public key nor the necessary decryption function seem to be exposed to the smart contract.We could consider this in the future as an enhancement. For now, I think we shouldn't complicate things.
This is almost complete, except for rand_secret
being initialized to None
. That is tracked as #67, so I am closing this issue.
We have the
Random
contract for AuRa: https://github.com/poanetwork/pos-contracts/blob/master/contracts/RandomAuRa.solThere're several functions needed to generate random numbers in
randao
manner. This is how it should work for AuRa in our case:I propose to have so-called
collection rounds
. The length of each collection round is 200 blocks. Each collection round is split into two equal phases of 100 blocks:commits phase
andreveals phase
.Each phase is determined by the current block number: https://github.com/poanetwork/pos-contracts/blob/f7d080fbf5e16bd9b8cdb474bf9541bfe292c796/contracts/RandomAuRa.sol#L182-L188
In the
commits phase
validator's node must generate a random number, callcommitHash
function and pass thekeccak256
hash of the number. That must be done by each validator's nodeonly once
percommits phase
. E.g., if we have 10 validators, the function will be called only 10 times during thecommits phase
.The node can call
isCommitPhase()
function to know what's the current phase for the current block: https://github.com/poanetwork/pos-contracts/blob/f7d080fbf5e16bd9b8cdb474bf9541bfe292c796/contracts/RandomAuRa.sol#L182Then during the
reveals phase
each validator's node must callrevealSecret
function and pass the random number that was generated by the node earlier (during thecommits phase
). TherevealSecret
function must only be calledonce
duringreveals phase
.Once
reveals phase
is completed, the XORed random number is stored by the contract in a public array (max length of which is 20).Then the next
collection round
begins and so on.Totally, we will have 20 random numbers refreshed permanently several times a staking epoch (which duration is one week).
If we take 200 blocks as the length of
collection round
, there will be ~600collection rounds
per staking epoch which is more than enough to generate 20 random numbers during the staking epoch even if not all validators reveal their numbers sometimes.To implement the described mechanism we need to make Parity call those functions of
Random
contract with zero gas price.For AuRa the
ReportingValidatorSet
contract will deny making the changes in stakes for the last6 hours
of staking epoch so that the users couldn't manipulate the outcome in this case. The users will see the random numbers at the last blocks of staking epoch but won't be able to influence the outcome.UPDATE - the struck out things below
will beare implemented in contracts (not in Parity):We should consider it malicious behavior to not reveal (and to not commit), to make sure the last validator can't freely decide whether to reveal or not.So, if Parity discovers on the last block ofcommits phase
that a validator produced at least one block during thecommits phase
but didn't make a commit, this must be treated as misbehavior. The same is forreveals phase
: if Parity discovers on the last block ofreveals phase
that a validator produced at least one block during thereveals phase
but didn't make a reveal, this must be treated as misbehavior.An exception: if a validator didn't callcommitHash
orrevealSecret
during the first 400 blocks of new staking epoch, this shouldn't be treated as misbehavior because new validators need to have time to commit/reveal during the fullcollection round
.The contracts keep track of intentional nonparticipation in revealing secret numbers as described in the struck out sentences above. To reduce the risk of unintentional node's disconnection, we will recommend the validators to launch more than one node (AuRa supports this) and separate them by different Internet providers (channels).