From 8239375013d825b69ef35b50093cc27c961e391f Mon Sep 17 00:00:00 2001 From: jiacheng Date: Tue, 15 Jan 2019 15:11:17 +0800 Subject: [PATCH 1/4] Add CheckValidNum to Context --- app/baseapp.go | 36 ++++++++++++++++++++++-------------- modules/slashing/tick.go | 17 +++++++++++++++++ types/context.go | 10 +++++++++- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/app/baseapp.go b/app/baseapp.go index 3c3dbf0c5..365a311b7 100644 --- a/app/baseapp.go +++ b/app/baseapp.go @@ -16,12 +16,12 @@ import ( "github.com/gogo/protobuf/proto" "github.com/irisnet/irishub/app/protocol" "github.com/irisnet/irishub/codec" + "github.com/irisnet/irishub/modules/auth" "github.com/irisnet/irishub/store" sdk "github.com/irisnet/irishub/types" "github.com/irisnet/irishub/version" tmstate "github.com/tendermint/tendermint/state" "strconv" - "github.com/irisnet/irishub/modules/auth" ) // Key to store the consensus params in the main store. @@ -74,6 +74,7 @@ type BaseApp struct { // flag for sealing sealed bool + } var _ abci.Application = (*BaseApp)(nil) @@ -85,10 +86,10 @@ var _ abci.Application = (*BaseApp)(nil) // Accepts variable number of option functions, which act on the BaseApp to set configuration choices func NewBaseApp(name string, logger log.Logger, db dbm.DB, options ...func(*BaseApp)) *BaseApp { app := &BaseApp{ - Logger: logger, - name: name, - db: db, - cms: store.NewCommitMultiStore(db), + Logger: logger, + name: name, + db: db, + cms: store.NewCommitMultiStore(db), } for _, option := range options { @@ -491,7 +492,7 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg // by InitChain. Context is now updated with Header information. app.deliverState.ctx = app.deliverState.ctx. WithBlockHeader(req.Header). - WithBlockHeight(req.Header.Height) + WithBlockHeight(req.Header.Height).WithCheckValidNum(0) } // add block gas meter @@ -511,6 +512,10 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg // set the signed validators for addition to context in deliverTx // TODO: communicate this result to the address to pubkey map in slashing app.voteInfos = req.LastCommitInfo.GetVotes() + + x := app.deliverState.ctx.CheckValidNum() + _ = x + return } @@ -523,12 +528,12 @@ func (app *BaseApp) CheckTx(txBytes []byte) (res abci.ResponseCheckTx) { // Decode the Tx. var result sdk.Result - var tx, err = app.txDecoder(txBytes) - if err != nil { - result = err.Result() - } else { - result = app.runTx(RunTxModeCheck, txBytes, tx) - } + //var tx, err = app.txDecoder(txBytes) + //if err != nil { + // result = err.Result() + //} else { + // result = app.runTx(RunTxModeCheck, txBytes, tx) + //} return abci.ResponseCheckTx{ Code: uint32(result.Code), @@ -548,7 +553,10 @@ func (app *BaseApp) DeliverTx(txBytes []byte) (res abci.ResponseDeliverTx) { if err != nil { result = err.Result() } else { + // success pass txDecoder + app.deliverState.ctx = app.deliverState.ctx.WithCheckValidNum(app.deliverState.ctx.CheckValidNum()+1) result = app.runTx(RunTxModeDeliver, txBytes, tx) + } // Even though the Result.Code is not OK, there are still effects, @@ -762,7 +770,6 @@ func (app *BaseApp) runTx(mode RunTxMode, txBytes []byte, tx sdk.Tx) (result sdk } }() - feePreprocessHandler := app.Engine.GetCurrentProtocol().GetFeePreprocessHandler() // run the fee handler if feePreprocessHandler != nil && ctx.BlockHeight() != 0 { @@ -790,7 +797,7 @@ func (app *BaseApp) runTx(mode RunTxMode, txBytes []byte, tx sdk.Tx) (result sdk return result } - newCtx.GasMeter().ConsumeGas(auth.BlockStoreCostPerByte * sdk.Gas(len(txBytes)), "blockstore") + newCtx.GasMeter().ConsumeGas(auth.BlockStoreCostPerByte*sdk.Gas(len(txBytes)), "blockstore") if !newCtx.IsZero() { // At this point, newCtx.MultiStore() is cache wrapped, @@ -827,6 +834,7 @@ func (app *BaseApp) runTx(mode RunTxMode, txBytes []byte, tx sdk.Tx) (result sdk // EndBlock implements the ABCI application interface. func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBlock) { + if app.deliverState.ms.TracingEnabled() { app.deliverState.ms = app.deliverState.ms.ResetTraceContext().(sdk.CacheMultiStore) } diff --git a/modules/slashing/tick.go b/modules/slashing/tick.go index ebca95bef..4f4374d07 100644 --- a/modules/slashing/tick.go +++ b/modules/slashing/tick.go @@ -40,3 +40,20 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) (tags return } + +// slashing begin block functionality +func EndBlocker(ctx sdk.Context,req abci.RequestEndBlock, sk Keeper) (tags sdk.Tags) { + + // Tag the height + heightBytes := make([]byte, 8) + binary.LittleEndian.PutUint64(heightBytes, uint64(req.Height)) + tags = sdk.NewTags("height", heightBytes) + + doubleSignSlashTag := sk.handleDoubleSign(ctx, + ctx.BlockHeader().ProposerAddress, + ctx.BlockHeight(), + ctx.BlockHeader().Time, + sk.validatorSet.ValidatorByConsAddr(ctx,(sdk.ConsAddress)(ctx.BlockHeader().ProposerAddress)).GetPower().RoundInt64()) + tags = tags.AppendTags(doubleSignSlashTag) + return +} \ No newline at end of file diff --git a/types/context.go b/types/context.go index 6517b4274..514f660a3 100644 --- a/types/context.go +++ b/types/context.go @@ -49,6 +49,7 @@ func NewContext(ms MultiStore, header abci.Header, isCheckTx bool, logger log.Lo c = c.WithGasMeter(NewInfiniteGasMeter()) c = c.WithMinimumFees(Coins{}) c = c.WithConsensusParams(nil) + c = c.WithCheckValidNum(0) return c } @@ -143,6 +144,7 @@ const ( contextKeyGasMeter contextKeyBlockGasMeter contextKeyMinimumFees + contextKeyCheckValidNum ) // NOTE: Do not expose MultiStore. @@ -159,7 +161,6 @@ func (c Context) BlockHeight() int64 { return c.Value(contextKeyBlockHeight).(in func (c Context) ConsensusParams() *abci.ConsensusParams { return c.Value(contextKeyConsensusParams).(*abci.ConsensusParams) } - func (c Context) ChainID() string { return c.Value(contextKeyChainID).(string) } func (c Context) TxBytes() []byte { return c.Value(contextKeyTxBytes).([]byte) } @@ -178,6 +179,9 @@ func (c Context) IsCheckTx() bool { return c.Value(contextKeyIsCheckTx).(bool) } func (c Context) MinimumFees() Coins { return c.Value(contextKeyMinimumFees).(Coins) } + +func (c Context) CheckValidNum() uint64 { return c.Value(contextKeyCheckValidNum).(uint64) } + func (c Context) WithMultiStore(ms MultiStore) Context { return c.withValue(contextKeyMultiStore, ms) } func (c Context) WithBlockHeader(header abci.Header) Context { @@ -207,6 +211,10 @@ func (c Context) WithConsensusParams(params *abci.ConsensusParams) Context { return c.withValue(contextKeyConsensusParams, params) } +func (c Context) WithCheckValidNum(checkValidNum uint64) Context { + return c.withValue(contextKeyCheckValidNum, checkValidNum) +} + func (c Context) WithChainID(chainID string) Context { return c.withValue(contextKeyChainID, chainID) } func (c Context) WithTxBytes(txBytes []byte) Context { return c.withValue(contextKeyTxBytes, txBytes) } From 3d867753ed8932dd35941e54ffd1916c88f32a2b Mon Sep 17 00:00:00 2001 From: jiacheng Date: Wed, 16 Jan 2019 10:00:58 +0800 Subject: [PATCH 2/4] Finish the handleProposerCensorship publishment --- app/baseapp.go | 27 ++++++++++------------- app/v0/protocol_v0.go | 4 ++-- modules/slashing/keeper.go | 44 ++++++++++++++++++++++++++++++++++++++ modules/slashing/tick.go | 12 +++++------ 4 files changed, 63 insertions(+), 24 deletions(-) diff --git a/app/baseapp.go b/app/baseapp.go index 365a311b7..ba2af5eba 100644 --- a/app/baseapp.go +++ b/app/baseapp.go @@ -74,7 +74,6 @@ type BaseApp struct { // flag for sealing sealed bool - } var _ abci.Application = (*BaseApp)(nil) @@ -86,10 +85,10 @@ var _ abci.Application = (*BaseApp)(nil) // Accepts variable number of option functions, which act on the BaseApp to set configuration choices func NewBaseApp(name string, logger log.Logger, db dbm.DB, options ...func(*BaseApp)) *BaseApp { app := &BaseApp{ - Logger: logger, - name: name, - db: db, - cms: store.NewCommitMultiStore(db), + Logger: logger, + name: name, + db: db, + cms: store.NewCommitMultiStore(db), } for _, option := range options { @@ -513,9 +512,6 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg // TODO: communicate this result to the address to pubkey map in slashing app.voteInfos = req.LastCommitInfo.GetVotes() - x := app.deliverState.ctx.CheckValidNum() - _ = x - return } @@ -528,12 +524,12 @@ func (app *BaseApp) CheckTx(txBytes []byte) (res abci.ResponseCheckTx) { // Decode the Tx. var result sdk.Result - //var tx, err = app.txDecoder(txBytes) - //if err != nil { - // result = err.Result() - //} else { - // result = app.runTx(RunTxModeCheck, txBytes, tx) - //} + var tx, err = app.txDecoder(txBytes) + if err != nil { + result = err.Result() + } else { + result = app.runTx(RunTxModeCheck, txBytes, tx) + } return abci.ResponseCheckTx{ Code: uint32(result.Code), @@ -554,7 +550,6 @@ func (app *BaseApp) DeliverTx(txBytes []byte) (res abci.ResponseDeliverTx) { result = err.Result() } else { // success pass txDecoder - app.deliverState.ctx = app.deliverState.ctx.WithCheckValidNum(app.deliverState.ctx.CheckValidNum()+1) result = app.runTx(RunTxModeDeliver, txBytes, tx) } @@ -813,7 +808,7 @@ func (app *BaseApp) runTx(mode RunTxMode, txBytes []byte, tx sdk.Tx) (result sdk if mode == RunTxModeCheck { return } - + app.deliverState.ctx = app.deliverState.ctx.WithCheckValidNum(app.deliverState.ctx.CheckValidNum() + 1) // Create a new context based off of the existing context with a cache wrapped // multi-store in case message processing fails. runMsgCtx, msCache := app.cacheTxContext(ctx, txBytes) diff --git a/app/v0/protocol_v0.go b/app/v0/protocol_v0.go index 87f9a2773..d0c774590 100644 --- a/app/v0/protocol_v0.go +++ b/app/v0/protocol_v0.go @@ -304,10 +304,10 @@ func (p *ProtocolV0) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) a // application updates every end block func (p *ProtocolV0) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { tags := gov.EndBlocker(ctx, p.govKeeper) - validatorUpdates := stake.EndBlocker(ctx, p.StakeKeeper) + tags = tags.AppendTags(slashing.EndBlocker(ctx, req, p.slashingKeeper)) tags = tags.AppendTags(service.EndBlocker(ctx, p.serviceKeeper)) tags = tags.AppendTags(upgrade.EndBlocker(ctx, p.upgradeKeeper)) - + validatorUpdates := stake.EndBlocker(ctx, p.StakeKeeper) p.assertRuntimeInvariants(ctx) return abci.ResponseEndBlock{ diff --git a/modules/slashing/keeper.go b/modules/slashing/keeper.go index 4ec03e238..3b43c8b43 100644 --- a/modules/slashing/keeper.go +++ b/modules/slashing/keeper.go @@ -174,6 +174,50 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p return } +// Punish proposer censorship by slashing malefactor's stake +func (k Keeper) handleProposalCensorship(ctx sdk.Context, addr crypto.Address, infractionHeight int64) (tags sdk.Tags) { + logger := ctx.Logger().With("module", "x/slashing") + time := ctx.BlockHeader().Time + consAddr := sdk.ConsAddress(addr) + pubkey, err := k.getPubkey(ctx, addr) + if err != nil { + panic(fmt.Sprintf("Validator consensus-address %v not found", consAddr)) + } + + // Get validator. + validator := k.validatorSet.ValidatorByConsAddr(ctx, consAddr) + if validator == nil || validator.GetStatus() == sdk.Unbonded { + // Defensive. + // Simulation doesn't take unbonding periods into account, and + // Tendermint might break this assumption at some point. + return + } + logger.Info(fmt.Sprintf("proposer censorship from %s at height %d", pubkey.Address(), infractionHeight)) + + + // Slash validator + // `power` is the int64 power of the validator as provided to/by + // Tendermint. This value is validator.Tokens as sent to Tendermint via + // ABCI, and now received as evidence. + // The revisedFraction (which is the new fraction to be slashed) is passed + // in separately to separately slash unbonding and rebonding delegations. + tags = k.validatorSet.Slash(ctx, consAddr,infractionHeight, validator.GetPower().RoundInt64(), sdk.NewDecWithPrec(5,2)) + + // Jail validator if not already jailed + if !validator.GetJailed() { + k.validatorSet.Jail(ctx, consAddr) + } + + // Set or updated validator jail duration + signInfo, found := k.getValidatorSigningInfo(ctx, consAddr) + if !found { + panic(fmt.Sprintf("Expected signing info for validator %s but not found", consAddr)) + } + signInfo.JailedUntil = time.Add(k.DoubleSignUnbondDuration(ctx)) + k.SetValidatorSigningInfo(ctx, consAddr, signInfo) + return +} + func (k Keeper) addPubkey(ctx sdk.Context, pubkey crypto.PubKey) { addr := pubkey.Address() k.setAddrPubkeyRelation(ctx, addr, pubkey) diff --git a/modules/slashing/tick.go b/modules/slashing/tick.go index 4f4374d07..035185647 100644 --- a/modules/slashing/tick.go +++ b/modules/slashing/tick.go @@ -49,11 +49,11 @@ func EndBlocker(ctx sdk.Context,req abci.RequestEndBlock, sk Keeper) (tags sdk.T binary.LittleEndian.PutUint64(heightBytes, uint64(req.Height)) tags = sdk.NewTags("height", heightBytes) - doubleSignSlashTag := sk.handleDoubleSign(ctx, - ctx.BlockHeader().ProposerAddress, - ctx.BlockHeight(), - ctx.BlockHeader().Time, - sk.validatorSet.ValidatorByConsAddr(ctx,(sdk.ConsAddress)(ctx.BlockHeader().ProposerAddress)).GetPower().RoundInt64()) - tags = tags.AppendTags(doubleSignSlashTag) + if int64(ctx.CheckValidNum()) < ctx.BlockHeader().NumTxs { + proposalCensorshipTag := sk.handleProposalCensorship(ctx, + ctx.BlockHeader().ProposerAddress, + ctx.BlockHeight()) + tags = tags.AppendTags(proposalCensorshipTag) + } return } \ No newline at end of file From 418c6235de7da08a5ff27f8093c5b2ca69c55f9e Mon Sep 17 00:00:00 2001 From: jiacheng Date: Thu, 17 Jan 2019 15:15:56 +0800 Subject: [PATCH 3/4] fix the comment --- app/baseapp.go | 4 ++- modules/slashing/keeper.go | 8 ++--- modules/slashing/params.go | 66 +++++++++++++++++++++++++++++++++++++- modules/slashing/tick.go | 4 +-- 4 files changed, 74 insertions(+), 8 deletions(-) diff --git a/app/baseapp.go b/app/baseapp.go index ba2af5eba..e82929a58 100644 --- a/app/baseapp.go +++ b/app/baseapp.go @@ -716,6 +716,8 @@ func (app *BaseApp) runTx(mode RunTxMode, txBytes []byte, tx sdk.Tx) (result sdk return err.Result() } + app.deliverState.ctx = app.deliverState.ctx.WithCheckValidNum(app.deliverState.ctx.CheckValidNum() + 1) + defer func() { if r := recover(); r != nil { switch rType := r.(type) { @@ -808,7 +810,7 @@ func (app *BaseApp) runTx(mode RunTxMode, txBytes []byte, tx sdk.Tx) (result sdk if mode == RunTxModeCheck { return } - app.deliverState.ctx = app.deliverState.ctx.WithCheckValidNum(app.deliverState.ctx.CheckValidNum() + 1) + // Create a new context based off of the existing context with a cache wrapped // multi-store in case message processing fails. runMsgCtx, msCache := app.cacheTxContext(ctx, txBytes) diff --git a/modules/slashing/keeper.go b/modules/slashing/keeper.go index 3b43c8b43..f027776b9 100644 --- a/modules/slashing/keeper.go +++ b/modules/slashing/keeper.go @@ -175,7 +175,7 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p } // Punish proposer censorship by slashing malefactor's stake -func (k Keeper) handleProposalCensorship(ctx sdk.Context, addr crypto.Address, infractionHeight int64) (tags sdk.Tags) { +func (k Keeper) handleProposerCensorship(ctx sdk.Context, addr crypto.Address, infractionHeight int64) (tags sdk.Tags) { logger := ctx.Logger().With("module", "x/slashing") time := ctx.BlockHeader().Time consAddr := sdk.ConsAddress(addr) @@ -194,14 +194,14 @@ func (k Keeper) handleProposalCensorship(ctx sdk.Context, addr crypto.Address, i } logger.Info(fmt.Sprintf("proposer censorship from %s at height %d", pubkey.Address(), infractionHeight)) - + distributionHeight := infractionHeight - stake.ValidatorUpdateDelay // Slash validator // `power` is the int64 power of the validator as provided to/by // Tendermint. This value is validator.Tokens as sent to Tendermint via // ABCI, and now received as evidence. // The revisedFraction (which is the new fraction to be slashed) is passed // in separately to separately slash unbonding and rebonding delegations. - tags = k.validatorSet.Slash(ctx, consAddr,infractionHeight, validator.GetPower().RoundInt64(), sdk.NewDecWithPrec(5,2)) + tags = k.validatorSet.Slash(ctx, consAddr, distributionHeight, validator.GetPower().RoundInt64(),k.SlashFractionCensorship(ctx)) // Jail validator if not already jailed if !validator.GetJailed() { @@ -213,7 +213,7 @@ func (k Keeper) handleProposalCensorship(ctx sdk.Context, addr crypto.Address, i if !found { panic(fmt.Sprintf("Expected signing info for validator %s but not found", consAddr)) } - signInfo.JailedUntil = time.Add(k.DoubleSignUnbondDuration(ctx)) + signInfo.JailedUntil = time.Add(k.CensorshipUnbondDuration(ctx)) k.SetValidatorSigningInfo(ctx, consAddr, signInfo) return } diff --git a/modules/slashing/params.go b/modules/slashing/params.go index 04362505e..36b14413c 100644 --- a/modules/slashing/params.go +++ b/modules/slashing/params.go @@ -26,6 +26,8 @@ var ( KeyDowntimeJailDuration = []byte("DowntimeJailDuration") KeySlashFractionDoubleSign = []byte("SlashFractionDoubleSign") KeySlashFractionDowntime = []byte("SlashFractionDowntime") + keySlashFractionCensorship = []byte("SlashFractionCensorship") + keyCensorshipJailDuration = []byte("CensorshipJailDuration") ) // ParamTypeTable for slashing module @@ -42,6 +44,8 @@ type Params struct { DowntimeJailDuration time.Duration `json:"downtime-unbond-duration"` SlashFractionDoubleSign sdk.Dec `json:"slash-fraction-double-sign"` SlashFractionDowntime sdk.Dec `json:"slash-fraction-downtime"` + SlashFractionCensorship sdk.Dec `json:"slash-fraction-censorship"` + CensorshipJailDuration time.Duration `json:"censorship-jail-duration"` } // Implements params.ParamStruct @@ -54,6 +58,8 @@ func (p *Params) KeyValuePairs() params.KeyValuePairs { {KeyDowntimeJailDuration, &p.DowntimeJailDuration}, {KeySlashFractionDoubleSign, &p.SlashFractionDoubleSign}, {KeySlashFractionDowntime, &p.SlashFractionDowntime}, + {keySlashFractionCensorship, &p.SlashFractionCensorship}, + {keyCensorshipJailDuration, &p.CensorshipJailDuration}, } } @@ -122,6 +128,24 @@ func (p *Params) Validate(key string, value string) (interface{}, sdk.Error) { return nil, err } return slashFractionDowntime, nil + case string(keySlashFractionCensorship): + slashFractionCensorship, err := sdk.NewDecFromStr(value) + if err != nil { + return nil, params.ErrInvalidString(value) + } + if err := validateSlashFractionCensorship(slashFractionCensorship); err != nil { + return nil, err + } + return slashFractionCensorship, nil + case string(keyCensorshipJailDuration): + censorshipJailDuration, err := time.ParseDuration(value) + if err != nil { + return nil, params.ErrInvalidString(value) + } + if err := validateCensorshipJailDuration(censorshipJailDuration); err != nil { + return nil, err + } + return censorshipJailDuration, nil default: return nil, sdk.NewError(params.DefaultCodespace, params.CodeInvalidKey, fmt.Sprintf("%s is not found", key)) } @@ -154,6 +178,12 @@ func (p *Params) StringFromBytes(cdc *codec.Codec, key string, bytes []byte) (st case string(KeySlashFractionDowntime): err := cdc.UnmarshalJSON(bytes, &p.SlashFractionDowntime) return p.SlashFractionDowntime.String(), err + case string(keySlashFractionCensorship): + err := cdc.UnmarshalJSON(bytes, &p.SlashFractionCensorship) + return p.SlashFractionCensorship.String(), err + case string(keyCensorshipJailDuration): + err := cdc.UnmarshalJSON(bytes, &p.CensorshipJailDuration) + return p.CensorshipJailDuration.String(), err default: return "", fmt.Errorf("%s is not existed", key) } @@ -169,6 +199,8 @@ func DefaultParams() Params { MinSignedPerWindow: sdk.NewDecWithPrec(5, 1), SlashFractionDoubleSign: sdk.NewDecWithPrec(1, 2), SlashFractionDowntime: sdk.NewDecWithPrec(5, 3), + SlashFractionCensorship: sdk.NewDecWithPrec(2, 2), + CensorshipJailDuration: 7 * sdk.Day, } } @@ -181,6 +213,8 @@ func DefaultParamsForTestnet() Params { MinSignedPerWindow: sdk.NewDecWithPrec(5, 1), SlashFractionDoubleSign: sdk.NewDec(1).Quo(sdk.NewDec(20)), SlashFractionDowntime: sdk.NewDec(1).Quo(sdk.NewDec(100)), + SlashFractionCensorship: sdk.NewDecWithPrec(2, 2), + CensorshipJailDuration: 60 * 7 * time.Second, } } @@ -210,7 +244,12 @@ func validateParams(p Params) sdk.Error { if err := validateSlashFractionDowntime(p.SlashFractionDowntime); err != nil { return err } - + if err := validateSlashFractionCensorship(p.SlashFractionCensorship); err != nil { + return err + } + if err := validateCensorshipJailDuration(p.CensorshipJailDuration); err != nil { + return err + } return nil } @@ -232,6 +271,13 @@ func validateJailDuration(p time.Duration) sdk.Error { return nil } +func validateCensorshipJailDuration(p time.Duration) sdk.Error { + if p <= 0 || p >= 4 * sdk.Week { + return sdk.NewError(params.DefaultCodespace, params.CodeInvalidSlashParams, fmt.Sprintf("Slash CensorshipJailDuration should be between (0, 4week) ", p.String())) + } + return nil +} + func validateSignedBlocksWindow(p int64) sdk.Error { if p < 100 || p > 140000 { return sdk.NewError(params.DefaultCodespace, params.CodeInvalidSlashParams, fmt.Sprintf("Slash SignedBlocksWindow [%d] should be between [100, 140000] ", p)) @@ -260,6 +306,12 @@ func validateSlashFractionDowntime(p sdk.Dec) sdk.Error { return nil } +func validateSlashFractionCensorship(p sdk.Dec) sdk.Error { + if p.LT(sdk.NewDecWithPrec(5, 3)) || p.GT(sdk.NewDecWithPrec(1, 1)) { + return sdk.NewError(params.DefaultCodespace, params.CodeInvalidSlashParams, fmt.Sprintf("Slash SlashFractionCensorship [%s] should be between [0.005, 0.1] ", p.String())) + } + return nil +} //______________________________________________________________________ // get inflation params from the global param store @@ -317,3 +369,15 @@ func (k Keeper) SlashFractionDowntime(ctx sdk.Context) (res sdk.Dec) { k.paramspace.Get(ctx, KeySlashFractionDowntime, &res) return } + +// SlashFractionDowntime - currently default 1% +func (k Keeper) SlashFractionCensorship(ctx sdk.Context) (res sdk.Dec) { + k.paramspace.Get(ctx, keySlashFractionCensorship, &res) + return +} + +// Downtime unbond duration +func (k Keeper) CensorshipUnbondDuration(ctx sdk.Context) (res time.Duration) { + k.paramspace.Get(ctx, keyCensorshipJailDuration, &res) + return +} \ No newline at end of file diff --git a/modules/slashing/tick.go b/modules/slashing/tick.go index 035185647..518b4e1db 100644 --- a/modules/slashing/tick.go +++ b/modules/slashing/tick.go @@ -41,7 +41,7 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) (tags return } -// slashing begin block functionality +// slashing end block functionality func EndBlocker(ctx sdk.Context,req abci.RequestEndBlock, sk Keeper) (tags sdk.Tags) { // Tag the height @@ -50,7 +50,7 @@ func EndBlocker(ctx sdk.Context,req abci.RequestEndBlock, sk Keeper) (tags sdk.T tags = sdk.NewTags("height", heightBytes) if int64(ctx.CheckValidNum()) < ctx.BlockHeader().NumTxs { - proposalCensorshipTag := sk.handleProposalCensorship(ctx, + proposalCensorshipTag := sk.handleProposerCensorship(ctx, ctx.BlockHeader().ProposerAddress, ctx.BlockHeight()) tags = tags.AppendTags(proposalCensorshipTag) From c6894198a8e35aea938b7da84eb3b9ac9bd6c46e Mon Sep 17 00:00:00 2001 From: jiacheng Date: Thu, 17 Jan 2019 17:06:42 +0800 Subject: [PATCH 4/4] go fmt --- app/baseapp.go | 2 +- modules/slashing/keeper.go | 4 ++-- modules/slashing/params.go | 39 ++++++++++++++++++----------------- modules/slashing/tick.go | 4 ++-- modules/stake/keeper/slash.go | 13 ++++++------ 5 files changed, 32 insertions(+), 30 deletions(-) diff --git a/app/baseapp.go b/app/baseapp.go index 8b090521b..d023fbd84 100644 --- a/app/baseapp.go +++ b/app/baseapp.go @@ -716,7 +716,7 @@ func (app *BaseApp) runTx(mode RunTxMode, txBytes []byte, tx sdk.Tx) (result sdk return err.Result() } - if mode == RunTxModeDeliver { + if mode == RunTxModeDeliver { app.deliverState.ctx = app.deliverState.ctx.WithCheckValidNum(app.deliverState.ctx.CheckValidNum() + 1) } diff --git a/modules/slashing/keeper.go b/modules/slashing/keeper.go index f027776b9..87d758d2a 100644 --- a/modules/slashing/keeper.go +++ b/modules/slashing/keeper.go @@ -5,9 +5,9 @@ import ( "time" "github.com/irisnet/irishub/codec" - sdk "github.com/irisnet/irishub/types" "github.com/irisnet/irishub/modules/params" stake "github.com/irisnet/irishub/modules/stake/types" + sdk "github.com/irisnet/irishub/types" "github.com/tendermint/tendermint/crypto" ) @@ -201,7 +201,7 @@ func (k Keeper) handleProposerCensorship(ctx sdk.Context, addr crypto.Address, i // ABCI, and now received as evidence. // The revisedFraction (which is the new fraction to be slashed) is passed // in separately to separately slash unbonding and rebonding delegations. - tags = k.validatorSet.Slash(ctx, consAddr, distributionHeight, validator.GetPower().RoundInt64(),k.SlashFractionCensorship(ctx)) + tags = k.validatorSet.Slash(ctx, consAddr, distributionHeight, validator.GetPower().RoundInt64(), k.SlashFractionCensorship(ctx)) // Jail validator if not already jailed if !validator.GetJailed() { diff --git a/modules/slashing/params.go b/modules/slashing/params.go index 36b14413c..1b9f38682 100644 --- a/modules/slashing/params.go +++ b/modules/slashing/params.go @@ -3,10 +3,10 @@ package slashing import ( "time" + "fmt" "github.com/irisnet/irishub/codec" "github.com/irisnet/irishub/modules/params" sdk "github.com/irisnet/irishub/types" - "fmt" "strconv" ) @@ -192,29 +192,29 @@ func (p *Params) StringFromBytes(cdc *codec.Codec, key string, bytes []byte) (st // Default parameters used by Iris Hub func DefaultParams() Params { return Params{ - MaxEvidenceAge: sdk.Day, - DoubleSignJailDuration: 5 * sdk.Day, - SignedBlocksWindow: 20000, - DowntimeJailDuration: 2 * sdk.Day, - MinSignedPerWindow: sdk.NewDecWithPrec(5, 1), + MaxEvidenceAge: sdk.Day, + DoubleSignJailDuration: 5 * sdk.Day, + SignedBlocksWindow: 20000, + DowntimeJailDuration: 2 * sdk.Day, + MinSignedPerWindow: sdk.NewDecWithPrec(5, 1), SlashFractionDoubleSign: sdk.NewDecWithPrec(1, 2), - SlashFractionDowntime: sdk.NewDecWithPrec(5, 3), + SlashFractionDowntime: sdk.NewDecWithPrec(5, 3), SlashFractionCensorship: sdk.NewDecWithPrec(2, 2), - CensorshipJailDuration: 7 * sdk.Day, + CensorshipJailDuration: 7 * sdk.Day, } } func DefaultParamsForTestnet() Params { return Params{ - MaxEvidenceAge: 10 * time.Minute, - DoubleSignJailDuration: 60 * 5 * time.Second, - SignedBlocksWindow: 100, - DowntimeJailDuration: 60 * 10 * time.Second, - MinSignedPerWindow: sdk.NewDecWithPrec(5, 1), + MaxEvidenceAge: 10 * time.Minute, + DoubleSignJailDuration: 60 * 5 * time.Second, + SignedBlocksWindow: 100, + DowntimeJailDuration: 60 * 10 * time.Second, + MinSignedPerWindow: sdk.NewDecWithPrec(5, 1), SlashFractionDoubleSign: sdk.NewDec(1).Quo(sdk.NewDec(20)), - SlashFractionDowntime: sdk.NewDec(1).Quo(sdk.NewDec(100)), + SlashFractionDowntime: sdk.NewDec(1).Quo(sdk.NewDec(100)), SlashFractionCensorship: sdk.NewDecWithPrec(2, 2), - CensorshipJailDuration: 60 * 7 * time.Second, + CensorshipJailDuration: 60 * 7 * time.Second, } } @@ -258,21 +258,21 @@ func validateMaxEvidenceAge(p time.Duration) sdk.Error { if p < sdk.Day { return sdk.NewError(params.DefaultCodespace, params.CodeInvalidSlashParams, fmt.Sprintf("Slash MaxEvidenceAge [%s] should be between [1day,) ", p.String())) } - } else if p < 10 * time.Minute { + } else if p < 10*time.Minute { return sdk.NewError(params.DefaultCodespace, params.CodeInvalidSlashParams, fmt.Sprintf("Slash MaxEvidenceAge [%s] should be between [10min,) ", p.String())) } return nil } func validateJailDuration(p time.Duration) sdk.Error { - if p <= 0 || p >= 4 * sdk.Week { + if p <= 0 || p >= 4*sdk.Week { return sdk.NewError(params.DefaultCodespace, params.CodeInvalidSlashParams, fmt.Sprintf("Slash DoubleSignJailDuration and DowntimeJailDuration [%s] should be between (0, 4week) ", p.String())) } return nil } func validateCensorshipJailDuration(p time.Duration) sdk.Error { - if p <= 0 || p >= 4 * sdk.Week { + if p <= 0 || p >= 4*sdk.Week { return sdk.NewError(params.DefaultCodespace, params.CodeInvalidSlashParams, fmt.Sprintf("Slash CensorshipJailDuration should be between (0, 4week) ", p.String())) } return nil @@ -312,6 +312,7 @@ func validateSlashFractionCensorship(p sdk.Dec) sdk.Error { } return nil } + //______________________________________________________________________ // get inflation params from the global param store @@ -380,4 +381,4 @@ func (k Keeper) SlashFractionCensorship(ctx sdk.Context) (res sdk.Dec) { func (k Keeper) CensorshipUnbondDuration(ctx sdk.Context) (res time.Duration) { k.paramspace.Get(ctx, keyCensorshipJailDuration, &res) return -} \ No newline at end of file +} diff --git a/modules/slashing/tick.go b/modules/slashing/tick.go index 518b4e1db..7e20c100c 100644 --- a/modules/slashing/tick.go +++ b/modules/slashing/tick.go @@ -42,7 +42,7 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) (tags } // slashing end block functionality -func EndBlocker(ctx sdk.Context,req abci.RequestEndBlock, sk Keeper) (tags sdk.Tags) { +func EndBlocker(ctx sdk.Context, req abci.RequestEndBlock, sk Keeper) (tags sdk.Tags) { // Tag the height heightBytes := make([]byte, 8) @@ -56,4 +56,4 @@ func EndBlocker(ctx sdk.Context,req abci.RequestEndBlock, sk Keeper) (tags sdk.T tags = tags.AppendTags(proposalCensorshipTag) } return -} \ No newline at end of file +} diff --git a/modules/stake/keeper/slash.go b/modules/stake/keeper/slash.go index 1cae045e9..2aaf931f0 100644 --- a/modules/stake/keeper/slash.go +++ b/modules/stake/keeper/slash.go @@ -3,8 +3,8 @@ package keeper import ( "fmt" - sdk "github.com/irisnet/irishub/types" "github.com/irisnet/irishub/modules/stake/types" + sdk "github.com/irisnet/irishub/types" ) const ( @@ -17,6 +17,7 @@ const ( // slash-validator-redelegation-[validatorAddrDst]-[validatorAddrSrc]-[delegatorAddr] SlashValidatorRedelegation = "slash-validator-redelegation-%s-%s-%s" ) + // Slash a validator for an infraction committed at a known height // Find the contributing stake at that height and burn the specified slashFactor // of it, updating unbonding delegation & redelegations appropriately @@ -114,7 +115,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh // cannot decrease balance below zero tokensToBurn := sdk.MinDec(remainingSlashAmount, validator.Tokens) tokensToBurn = sdk.MaxDec(tokensToBurn, sdk.ZeroDec()) // defensive. - tags = tags.AppendTag(fmt.Sprintf(SlashValidator, validator.OperatorAddr),[]byte(tokensToBurn.String())) + tags = tags.AppendTag(fmt.Sprintf(SlashValidator, validator.OperatorAddr), []byte(tokensToBurn.String())) // Deduct from validator's bonded tokens and update the validator. // The deducted tokens are returned to pool.LooseTokens. validator = k.RemoveValidatorTokens(ctx, validator, tokensToBurn) @@ -122,7 +123,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh panic("slash decimal token in redelegation") } k.bankKeeper.DecreaseLoosenToken(ctx, sdk.Coins{sdk.Coin{ - Denom: types.StakeDenom, + Denom: types.StakeDenom, Amount: tokensToBurn.TruncateInt(), }}) // Log that a slash occurred! @@ -187,10 +188,10 @@ func (k Keeper) slashUnbondingDelegation(ctx sdk.Context, unbondingDelegation ty // Update unbonding delegation if necessary if !unbondingSlashAmount.IsZero() { unbondingDelegation.Balance.Amount = unbondingDelegation.Balance.Amount.Sub(unbondingSlashAmount) - tags = tags.AppendTag(fmt.Sprintf(SlashUnbondindDelegation, unbondingDelegation.DelegatorAddr, unbondingDelegation.ValidatorAddr),[]byte(unbondingSlashAmount.String())) + tags = tags.AppendTag(fmt.Sprintf(SlashUnbondindDelegation, unbondingDelegation.DelegatorAddr, unbondingDelegation.ValidatorAddr), []byte(unbondingSlashAmount.String())) k.SetUnbondingDelegation(ctx, unbondingDelegation) k.bankKeeper.DecreaseLoosenToken(ctx, sdk.Coins{sdk.Coin{ - Denom: types.StakeDenom, + Denom: types.StakeDenom, Amount: unbondingSlashAmount, }}) } @@ -254,7 +255,7 @@ func (k Keeper) slashRedelegation(ctx sdk.Context, validator types.Validator, re } tags = tags.AppendTag(fmt.Sprintf(SlashValidatorRedelegation, redelegation.ValidatorDstAddr, redelegation.ValidatorSrcAddr, redelegation.DelegatorAddr), []byte(tokensToBurn.String())) k.bankKeeper.DecreaseLoosenToken(ctx, sdk.Coins{sdk.Coin{ - Denom: types.StakeDenom, + Denom: types.StakeDenom, Amount: tokensToBurn.TruncateInt(), }}) }