Skip to content

Commit 4f35f6a

Browse files
committed
Working version
1. Return all Validators directly, skip most of the current mechanisms and check (`BlockValidatorUpdates`) 2. Do not actually transfer coin for Validators created via SetComputeValidators 3. Bulk of the logic in SetComputeValidators: Map all of the current validators and computeResults via PubKey. - Modify ones that need to be modified - Set to 0 ones to be removed - Create new ones
1 parent 6a3bedd commit 4f35f6a

File tree

4 files changed

+149
-4
lines changed

4 files changed

+149
-4
lines changed

x/staking/keeper/abci.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package keeper
22

33
import (
44
"context"
5+
"cosmossdk.io/math"
56

67
abci "github.com/cometbft/cometbft/abci/types"
78

@@ -19,5 +20,15 @@ func (k *Keeper) BeginBlocker(ctx context.Context) error {
1920
// EndBlocker called at every block, update validator set
2021
func (k *Keeper) EndBlocker(ctx context.Context) ([]abci.ValidatorUpdate, error) {
2122
defer telemetry.ModuleMeasureSince(types.ModuleName, telemetry.Now(), telemetry.MetricKeyEndBlocker)
22-
return k.BlockValidatorUpdates(ctx)
23+
allValidators, err := k.GetAllValidators(ctx)
24+
if err != nil {
25+
return nil, err
26+
}
27+
updates := make([]abci.ValidatorUpdate, 0, len(allValidators))
28+
for _, validator := range allValidators {
29+
update := validator.ABCIValidatorUpdate(math.NewInt(1))
30+
updates = append(updates, update)
31+
k.Logger(ctx).Info("UpdateValidator:", "pubKey", update.PubKey, "power", update.Power)
32+
}
33+
return updates, nil
2334
}

x/staking/keeper/compute.go

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package keeper
2+
3+
import (
4+
"context"
5+
"cosmossdk.io/math"
6+
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
7+
sdk "github.com/cosmos/cosmos-sdk/types"
8+
"github.com/cosmos/cosmos-sdk/x/staking/types"
9+
)
10+
11+
type ComputeResult struct {
12+
Power int64
13+
ValidatorPubKey cryptotypes.PubKey
14+
OperatorAddress string
15+
}
16+
17+
func (k Keeper) SetComputeValidators(ctx context.Context, computeResults []ComputeResult) ([]types.Validator, error) {
18+
server := NewMsgServerImpl(&k)
19+
logger := k.Logger(ctx)
20+
resultsMap := make(map[string]ComputeResult)
21+
for _, result := range computeResults {
22+
resultsMap[result.ValidatorPubKey.String()] = result
23+
}
24+
25+
currentValidators, err := k.GetAllValidators(ctx)
26+
if err != nil {
27+
logger.Error("error getting current validators", "error", err.Error())
28+
return nil, err
29+
}
30+
31+
validatorsAlreadyExisting := make(map[string]bool)
32+
for _, validator := range currentValidators {
33+
conPubKey, err := validator.ConsPubKey()
34+
if err != nil {
35+
logger.Error("Error getting cons pubkey", "error", err.Error())
36+
return nil, err
37+
}
38+
validatorsAlreadyExisting[conPubKey.String()] = true
39+
}
40+
41+
// Handle validators already in
42+
for _, validator := range currentValidators {
43+
conPubKey, err := validator.ConsPubKey()
44+
if err != nil {
45+
logger.Error("Error getting cons pubkey", "error", err.Error())
46+
return nil, err
47+
}
48+
computeResult, inNewResults := resultsMap[conPubKey.String()]
49+
if inNewResults {
50+
logger.Info("Updating validator", "operator", validator.GetOperator(), "power", computeResult.Power)
51+
// update to new power
52+
validator.Tokens = math.NewInt(computeResult.Power)
53+
err := k.SetValidator(ctx, validator)
54+
if err != nil {
55+
return nil, err
56+
}
57+
} else {
58+
logger.Info("Removing validator", "operator", validator.GetOperator(), "power", computeResult.Power)
59+
// update to new power
60+
validator.Tokens = math.NewInt(0)
61+
err := k.SetValidator(ctx, validator)
62+
if err != nil {
63+
return nil, err
64+
}
65+
}
66+
}
67+
68+
// Handle validators not in
69+
for _, computeResult := range computeResults {
70+
if _, ok := validatorsAlreadyExisting[computeResult.ValidatorPubKey.String()]; !ok {
71+
logger.Info("Creating validator", "power", computeResult, "operator", computeResult.OperatorAddress)
72+
_, err := k.createValidator(ctx, computeResult, server)
73+
if err != nil {
74+
logger.Error("Error creating validator", "error", err.Error())
75+
return nil, err
76+
}
77+
}
78+
}
79+
return k.GetAllValidators(ctx)
80+
}
81+
82+
func (k Keeper) createValidator(ctx context.Context, computeResult ComputeResult, server types.MsgServer) (*types.Validator, error) {
83+
logger := k.Logger(ctx)
84+
s := computeResult.ValidatorPubKey.Address().String()
85+
newValAddr, err := sdk.ValAddressFromHex(s)
86+
87+
if err != nil {
88+
logger.Error("Error converting pubkey to val address", "error", err.Error())
89+
return nil, err
90+
}
91+
denom, err := k.BondDenom(ctx)
92+
if err != nil {
93+
return nil, err
94+
}
95+
createValidatorMsg, err := types.NewMsgCreateValidator(
96+
newValAddr.String(),
97+
computeResult.ValidatorPubKey,
98+
sdk.NewCoin(denom, math.NewInt(computeResult.Power)),
99+
types.Description{
100+
Moniker: computeResult.OperatorAddress,
101+
Details: "Created after Proof of Compute",
102+
},
103+
104+
types.CommissionRates{
105+
Rate: math.LegacyMustNewDecFromStr("0.1"),
106+
MaxRate: math.LegacyMustNewDecFromStr("0.2"),
107+
MaxChangeRate: math.LegacyMustNewDecFromStr("0.01"),
108+
},
109+
math.NewInt(1),
110+
)
111+
// I think the Go fanatics are off their rocker. This is a lot of boilerplate.
112+
if err != nil {
113+
logger.Error("Error creating validator message", "error", err.Error())
114+
return nil, err
115+
}
116+
_, err = server.CreateValidator(ctx, createValidatorMsg)
117+
if err != nil {
118+
logger.Error("Error creating validator", "error", err.Error())
119+
return nil, err
120+
}
121+
newVal, err := k.GetValidator(ctx, newValAddr)
122+
if err != nil {
123+
logger.Error("Error getting created validator", "error", err.Error())
124+
return nil, err
125+
}
126+
logger.Info("Created validator", "validator", newVal.String())
127+
bondedVal, err := k.bondValidator(ctx, newVal)
128+
if err != nil {
129+
logger.Error("Error bonding validator", "error", err.Error())
130+
return nil, err
131+
}
132+
logger.Info("Bonded validator", "validator", bondedVal.String())
133+
return &bondedVal, nil
134+
}

x/staking/keeper/delegation.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,7 @@ func (k Keeper) Delegate(
901901
// if subtractAccount is true then we are
902902
// performing a delegation and not a redelegation, thus the source tokens are
903903
// all non bonded
904-
if subtractAccount {
904+
if subtractAccount && validator.Description.Details != "Created after Proof of Compute" {
905905
if tokenSrc == types.Bonded {
906906
panic("delegation token source cannot be bonded")
907907
}
@@ -926,7 +926,7 @@ func (k Keeper) Delegate(
926926
if err := k.bankKeeper.DelegateCoinsFromAccountToModule(ctx, delAddr, sendName, coins); err != nil {
927927
return math.LegacyDec{}, err
928928
}
929-
} else {
929+
} else if validator.Description.Details != "Created after Proof of Compute" {
930930
// potentially transfer tokens between pools, if
931931
switch {
932932
case tokenSrc == types.Bonded && validator.IsBonded():

x/staking/types/validator.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ func (v Validator) BondedTokens() math.Int {
352352
// validator tokens is applied
353353
func (v Validator) ConsensusPower(r math.Int) int64 {
354354
if v.IsBonded() {
355-
return 365
355+
return v.PotentialConsensusPower(r)
356356
}
357357

358358
return 0

0 commit comments

Comments
 (0)