diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index b390e3841..34844974f 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -411,6 +411,12 @@ func handleQueryCustom(app *BaseApp, path []string, req abci.RequestQuery) (res // BeginBlock implements the ABCI application interface. func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeginBlock) { + fmt.Println( + cmn.Cyan( + fmt.Sprintf("BEGIN BLOCK #%v", req.Header.Height), + ), + ) + if app.cms.TracingEnabled() { app.cms.ResetTraceContext() app.cms.WithTracingContext(sdk.TraceContext( @@ -672,6 +678,12 @@ func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBloc res = app.endBlocker(app.deliverState.ctx, req) } + fmt.Println( + cmn.Cyan( + fmt.Sprintf("END BLOCK"), + ), + ) + return } diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 24b56d406..0d0fd0636 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -341,8 +341,9 @@ func (h Hooks) OnValidatorModified(ctx sdk.Context, addr sdk.ValAddress) { func (h Hooks) OnValidatorRemoved(ctx sdk.Context, addr sdk.ValAddress) { h.dh.OnValidatorRemoved(ctx, addr) } -func (h Hooks) OnValidatorBonded(ctx sdk.Context, addr sdk.ConsAddress) { - h.sh.OnValidatorBonded(ctx, addr) +func (h Hooks) OnValidatorBonded(ctx sdk.Context, addr sdk.ConsAddress, operator sdk.ValAddress) { + h.dh.OnValidatorBonded(ctx, addr, operator) + h.sh.OnValidatorBonded(ctx, addr, operator) } func (h Hooks) OnValidatorBeginUnbonding(ctx sdk.Context, addr sdk.ConsAddress, operator sdk.ValAddress) { h.dh.OnValidatorBeginUnbonding(ctx, addr, operator) diff --git a/cmd/gaia/app/sim_test.go b/cmd/gaia/app/sim_test.go index 630165cd0..d39edb91b 100644 --- a/cmd/gaia/app/sim_test.go +++ b/cmd/gaia/app/sim_test.go @@ -66,7 +66,7 @@ func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage { var delegations []stake.Delegation // XXX Try different numbers of initially bonded validators - numInitiallyBonded := int64(50) + numInitiallyBonded := int64(5) valAddrs := make([]sdk.ValAddress, numInitiallyBonded) for i := 0; i < int(numInitiallyBonded); i++ { valAddr := sdk.ValAddress(accs[i].Address) diff --git a/types/stake.go b/types/stake.go index 1818919ab..319dd470b 100644 --- a/types/stake.go +++ b/types/stake.go @@ -115,7 +115,7 @@ type StakingHooks interface { OnValidatorModified(ctx Context, address ValAddress) // Must be called when a validator's state changes OnValidatorRemoved(ctx Context, address ValAddress) // Must be called when a validator is deleted - OnValidatorBonded(ctx Context, address ConsAddress) // Must be called when a validator is bonded + OnValidatorBonded(ctx Context, address ConsAddress, operator ValAddress) // Must be called when a validator is bonded OnValidatorBeginUnbonding(ctx Context, address ConsAddress, operator ValAddress) // Must be called when a validator begins unbonding OnDelegationCreated(ctx Context, delAddr AccAddress, valAddr ValAddress) // Must be called when a delegation is created diff --git a/x/distribution/keeper/allocation.go b/x/distribution/keeper/allocation.go index debf0eb62..ddb351e4e 100644 --- a/x/distribution/keeper/allocation.go +++ b/x/distribution/keeper/allocation.go @@ -13,6 +13,7 @@ func (k Keeper) AllocateTokens(ctx sdk.Context, percentVotes sdk.Dec, proposer s // get the proposer of this block proposerValidator := k.stakeKeeper.ValidatorByConsAddr(ctx, proposer) + proposerDist := k.GetValidatorDistInfo(ctx, proposerValidator.GetOperator()) // get the fees which have been getting collected through all the diff --git a/x/distribution/keeper/hooks.go b/x/distribution/keeper/hooks.go index aeb394f26..f02b12b8d 100644 --- a/x/distribution/keeper/hooks.go +++ b/x/distribution/keeper/hooks.go @@ -23,8 +23,10 @@ func (k Keeper) onValidatorCreated(ctx sdk.Context, addr sdk.ValAddress) { // Withdrawal all validator rewards func (k Keeper) onValidatorModified(ctx sdk.Context, addr sdk.ValAddress) { - if err := k.WithdrawValidatorRewardsAll(ctx, addr); err != nil { - panic(err) + if ctx.BlockHeight() > 0 { + if err := k.WithdrawValidatorRewardsAll(ctx, addr); err != nil { + panic(err) + } } } @@ -52,6 +54,8 @@ func (k Keeper) onDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, func (k Keeper) onDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { + fmt.Printf("DELEGATION SHARES MODIFIED %v\n", valAddr) + if err := k.WithdrawDelegationReward(ctx, delAddr, valAddr); err != nil { panic(err) } @@ -87,9 +91,11 @@ func (h Hooks) OnValidatorRemoved(ctx sdk.Context, addr sdk.ValAddress) { h.k.onValidatorRemoved(ctx, addr) } func (h Hooks) OnDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { + h.k.onValidatorModified(ctx, valAddr) h.k.onDelegationCreated(ctx, delAddr, valAddr) } func (h Hooks) OnDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { + h.k.onValidatorModified(ctx, valAddr) h.k.onDelegationSharesModified(ctx, delAddr, valAddr) } func (h Hooks) OnDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { @@ -98,6 +104,6 @@ func (h Hooks) OnDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valA func (h Hooks) OnValidatorBeginUnbonding(ctx sdk.Context, _ sdk.ConsAddress, addr sdk.ValAddress) { h.k.onValidatorModified(ctx, addr) } - -// nolint - unused hooks for interface -func (h Hooks) OnValidatorBonded(ctx sdk.Context, addr sdk.ConsAddress) {} +func (h Hooks) OnValidatorBonded(ctx sdk.Context, _ sdk.ConsAddress, addr sdk.ValAddress) { + h.k.onValidatorModified(ctx, addr) +} diff --git a/x/distribution/types/validator_info.go b/x/distribution/types/validator_info.go index df1062e5c..9e122cb0c 100644 --- a/x/distribution/types/validator_info.go +++ b/x/distribution/types/validator_info.go @@ -46,6 +46,15 @@ func (vi ValidatorDistInfo) UpdateTotalDelAccum(height int64, totalDelShares sdk func (vi ValidatorDistInfo) TakeFeePoolRewards(fp FeePool, height int64, totalBonded, vdTokens, commissionRate sdk.Dec) (ValidatorDistInfo, FeePool) { + if vi.FeePoolWithdrawalHeight != height && !vdTokens.IsZero() { + fmt.Println( + cmn.Yellow( + fmt.Sprintf("TakeFeePoolRewards %v last: %v curr: %v pow: %v", + vi.OperatorAddr, vi.FeePoolWithdrawalHeight, height, vdTokens.String()), + ), + ) + } + fp = fp.UpdateTotalValAccum(height, totalBonded) if fp.TotalValAccum.Accum.IsZero() { diff --git a/x/mock/simulation/random_simulate_blocks.go b/x/mock/simulation/random_simulate_blocks.go index bccb42285..4c9b91d72 100644 --- a/x/mock/simulation/random_simulate_blocks.go +++ b/x/mock/simulation/random_simulate_blocks.go @@ -176,6 +176,12 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp, app.Commit() } + if header.ProposerAddress == nil { + fmt.Printf("\nSimulation stopped early as all validators have been unbonded, there is nobody left propose a block!\n") + stopEarly = true + break + } + // Generate a random RequestBeginBlock with the current validator set for the next block request = RandomRequestBeginBlock(r, validators, livenessTransitionMatrix, evidenceFraction, pastTimes, pastVoteInfos, event, header) @@ -227,7 +233,7 @@ func createBlockSimulator(testingMode bool, tb testing.TB, t *testing.T, event f assertAllInvariants(t, app, invariants, fmt.Sprintf("operation: %v", logUpdate), displayLogs) } if opCount%50 == 0 { - fmt.Printf("\rSimulating... block %d/%d, operation %d/%d. ", header.Height, totalNumBlocks, opCount, blocksize) + fmt.Printf("\rSimulating... block %d/%d, operation %d/%d. ", header.Height, totalNumBlocks, opCount, blocksize) } } opCount++ diff --git a/x/slashing/hooks.go b/x/slashing/hooks.go index 3ad08b864..ee794e203 100644 --- a/x/slashing/hooks.go +++ b/x/slashing/hooks.go @@ -6,7 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -func (k Keeper) onValidatorBonded(ctx sdk.Context, address sdk.ConsAddress) { +func (k Keeper) onValidatorBonded(ctx sdk.Context, address sdk.ConsAddress, _ sdk.ValAddress) { // Update the signing info start height or create a new signing info _, found := k.getValidatorSigningInfo(ctx, address) if !found { @@ -51,8 +51,8 @@ func (k Keeper) Hooks() Hooks { } // Implements sdk.ValidatorHooks -func (h Hooks) OnValidatorBonded(ctx sdk.Context, address sdk.ConsAddress) { - h.k.onValidatorBonded(ctx, address) +func (h Hooks) OnValidatorBonded(ctx sdk.Context, address sdk.ConsAddress, operator sdk.ValAddress) { + h.k.onValidatorBonded(ctx, address, operator) } // Implements sdk.ValidatorHooks diff --git a/x/slashing/hooks_test.go b/x/slashing/hooks_test.go index 5da7ebafb..eb7406764 100644 --- a/x/slashing/hooks_test.go +++ b/x/slashing/hooks_test.go @@ -11,7 +11,7 @@ import ( func TestHookOnValidatorBonded(t *testing.T) { ctx, _, _, _, keeper := createTestInput(t, DefaultParams()) addr := sdk.ConsAddress(addrs[0]) - keeper.onValidatorBonded(ctx, addr) + keeper.onValidatorBonded(ctx, addr, nil) period := keeper.getValidatorSlashingPeriodForHeight(ctx, addr, ctx.BlockHeight()) require.Equal(t, ValidatorSlashingPeriod{addr, ctx.BlockHeight(), 0, sdk.ZeroDec()}, period) } @@ -19,7 +19,7 @@ func TestHookOnValidatorBonded(t *testing.T) { func TestHookOnValidatorBeginUnbonding(t *testing.T) { ctx, _, _, _, keeper := createTestInput(t, DefaultParams()) addr := sdk.ConsAddress(addrs[0]) - keeper.onValidatorBonded(ctx, addr) + keeper.onValidatorBonded(ctx, addr, nil) keeper.onValidatorBeginUnbonding(ctx, addr, addrs[0]) period := keeper.getValidatorSlashingPeriodForHeight(ctx, addr, ctx.BlockHeight()) require.Equal(t, ValidatorSlashingPeriod{addr, ctx.BlockHeight(), ctx.BlockHeight(), sdk.ZeroDec()}, period) diff --git a/x/stake/genesis.go b/x/stake/genesis.go index 2fed87741..0e398e4a5 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -41,12 +41,13 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [ // Manually set indices for the first time keeper.SetValidatorByConsAddr(ctx, validator) keeper.SetValidatorByPowerIndex(ctx, validator, data.Pool) - + fmt.Println("stake.INITGENESIS", ctx.BlockHeight()) keeper.OnValidatorCreated(ctx, validator.OperatorAddr) } for _, delegation := range data.Bonds { keeper.SetDelegation(ctx, delegation) + fmt.Println("stake.INITGENESISd", ctx.BlockHeight()) keeper.OnDelegationCreated(ctx, delegation.DelegatorAddr, delegation.ValidatorAddr) } diff --git a/x/stake/handler.go b/x/stake/handler.go index 24cbee717..1d095f3f4 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -106,6 +106,8 @@ func handleMsgCreateValidator(ctx sdk.Context, msg types.MsgCreateValidator, k k k.SetValidatorByConsAddr(ctx, validator) k.SetNewValidatorByPowerIndex(ctx, validator) + k.OnValidatorCreated(ctx, validator.OperatorAddr) + // move coins from the msg.Address account to a (self-delegation) delegator account // the validator account and global shares are updated within here _, err = k.Delegate(ctx, msg.DelegatorAddr, msg.Delegation, validator, true) @@ -113,8 +115,6 @@ func handleMsgCreateValidator(ctx sdk.Context, msg types.MsgCreateValidator, k k return err.Result() } - k.OnValidatorCreated(ctx, validator.OperatorAddr) - tags := sdk.NewTags( tags.Action, tags.ActionCreateValidator, tags.DstValidator, []byte(msg.ValidatorAddr.String()), diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index a5d08d489..df5e22121 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -360,6 +360,7 @@ func (k Keeper) Delegate(ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.Co } // call the appropriate hook if present + //fmt.Printf("DELEGATION SHARES MODIFIED (2) FOUND OR NOT %v found: %v\n", validator.OperatorAddr, found) if found { k.OnDelegationSharesModified(ctx, delAddr, validator.OperatorAddr) } else { diff --git a/x/stake/keeper/hooks.go b/x/stake/keeper/hooks.go index 14eedb693..f8c0a6e07 100644 --- a/x/stake/keeper/hooks.go +++ b/x/stake/keeper/hooks.go @@ -23,9 +23,9 @@ func (k Keeper) OnValidatorRemoved(ctx sdk.Context, address sdk.ValAddress) { } } -func (k Keeper) OnValidatorBonded(ctx sdk.Context, address sdk.ConsAddress) { +func (k Keeper) OnValidatorBonded(ctx sdk.Context, address sdk.ConsAddress, operator sdk.ValAddress) { if k.hooks != nil { - k.hooks.OnValidatorBonded(ctx, address) + k.hooks.OnValidatorBonded(ctx, address, operator) } } diff --git a/x/stake/keeper/keeper.go b/x/stake/keeper/keeper.go index 26c686bc9..80aa27aea 100644 --- a/x/stake/keeper/keeper.go +++ b/x/stake/keeper/keeper.go @@ -78,7 +78,7 @@ func (k Keeper) GetLastTotalPower(ctx sdk.Context) (power sdk.Dec) { store := ctx.KVStore(k.storeKey) b := store.Get(LastTotalPowerKey) if b == nil { - panic("stored last total power should not have been nil") + return sdk.ZeroDec() } k.cdc.MustUnmarshalBinary(b, &power) return diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index cfa381973..c1f026079 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -9,6 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/stake/types" + cmn "github.com/tendermint/tendermint/libs/common" ) // Apply and return accumulated updates to the bonded validator set. Also, @@ -29,6 +30,8 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab maxValidators := k.GetParams(ctx).MaxValidators totalPower := int64(0) + fmt.Println(cmn.Cyan(fmt.Sprintf("BLOCK #%v ApplyAndReturnValidatorSetUpdates", ctx.BlockHeight()))) + // Retrieve the last validator set. // The persistent set is updated later in this function. // (see LastValidatorPowerKey). @@ -80,11 +83,24 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab // set validator power on lookup index. k.SetLastValidatorPower(ctx, operator, sdk.NewDec(newPower)) + fmt.Println( + cmn.Cyan( + fmt.Sprintf("SetLastValidatorPower %v pow: %v", + operator, newPower), + ), + ) } // validator still in the validator set, so delete from the copy delete(last, operatorBytes) + fmt.Println( + cmn.Cyan( + fmt.Sprintf("TOTAL ADD %v pow: %v", + operator, newPower), + ), + ) + // keep count count++ totalPower += newPower @@ -100,7 +116,9 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab validator := k.mustGetValidator(ctx, sdk.ValAddress(operator)) // bonded to unbonding + fmt.Println("!!!!") k.bondedToUnbonding(ctx, validator) + fmt.Println("!!!!2") // remove validator if it has no more tokens if validator.Tokens.IsZero() { @@ -108,7 +126,13 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab } // delete from the bonded validator index - k.DeleteLastValidatorPower(ctx, operator) + k.DeleteLastValidatorPower(ctx, sdk.ValAddress(operator)) + fmt.Println( + cmn.Cyan( + fmt.Sprintf("SetLastValidatorPower %v pow: 0", + sdk.ValAddress(operator)), + ), + ) // update the validator set updates = append(updates, validator.ABCIValidatorUpdateZero()) @@ -118,6 +142,11 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab if len(updates) > 0 { k.SetLastTotalPower(ctx, sdk.NewDec(totalPower)) } + fmt.Println( + cmn.Cyan( + fmt.Sprintf("SetLastTotalPower pow: %v", totalPower), + ), + ) return updates } @@ -197,7 +226,7 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types. // call the bond hook if present if k.hooks != nil { - k.hooks.OnValidatorBonded(ctx, validator.ConsAddress()) + k.hooks.OnValidatorBonded(ctx, validator.ConsAddress(), validator.OperatorAddr) } return validator