Skip to content
This repository has been archived by the owner on Jul 27, 2022. It is now read-only.

Problem (Fix #1142): revised punishment mechanisms not implemented #1292

Merged
merged 1 commit into from
Mar 30, 2020

Conversation

yihuang
Copy link
Collaborator

@yihuang yihuang commented Mar 24, 2020

Solution:

  • revised staking and punishment implementation

This change is Reviewable

@codecov
Copy link

codecov bot commented Mar 24, 2020

Codecov Report

Merging #1292 into master will decrease coverage by 0.37%.
The diff coverage is 87.55%.

@@            Coverage Diff            @@
##           master   #1292      +/-   ##
=========================================
- Coverage   63.97%   63.6%   -0.38%     
=========================================
  Files         154     152       -2     
  Lines       20876   20680     -196     
=========================================
- Hits        13356   13153     -203     
- Misses       7520    7527       +7
Impacted Files Coverage Δ
chain-core/src/lib.rs 91.66% <ø> (-8.34%) ⬇️
client-cli/src/command.rs 0% <0%> (ø) ⬆️
chain-abci/src/app/query.rs 60.58% <0%> (+3.73%) ⬆️
chain-abci/tests/abci_app.rs 94.89% <100%> (-0.14%) ⬇️
chain-abci/src/app/end_block.rs 100% <100%> (ø) ⬆️
test-common/src/chain_env.rs 94.27% <100%> (+0.12%) ⬆️
...work/src/network_ops/default_network_ops_client.rs 75.79% <100%> (-0.01%) ⬇️
chain-abci/src/app/rewards.rs 98.29% <100%> (-0.08%) ⬇️
chain-core/src/init/config.rs 78.09% <100%> (+3.53%) ⬆️
chain-abci/tests/punishment.rs 100% <100%> (ø) ⬆️
... and 34 more

Copy link
Contributor

@tomtau tomtau left a comment

Choose a reason for hiding this comment

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

looks good -- still a big PR, but more manageable. For the big PR, I prefer using reviewable, as it's easier for tracking changes across revisions etc., so for the comments you can reply there: https://reviewable.io/reviews/crypto-com/chain/1292#-

Reviewed 34 of 34 files at r1, 13 of 13 files at r2.
Reviewable status: all files reviewed, 20 unresolved discussions (waiting on @calvinaco, @devashishdxt, @leejw51crypto, @linfeng-crypto, and @yihuang)


chain-abci/src/staking_table.rs, line 8 at r1 (raw file):

use parity_scale_codec::{Decode, Encode};
#[cfg(not(feature = "mesalock_sgx"))]

is this needed? chain-abci doesn't have this feature?


chain-abci/src/staking_table.rs, line 35 at r1 (raw file):

#[derive(Error, Debug)]
pub enum UnjailError {

NIT: perhaps all these data types can be put in some "publictx_error" module?


chain-abci/src/staking_table.rs, line 94 at r1 (raw file):

/// Invarient 2.2:
///   All the secondary indexes should be partial index with condition `validator is not null`
///   So there is no nothing-at-stake risk here, because there is a cost to become validator.

"nothing-at-stake" generally refers to the consensus attack where a validator signs on multiple forks -- whereas here, at least according to that older PR, it's just saying "this shouldn't be prone to DoS as long as minimum required stake is high enough".
it can be rephrased as in that explanatory GitHub comment, otherwise the text is a bit misleading.

and it's not that "there is no risk" -- if my understanding of that comment is correct, there could be risk if it's say Coin::one(). It'd ideally be quantified and also put in documentation (perhaps to the rustdoc near that network parameter)


chain-abci/src/staking_table.rs, line 105 at r1 (raw file):

///   Proof: always update index when related validator fields changed.
#[derive(Clone, Debug, Default, Encode, Decode)]
#[cfg_attr(not(feature = "mesalock_sgx"), derive(Serialize, Deserialize))]

not needed, as this feature isn't in abci? is Deserialize needed?


chain-abci/src/staking_table.rs, line 108 at r1 (raw file):

pub struct StakingTable {
    // Selected validator voting powers of last executed end block
    pub validator_snapshot: BTreeMap<StakedStateAddress, TendermintVotePower>,

does this need to be pub, is it for serde auto-derives? for enforcing the invariants in the comment (if this is in some &mut context), it may be better to hide it (if it's for serde json serialize, there may be some annotation?)?


chain-abci/src/staking_table.rs, line 123 at r1 (raw file):

impl StakingTable {
    /// Init with genesis stakings, panic if:

NIT: for rustdoc https://rust-lang.github.io/api-guidelines/documentation.html#function-docs-include-error-panic-and-safety-considerations-c-failure


chain-abci/src/staking_table.rs, line 143 at r1 (raw file):

    }

    /// After restored from storage, call initialize to populate the indexes

maybe a TODO to move this to be called automatically in Decode?


chain-abci/src/staking_table.rs, line 162 at r1 (raw file):

    }

    /// Handle abci begin_block event

just a comment here whether this is also expected to handle rewards later when the revised implementation is added?


chain-abci/src/staking_table.rs, line 259 at r1 (raw file):

                    block_time,
                    block_height,
                    &mut staking,

instead of having this slashing-related update in two places, it'll be better to unify it. e.g. instead of self.slash(...), there'll be computer_slash_amount (that doesn't take &mut staking) and do everything here or do everything in `.slash(...)


chain-abci/src/staking_table.rs, line 296 at r1 (raw file):

    /// Handle `NodeJoinTx`
    pub fn node_join(

these tx handlers can be perhaps put in separate modules/files where they can be a bit expanded for legibility -- for example, instead of this if-else nesting, it could just have a helper something like check_inactive_validator(...) -> Result<&mut Validator, PublicTxError> (probably not exactly)


chain-abci/src/staking_table.rs, line 392 at r1 (raw file):

            }
        } else {
            Err(UnjailError::NotJailed.into())

is this the right error in this branch (Validator is None?)


chain-abci/src/staking_table.rs, line 396 at r1 (raw file):

    }

    /// Handle reward statistics record

still the old one TODO comment?


chain-abci/src/staking_table.rs, line 451 at r1 (raw file):

            remainder = (remainder - amount).unwrap();
            distributed.push((addr, amount));
            self.add_bonded(amount, &mut staking).unwrap();

again the update add_bonded + inc_nonce can be together


chain-abci/src/staking_table.rs, line 881 at r1 (raw file):

}

/// Return success or not

returns success if less than max bound?


chain-abci/src/app/app_init.rs, line 46 at r1 (raw file):

    /// time in current block's header or genesis time, set in begin block
    pub block_time: Timespec,
    /// time in current block's height or genesis time, set in begin block

nit: comment -- current block height or 0 for genesis?


chain-abci/src/app/app_init.rs, line 49 at r1 (raw file):

    pub block_height: BlockHeight,
    /// Indexings of validator states
    pub staking_table: StakingTable,

should this be dumped by serde? currently this is in response to "info" request serialised in json


chain-abci/src/app/app_init.rs, line 61 at r1 (raw file):

}

impl NodeChecker for &ChainNodeState {

FYI to myself -- check if nodechecker trait was removed


chain-abci/src/app/app_init.rs, line 174 at r1 (raw file):

    mut req_validators: Vec<ValidatorUpdate>,
    distribution: &BTreeMap<RedeemAddress, (StakedStateDestination, Coin)>,
) -> bool {

prefer Result<(),()> if no need to return anything (bool is ambiguous as one doesn't know if true means "yes, it's correct" or "yes, it's invalid")


chain-abci/src/app/mod.rs, line 234 at r1 (raw file):

            }
            Err(msg) => {
                resp.set_code(1);

BTW, I guess it'll be useful to assign 1,2,3,4... to that error enum and set it here for #1293 (and perhaps in checktx)


chain-abci/src/app/validate_tx.rs, line 64 at r1 (raw file):

#[derive(thiserror::Error, Debug)]
pub enum PublicTxError {

nit: this could be in that error module with those other error types


chain-abci/tests/tx_validation.rs, line 174 at r1 (raw file):

}

struct NodeInfoWrap(

is this used for anything?

before this was a mock for isolating out the storage in validation testing -- seems no longer relevant?


chain-tx-validation/src/lib.rs, line 373 at r1 (raw file):

/// Verifies if the account is unjailed
pub fn verify_unjailed(account: &StakedState) -> Result<(), Error> {

is this used given those custom errors / validations in staking_table?

@tomtau
Copy link
Contributor

tomtau commented Mar 24, 2020

bors try

bors bot added a commit that referenced this pull request Mar 24, 2020
@bors
Copy link
Contributor

bors bot commented Mar 24, 2020

try

Build failed

Copy link
Collaborator Author

@yihuang yihuang left a comment

Choose a reason for hiding this comment

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

Reviewable status: all files reviewed, 18 unresolved discussions (waiting on @calvinaco, @devashishdxt, @leejw51crypto, @linfeng-crypto, and @tomtau)


chain-abci/src/staking_table.rs, line 8 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

is this needed? chain-abci doesn't have this feature?

Done.


chain-abci/src/staking_table.rs, line 35 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

NIT: perhaps all these data types can be put in some "publictx_error" module?

Will split it up into: tx, types, abci_events


chain-abci/src/staking_table.rs, line 94 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

"nothing-at-stake" generally refers to the consensus attack where a validator signs on multiple forks -- whereas here, at least according to that older PR, it's just saying "this shouldn't be prone to DoS as long as minimum required stake is high enough".
it can be rephrased as in that explanatory GitHub comment, otherwise the text is a bit misleading.

and it's not that "there is no risk" -- if my understanding of that comment is correct, there could be risk if it's say Coin::one(). It'd ideally be quantified and also put in documentation (perhaps to the rustdoc near that network parameter)

Done, changed to "this shouldn't be prone to DoS as long as minimum required stake is high enough"


chain-abci/src/staking_table.rs, line 105 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

not needed, as this feature isn't in abci? is Deserialize needed?

I think both serialize, deserialize is not needed here, if we don't need it to be queried by abci_query state


chain-abci/src/staking_table.rs, line 108 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

does this need to be pub, is it for serde auto-derives? for enforcing the invariants in the comment (if this is in some &mut context), it may be better to hide it (if it's for serde json serialize, there may be some annotation?)?

Will remove it and add a method.


chain-abci/src/staking_table.rs, line 123 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

NIT: for rustdoc https://rust-lang.github.io/api-guidelines/documentation.html#function-docs-include-error-panic-and-safety-considerations-c-failure

Done


chain-abci/src/staking_table.rs, line 143 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

maybe a TODO to move this to be called automatically in Decode?

It can't be called in Decode because of extra parameters.


chain-abci/src/staking_table.rs, line 162 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

just a comment here whether this is also expected to handle rewards later when the revised implementation is added?

Will extra the internal into separated methods.


chain-abci/src/staking_table.rs, line 259 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

instead of having this slashing-related update in two places, it'll be better to unify it. e.g. instead of self.slash(...), there'll be computer_slash_amount (that doesn't take &mut staking) and do everything here or do everything in `.slash(...)

Do you mean split slash into two methods or?


chain-abci/src/staking_table.rs, line 296 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

these tx handlers can be perhaps put in separate modules/files where they can be a bit expanded for legibility -- for example, instead of this if-else nesting, it could just have a helper something like check_inactive_validator(...) -> Result<&mut Validator, PublicTxError> (probably not exactly)

Will split up staking_table into several modules.
Both validator.is_some() and validator.is_none() are legitimate branches, the former is re-join, the latter is fresh join.


chain-abci/src/staking_table.rs, line 392 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

is this the right error in this branch (Validator is None?)

Clean staking can be considered as a not jailed staking I think.


chain-abci/src/staking_table.rs, line 396 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

still the old one TODO comment?

Done.


chain-abci/src/staking_table.rs, line 451 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

again the update add_bonded + inc_nonce can be together

I don't think they should be together, because nonce increment should stick to operation, an operation might modify bonded multiple times, nonce should increase only once.


chain-abci/src/staking_table.rs, line 881 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

returns success if less than max bound?

Changed into

/// Return out of date addresses if success (not exceeds max bound),
/// otherwise None

chain-abci/src/app/app_init.rs, line 46 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

nit: comment -- current block height or 0 for genesis?

Done


chain-abci/src/app/app_init.rs, line 49 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

should this be dumped by serde? currently this is in response to "info" request serialised in json

skip it for serde now.


chain-abci/src/app/app_init.rs, line 174 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

prefer Result<(),()> if no need to return anything (bool is ambiguous as one doesn't know if true means "yes, it's correct" or "yes, it's invalid")

Done.


chain-abci/src/app/validate_tx.rs, line 64 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

nit: this could be in that error module with those other error types

Will split it up.


chain-abci/tests/tx_validation.rs, line 174 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

is this used for anything?

before this was a mock for isolating out the storage in validation testing -- seems no longer relevant?

It's still used in this testing module, maybe it should be cleaned up, but there are dozens of places need to change.


chain-tx-validation/src/lib.rs, line 373 at r1 (raw file):

Previously, tomtau (Tomas Tauber) wrote…

is this used given those custom errors / validations in staking_table?

It's used by enclave tx processing, the Error is for enclave tx error.
The whole chain-tx-validation enclave only concerns about enclave tx processing.

@yihuang yihuang force-pushed the issue1142 branch 2 times, most recently from 6381d48 to cf5d7b8 Compare March 25, 2020 06:40
@yihuang
Copy link
Collaborator Author

yihuang commented Mar 25, 2020

  • Added chain-abci/src/tx_error.rs
  • Splited staking_table.rs into staking/mod.rs, staking/tx.rs, staking/table.rs.

The integration tests failure seems to be occasional, didn't reproduce locally, will be solved by #1293.

The nonce mismatch error in integration tests happens quite frequently currently, like 50% chance.

@yihuang yihuang requested a review from tomtau March 25, 2020 06:49
Copy link
Contributor

@tomtau tomtau left a comment

Choose a reason for hiding this comment

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

👍

Reviewed 16 of 16 files at r3.
Reviewable status: all files reviewed, 4 unresolved discussions (waiting on @calvinaco, @devashishdxt, @linfeng-crypto, @tomtau, and @yihuang)


chain-abci/src/staking_table.rs, line 259 at r1 (raw file):

Previously, yihuang (yihuang) wrote…

Do you mean split slash into two methods or?

I meant doing the mutation in one place


chain-abci/src/staking_table.rs, line 451 at r1 (raw file):

Previously, yihuang (yihuang) wrote…

I don't think they should be together, because nonce increment should stick to operation, an operation might modify bonded multiple times, nonce should increase only once.

it'd increase multiple times, as the resulting amount may be the same (but other things may change), so would require double-checking the tx

@yihuang
Copy link
Collaborator Author

yihuang commented Mar 25, 2020

chain-abci/src/staking_table.rs, line 451 at r1 (raw file):

Previously, yihuang (yihuang) wrote…

I don't think they should be together, because nonce increment should stick to operation, an operation might modify bonded multiple times, nonce should increase only once.

it'd increase multiple times, as the resulting amount may be the same (but other things may change), so would require double-checking the tx

For example, unbond tx will mutate staking at several places (unbounded, bonded, unbonded_from), the nonce should increase once or multiple times?

Also byzantine punishment will jail and slash, currently, nonce only increases once for the whole operation.

Copy link
Contributor

@tomtau tomtau left a comment

Choose a reason for hiding this comment

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

:lgtm:

Reviewed 2 of 2 files at r4.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @calvinaco, @devashishdxt, @linfeng-crypto, and @yihuang)


chain-abci/src/staking_table.rs, line 451 at r1 (raw file):

Previously, yihuang (yihuang) wrote…

For example, unbond tx will mutate staking at several places (unbounded, bonded, unbonded_from), the nonce should increase once or multiple times?

Also byzantine punishment will jail and slash, currently, nonce only increases once for the whole operation.

that's a bit different

@tomtau
Copy link
Contributor

tomtau commented Mar 25, 2020

bors r+

bors bot added a commit that referenced this pull request Mar 25, 2020
1292: Problem (Fix #1142): revised punishment mechanisms not implemented r=tomtau a=yihuang

Solution:
- revised staking and punishment implementation

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/crypto-com/chain/1292)
<!-- Reviewable:end -->


Co-authored-by: yihuang <yi.codeplayer@gmail.com>
@bors
Copy link
Contributor

bors bot commented Mar 25, 2020

Build failed

@yihuang
Copy link
Collaborator Author

yihuang commented Mar 25, 2020

For the integration test failure, I added a temporary fix:

unbonded_from = rpc.staking.state(addr)['unbonded_from']
 print('Wait until unbonded_from', unbonded_from)
-wait_for_blocktime(rpc, unbonded_from)
+# FIXME add extra 5 seconds to prevent nonce contension, remove after #1293 fixed
+wait_for_blocktime(rpc, unbonded_from + 5)

bors bot added a commit that referenced this pull request Mar 25, 2020
1292: Problem (Fix #1142): revised punishment mechanisms not implemented r=tomtau a=yihuang

Solution:
- revised staking and punishment implementation

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/crypto-com/chain/1292)
<!-- Reviewable:end -->


1298: Problem (Fix #1296): sgx-cargo-1804-hw1 is not easy to run locally r=tomtau a=yihuang

Solution:
    - Move it into default pipeline

```
drone exec --trusted --include sgx-test
```

Co-authored-by: yihuang <yi.codeplayer@gmail.com>
@bors
Copy link
Contributor

bors bot commented Mar 25, 2020

Build failed (retrying...)

bors bot added a commit that referenced this pull request Mar 25, 2020
1292: Problem (Fix #1142): revised punishment mechanisms not implemented r=tomtau a=yihuang

Solution:
- revised staking and punishment implementation

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/crypto-com/chain/1292)
<!-- Reviewable:end -->


Co-authored-by: yihuang <yi.codeplayer@gmail.com>
@bors
Copy link
Contributor

bors bot commented Mar 25, 2020

Build failed

Copy link
Contributor

@tomtau tomtau left a comment

Choose a reason for hiding this comment

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

bors retry

Reviewed 6 of 6 files at r6.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @calvinaco, @devashishdxt, @linfeng-crypto, and @yihuang)

bors bot added a commit that referenced this pull request Mar 26, 2020
1292: Problem (Fix #1142): revised punishment mechanisms not implemented r=tomtau a=yihuang

Solution:
- revised staking and punishment implementation

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/crypto-com/chain/1292)
<!-- Reviewable:end -->


Co-authored-by: yihuang <yi.codeplayer@gmail.com>
@bors
Copy link
Contributor

bors bot commented Mar 26, 2020

Build failed

@yihuang yihuang force-pushed the issue1142 branch 3 times, most recently from 269528e to 050207b Compare March 27, 2020 03:54
@yihuang
Copy link
Collaborator Author

yihuang commented Mar 27, 2020

Modified nonce logic, local test has passed.

@tomtau
Copy link
Contributor

tomtau commented Mar 27, 2020

bors try

Copy link
Contributor

@tomtau tomtau left a comment

Choose a reason for hiding this comment

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

Reviewed 10 of 10 files at r7.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @calvinaco, @devashishdxt, @linfeng-crypto, and @yihuang)

bors bot added a commit that referenced this pull request Mar 27, 2020
@bors
Copy link
Contributor

bors bot commented Mar 27, 2020

try

Build failed

@yihuang
Copy link
Collaborator Author

yihuang commented Mar 27, 2020

I've tracked down the cause for the integration test failure, I think it's a bug in wallet sync, will be solved in #1316

@tomtau
Copy link
Contributor

tomtau commented Mar 27, 2020

bors r+

@bors
Copy link
Contributor

bors bot commented Mar 27, 2020

Merge conflict

…emented

Solution:
- revised staking and punishment implementation

Update the app_hash in devnet genesis

cleanup unused files

review suggestions

hide validator_snapshot

split up staking_table modules

extract punish from begin_block

add logs and fix nonce contension

Problem: nonce logic makes client difficult to handle

Solution:
- Make nonce to be the count of transactions sent from the staking address
Copy link
Contributor

@tomtau tomtau left a comment

Choose a reason for hiding this comment

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

bors retry

Reviewed 6 of 6 files at r8.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @calvinaco, @devashishdxt, @linfeng-crypto, and @yihuang)

@bors
Copy link
Contributor

bors bot commented Mar 30, 2020

@bors bors bot merged commit 0abf949 into crypto-com:master Mar 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants