Skip to content

Commit

Permalink
reset back and simplify
Browse files Browse the repository at this point in the history
  • Loading branch information
Reecepbcups committed Oct 22, 2023
1 parent 6e938cd commit 3bf30a5
Show file tree
Hide file tree
Showing 8 changed files with 368 additions and 189 deletions.
289 changes: 176 additions & 113 deletions api/v1/tx.pulsar.go

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func NewTxCmd(ac address.Codec) *cobra.Command {

func NewSetPowerCmd(ac address.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "set-power [validator] [power]",
Use: "set-power [validator] [power] [--unsafe]",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
Expand All @@ -64,10 +64,16 @@ func NewSetPowerCmd(ac address.Codec) *cobra.Command {
return fmt.Errorf("strconv.ParseUint failed: %w", err)
}

unsafeAction, err := cmd.Flags().GetBool("unsafe")
if err != nil {
return fmt.Errorf("get unsafe flag failed: %w", err)
}

msg := &poa.MsgSetPower{
FromAddress: clientCtx.GetFromAddress().String(),
ValidatorAddress: validator,
Power: power,
Unsafe: unsafeAction,
}

if err := msg.Validate(ac); err != nil {
Expand All @@ -79,6 +85,7 @@ func NewSetPowerCmd(ac address.Codec) *cobra.Command {
}

flags.AddTxFlagsToCmd(cmd)
cmd.Flags().Bool("unsafe", false, "set power without checking if validator is in the validator set")

return cmd
}
Expand Down
7 changes: 6 additions & 1 deletion e2e/helpers/poa_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/stretchr/testify/require"
)

func POASetPower(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, valoper string, power int64) TxResponse {
func POASetPower(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, valoper string, power int64, unsafe bool) TxResponse {
cmd := []string{chain.Config().Bin, "tx", "poa", "set-power", valoper, fmt.Sprintf("%d", power),
"--node", chain.GetRPCAddress(),
"--home", chain.HomeDir(),
Expand All @@ -25,6 +25,11 @@ func POASetPower(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, u
"--output=json",
"-y",
}

if unsafe {
cmd = append(cmd, "--unsafe")
}

stdout, _, err := chain.Exec(ctx, cmd, nil)
require.NoError(t, err)

Expand Down
29 changes: 11 additions & 18 deletions e2e/poa_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package e2e

import (
"context"
"fmt"
"testing"

Expand Down Expand Up @@ -41,9 +40,6 @@ func TestPOA(t *testing.T) {
t.Fatal(err)
}

// Validate all validators are signing blocks
requiredSignatures(t, ctx, chain, numVals)

users := interchaintest.GetAndFundTestUsers(t, ctx, t.Name(), userFunds, chain)
incorrectUser := users[0]

Expand All @@ -61,11 +57,11 @@ func TestPOA(t *testing.T) {

// === Setting Power Test ===
powerOne := int64(9_000_000_000_000)
powerTwo := int64(2500)
powerTwo := int64(2_500_000)

helpers.POASetPower(t, ctx, chain, acc0, validators[0], powerOne)
helpers.POASetPower(t, ctx, chain, acc0, validators[1], powerTwo)
helpers.POASetPower(t, ctx, chain, incorrectUser, validators[1], 11111111) // err.
helpers.POASetPower(t, ctx, chain, acc0, validators[0], powerOne, true)
helpers.POASetPower(t, ctx, chain, acc0, validators[1], powerTwo, false)
helpers.POASetPower(t, ctx, chain, incorrectUser, validators[1], 11111111, false) // err.

vals := helpers.GetValidators(t, ctx, chain).Validators
require.Equal(t, vals[0].Tokens, fmt.Sprintf("%d", powerOne))
Expand All @@ -77,19 +73,16 @@ func TestPOA(t *testing.T) {
vals = helpers.GetValidators(t, ctx, chain).Validators
require.Equal(t, vals[0].Tokens, fmt.Sprintf("%d", powerOne))
require.Equal(t, vals[1].Tokens, "0")
require.Equal(t, vals[1].Status, 1) // 1 = Unbonded status (stakingtypes.Unbonded)
// require.Equal(t, vals[1].Status, 1) // We dont check this anymore, let the Appy handler set it
for _, v := range vals {
t.Log(v.OperatorAddress, v.Tokens)
}

// Validate only 1 validator is signing blocks
requiredSignatures(t, ctx, chain, 1)
}

// requiredSignatures asserts that the current block has the exact number of signatures as expected
func requiredSignatures(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, expectedSigs int) {
height, err := chain.GetNode().Height(ctx)
require.NoError(t, err)
block := helpers.GetBlockData(t, ctx, chain, height)
require.Equal(t, len(block.LastCommit.Signatures), expectedSigs)
}
// func requiredSignatures(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, expectedSigs int) {
// height, err := chain.GetNode().Height(ctx)
// require.NoError(t, err)
// block := helpers.GetBlockData(t, ctx, chain, height)
// require.Equal(t, len(block.LastCommit.Signatures), expectedSigs)
// }
79 changes: 77 additions & 2 deletions keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"

"github.com/strangelove-ventures/poa"
Expand All @@ -33,6 +34,10 @@ func (ms msgServer) SetPower(ctx context.Context, msg *poa.MsgSetPower) (*poa.Ms
return nil, fmt.Errorf("not an authority")
}

if err := msg.Validate(ms.k.validatorAddressCodec); err != nil {
return nil, err
}

isPending, err := ms.k.IsValidatorPending(ctx, msg.ValidatorAddress)
if err != nil {
return nil, err
Expand All @@ -42,7 +47,18 @@ func (ms msgServer) SetPower(ctx context.Context, msg *poa.MsgSetPower) (*poa.Ms
if err := ms.acceptNewValidator(ctx, msg.ValidatorAddress, msg.Power); err != nil {
return nil, err
}
}

// if msg.Unsafe is true, we don't check the total power and set it.
if !msg.Unsafe {
totalPower, err := ms.getTotalChainPower(ctx)
if err != nil {
return nil, err
}

if msg.Power > totalPower.Mul(math.NewInt(30)).Quo(math.NewInt(100)).Uint64() {
return nil, fmt.Errorf("unsafe: msg.Power is >30%% of total power, set unsafe=true to override")
}
}

valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress)
Expand Down Expand Up @@ -98,13 +114,36 @@ func (ms msgServer) SetPower(ctx context.Context, msg *poa.MsgSetPower) (*poa.Ms
return &poa.MsgSetPowerResponse{}, nil
}

func (ms msgServer) getTotalChainPower(ctx context.Context) (math.Int, error) {
delSum := math.ZeroInt()
allDelegations, err := ms.k.stakingKeeper.GetAllDelegations(ctx)
if err != nil {
return math.ZeroInt(), err
}

for _, del := range allDelegations {
delSum = delSum.Add(del.Shares.TruncateInt())
}

return delSum, nil
}

func (ms msgServer) RemoveValidator(ctx context.Context, msg *poa.MsgRemoveValidator) (*poa.MsgRemoveValidatorResponse, error) {
if ok, err := ms.isAdmin(ctx, msg.FromAddress); err != nil {
return nil, err
} else if !ok {
return nil, fmt.Errorf("not an authority")
}

// Ensure we do not remove the last validator in the set.
allValidators, err := ms.k.stakingKeeper.GetAllValidators(ctx)
if err != nil {
return nil, fmt.Errorf("GetAllValidators failed: %w", err)
}
if len(allValidators) == 1 {
return nil, fmt.Errorf("cannot remove the last validator")
}

valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress)
if err != nil {
return nil, fmt.Errorf("ValAddressFromBech32 failed: %w", err)
Expand Down Expand Up @@ -195,7 +234,7 @@ func (ms msgServer) CreateValidator(ctx context.Context, msg *poa.MsgCreateValid
return nil, err
}

validator.MinSelfDelegation = msg.MinSelfDelegation
validator.MinSelfDelegation = math.NewInt(1)

// the validator is now pending approval to be let into the set.
// Until then, they are not apart of the set.
Expand Down Expand Up @@ -240,6 +279,23 @@ func (ms msgServer) acceptNewValidator(ctx context.Context, operatingAddress str
return err
}

cons, err := val.GetConsAddr()
if err != nil {
return err
}

err = ms.k.slashKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(cons), slashingtypes.ValidatorSigningInfo{
Address: sdk.ConsAddress(cons).String(),
StartHeight: sdkCtx.BlockHeight(),
IndexOffset: 0,
JailedUntil: sdkCtx.BlockHeader().Time,
Tombstoned: false,
MissedBlocksCounter: 0,
})
if err != nil {
return err
}

// call the after-creation hook
if err := ms.k.stakingKeeper.Hooks().AfterValidatorCreated(ctx, valAddr); err != nil {
return err
Expand All @@ -249,6 +305,8 @@ func (ms msgServer) acceptNewValidator(ctx context.Context, operatingAddress str
return err
}

// TODO: set validator signing info (slashing) - how does staking do it?

sdkCtx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
stakingtypes.EventTypeCreateValidator,
Expand Down Expand Up @@ -287,13 +345,30 @@ func (ms msgServer) clearValidator(ctx context.Context, valAddr sdk.ValAddress)
}
}

val.Status = stakingtypes.Unbonded
// val.Status = stakingtypes.Unbonding // this removes the validator from singing BUT is not fully unbonded yet.
val.Tokens = math.ZeroInt()
val.DelegatorShares = math.LegacyNewDecFromInt(math.ZeroInt())
if err := ms.k.stakingKeeper.SetValidator(ctx, val); err != nil {
return fmt.Errorf("SetValidator failed: %w", err)
}

// Set their power to 0 they do no longer propose any blocks
if err := ms.k.stakingKeeper.SetLastValidatorPower(ctx, valAddr, 0); err != nil {
return fmt.Errorf("SetLastValidatorPower failed: %w", err)
}

// clear missed blocks
cons, err := val.GetConsAddr()
if err != nil {
return fmt.Errorf("GetConsAddr failed: %w", err)
}
if err := ms.k.slashKeeper.DeleteMissedBlockBitmap(ctx, sdk.ConsAddress(cons)); err != nil {
return err
}
if err := ms.k.slashKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(cons), slashingtypes.ValidatorSigningInfo{}); err != nil {
return err
}

// Do we handle? or does the sdk do this (may need to wait until the next block?)
// validator record not found for address: 67AE8730FE9C4A8E67FB699F61EEA7F90627B34F\n
// if err := ms.k.stakingKeeper.RemoveValidator(ctx, valAddr); err != nil {
Expand Down
3 changes: 2 additions & 1 deletion proto/strangelove_ventures/poa/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ message MsgSetPower {

string from_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string validator_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
uint64 power = 3;
uint64 power = 3;
bool unsafe = 4;
}
// MsgSetPowerResponse
message MsgSetPowerResponse {}
Expand Down
4 changes: 2 additions & 2 deletions simapp/test_node.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# cd simapp
# BINARY="poad" CHAIN_ID="poa-1" HOME_DIR="$HOME/.poad" TIMEOUT_COMMIT="500ms" CLEAN=true sh test_node.sh
#
# poad tx poa set-power $(poad q staking validators --output=json | jq .validators[0].operator_address -r) 1230000 --home=$HOME_DIR --yes --from=acc1
# poad tx poa set-power $(poad q staking validators --output=json | jq .validators[0].operator_address -r) 12356789 --home=$HOME_DIR --yes --from=acc1 --unsafe
# poad q staking validators
# poad tx poa remove $(poad q staking validators --output=json | jq .validators[0].operator_address -r) --home=$HOME_DIR --yes --from=acc1
#
Expand All @@ -14,7 +14,7 @@
# Create a validator
# poad tx poa create-validator simapp/validator_file.json --from acc3 --yes --home=$HOME_DIR # no genesis amount
# poad q poa pending-validators --output json
# poad tx poa set-power $(poad q poa pending-validators --output=json | jq .pending[0].operator_address -r) 123 --home=$HOME_DIR --yes --from=acc1
# poad tx poa set-power $(poad q poa pending-validators --output=json | jq .pending[0].operator_address -r) 1000000 --home=$HOME_DIR --yes --from=acc1
# poad tx poa remove $(poad q staking validators --output=json | jq .validators[1].operator_address -r) --home=$HOME_DIR --yes --from=acc1

export KEY="acc1" # validator
Expand Down
Loading

0 comments on commit 3bf30a5

Please sign in to comment.