Skip to content

Stop slashing commitments with "forced errors"#1267

Merged
lrubiorod merged 2 commits intowitnet:masterfrom
lrubiorod:no_slash
Jun 11, 2020
Merged

Stop slashing commitments with "forced errors"#1267
lrubiorod merged 2 commits intowitnet:masterfrom
lrubiorod:no_slash

Conversation

@lrubiorod
Copy link
Contributor

@lrubiorod lrubiorod commented May 28, 2020

This PR adds the next logic:

  • If you commit a RadonError you can not be slashed
  • If you commit a RadonError and you are in consensus, you will earn the wits reward
  • If you commit more RadonErrors than normal values (truths) in an epoch, you will not earn reputation.

image
image

Close #1261

@aesedepece aesedepece changed the title no slash errors Stop slashing commitments with "forced errors" Jun 2, 2020
@lrubiorod lrubiorod marked this pull request as ready for review June 3, 2020 10:41

// 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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mariocao, @aesedepece could you review that part?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems ok... maybe it could have some indirect consequence in the way non-conensus reveals are shown in Sheikah

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perfect, but in that case it could be solved in a little fix in the future if we notice that

None => format!(""),
Some(tally) => {
if tally.slashed_witnesses.contains(&pkh) {
// TODO: Need review by tmpolaczyk
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tmpolaczyk could you review that part?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An error in consensus should be considered as honest

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proposal number 2:

  • Honest: "+reward"
  • Liar: red text "-collateral"
  • Error: "+0"

Copy link
Contributor

@tmpolaczyk tmpolaczyk Jun 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applied!!

Comment on lines +448 to +444
let collateral = if dr_output.collateral == 0 {
collateral_minimum
} else {
dr_output.collateral
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let collateral = if dr_output.collateral == 0 {
collateral_minimum
} else {
dr_output.collateral
};
let collateral = max(collateral_minimum, dr_output.collateral);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as before

for (pkh, result) in rep_info {
if result.lies > 0 {
liars.push((pkh, result.lies));
// TODO: Decide which percentage would be fair enough
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we open an issue to further assess which percentage would be fair enough?

@lrubiorod lrubiorod force-pushed the no_slash branch 2 times, most recently from 88400a8 to 867e0d5 Compare June 5, 2020 15:47
@lrubiorod lrubiorod requested a review from mariocao June 5, 2020 16:03

// 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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems ok... maybe it could have some indirect consequence in the way non-conensus reveals are shown in Sheikah

// 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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if let Some(mut reveal) = liar {
if let Some(mut reveal) = outlier {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now they are not considered dishonest but outliers to the consensus.

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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uff, I want to merge as soon as possible, maybe we could open an issue to optimize some functions later

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fine

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// classified as a lier, but as an error
// classified not as a liar, but as an error

Copy link
Contributor

@tmpolaczyk tmpolaczyk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@lrubiorod
Copy link
Contributor Author

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

@lrubiorod lrubiorod force-pushed the no_slash branch 2 times, most recently from 2724ebb to 176b8b2 Compare June 9, 2020 14:13
@lrubiorod lrubiorod requested a review from tmpolaczyk June 9, 2020 14:16
@lrubiorod lrubiorod merged commit d214529 into witnet:master Jun 11, 2020
@lrubiorod lrubiorod deleted the no_slash branch February 4, 2021 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Discussion RadonErrors slashing and implement a solution

4 participants