Stop slashing commitments with "forced errors"#1267
Conversation
wallet/src/repository/wallet/mod.rs
Outdated
|
|
||
| // Set not `in_consensus` reveals | ||
| for pkh in &tally.slashed_witnesses { | ||
| // TODO: Review that part for wallet guys (now out of consensus is no the same that slashed) |
There was a problem hiding this comment.
@mariocao, @aesedepece could you review that part?
There was a problem hiding this comment.
seems ok... maybe it could have some indirect consequence in the way non-conensus reveals are shown in Sheikah
There was a problem hiding this comment.
perfect, but in that case it could be solved in a little fix in the future if we notice that
src/cli/node/json_rpc_client.rs
Outdated
| None => format!(""), | ||
| Some(tally) => { | ||
| if tally.slashed_witnesses.contains(&pkh) { | ||
| // TODO: Need review by tmpolaczyk |
There was a problem hiding this comment.
This condition should be "if the witness was not rewarded". But now there are 3 possible outcomes, so we should re-think the dataRequestReport method.
The current behavior is:
- Honest: "+reward"
- Liar: red text "-0"
I propose:
- Honest: "+reward"
- Liar: red text "-0"
- Error: red text "+reward"
This way will be relatively simple to implement but it may be difficult for users to understand the difference, unless we explain all the consensus logic in dataRequestReport --help.
So yeah, we should add an additional case to this if. Will see if I can write a commit later.
There was a problem hiding this comment.
we consider an error if it is out of consensus and an error, so it should not have a reward. And I think we have to include -collateral for the liars?
There was a problem hiding this comment.
An error in consensus should be considered as honest
There was a problem hiding this comment.
And I think we have to include -collateral for the liars?
Currently, dataRequestReport never shows -collateral when you lose the collateral, but that would make sense.
There was a problem hiding this comment.
Proposal number 2:
- Honest: "+reward"
- Liar: red text "-collateral"
- Error: "+0"
There was a problem hiding this comment.
Proposal number 3:
- Honest: "+reward" "+rep"
- Liar: red text "-collateral"
- Error: "+reward"
Although I'm not sure if it is possible to get the amount of reputation that has been rewarded to witnesses.
| let collateral = if dr_output.collateral == 0 { | ||
| collateral_minimum | ||
| } else { | ||
| dr_output.collateral | ||
| }; |
There was a problem hiding this comment.
| let collateral = if dr_output.collateral == 0 { | |
| collateral_minimum | |
| } else { | |
| dr_output.collateral | |
| }; | |
| let collateral = max(collateral_minimum, dr_output.collateral); |
There was a problem hiding this comment.
That it is a different approach. We consider that if there are not a collateral value, we put the collateral minimum. But if the requester specify a quantity for collateral, and is less than minimum I think we shouldnt change and wait for the data request error in validation.
Maybe someone put 50_000 because he thinks is in wits and need a big amount of collateral, it is better that the request will be never included, and the requester notice his own error than publish the request with a very low value of collateral
| let collateral = if dr_state.data_request.collateral == 0 { | ||
| collateral_minimum | ||
| } else { | ||
| dr_state.data_request.collateral | ||
| }; |
There was a problem hiding this comment.
| let collateral = if dr_state.data_request.collateral == 0 { | |
| collateral_minimum | |
| } else { | |
| dr_state.data_request.collateral | |
| }; | |
| let collateral = max(dr_state.data_request.collateral, collateral_minimum); |
| for (pkh, result) in rep_info { | ||
| if result.lies > 0 { | ||
| liars.push((pkh, result.lies)); | ||
| // TODO: Decide which percentage would be fair enough |
There was a problem hiding this comment.
The behavior implemented in this PR is to only give reputation to nodes whose number of errors is smaller than the number of "honests".
This opens an attack vector where an attacker can flood the network with requests that always return errors, and nobody will be able to earn reputation except of course the attacker nodes, which will avoid participating in their own requests and will slowly accumulate all the reputation.
There was a problem hiding this comment.
This attack need several wits to pay the rewards, because witness will earn the wits unless they do not earn reputation. The other option, give reputation to error_committers could produce incentives for node operators to commit errors without the risk to lose reputation, but also wining it
There was a problem hiding this comment.
Currently if one identity commits one error and one "honest", it will not be rewarded any reputation. Maybe we can change the > into >= to be less aggressive.
There was a problem hiding this comment.
Should we open an issue to further assess which percentage would be fair enough?
88400a8 to
867e0d5
Compare
wallet/src/repository/wallet/mod.rs
Outdated
|
|
||
| // Set not `in_consensus` reveals | ||
| for pkh in &tally.slashed_witnesses { | ||
| // TODO: Review that part for wallet guys (now out of consensus is no the same that slashed) |
There was a problem hiding this comment.
seems ok... maybe it could have some indirect consequence in the way non-conensus reveals are shown in Sheikah
wallet/src/repository/wallet/mod.rs
Outdated
| // TODO: Review that part for wallet guys (now out of consensus is no the same that slashed) | ||
| for pkh in &tally.out_of_consensus { | ||
| let liar = reveals.get_mut(&pkh).cloned(); | ||
| if let Some(mut reveal) = liar { |
There was a problem hiding this comment.
| if let Some(mut reveal) = liar { | |
| if let Some(mut reveal) = outlier { |
There was a problem hiding this comment.
Now they are not considered dishonest but outliers to the consensus.
6383231 to
4838014
Compare
| let reveals_count = dr_state.info.reveals.len(); | ||
| let honests_count = commits_count - ta_tx.slashed_witnesses.len(); | ||
|
|
||
| let (liars_count, errors_count) = calculate_liars_and_errors_count_from_tally(&ta_tx); |
There was a problem hiding this comment.
This operation is only needed to calculate the extra_tally_fee. If we could refactor this function from accepting tally_transactions: &[TallyTransaction] into tally_transactions_and_fees: &[(TallyTransaction, u64)] we could skip this calculation.
But we would need to add that information to create_tally_transactions, and I'm not sure if this change will be small enough to be included in this PR :P
There was a problem hiding this comment.
uff, I want to merge as soon as possible, maybe we could open an issue to optimize some functions later
validations/src/validations.rs
Outdated
| reports_len: usize, | ||
| ) -> RadonReport<RadonTypes> { | ||
| // This TallyMetadata would be included in case of Error Result, in that case, anyone has to be | ||
| // classified as a lier, but as an error |
There was a problem hiding this comment.
| // classified as a lier, but as an error | |
| // classified not as a liar, but as an error | |
tmpolaczyk
left a comment
There was a problem hiding this comment.
Investigate issue with random_source.json:
[2020-06-09T11:20:38Z ERROR witnet_node::actors::chain_manager::mining] Error trying to mine a block: Invalid witness reward found: 1000001000. Expected value: 2000001000
Logs:
pr-1282-fail.zip
Fixed |
2724ebb to
176b8b2
Compare

This PR adds the next logic:
Close #1261