Skip to content

Commit

Permalink
new proto for SlashInfo and BuildPipedValsetOpKey shorten
Browse files Browse the repository at this point in the history
  • Loading branch information
likesToEatFish committed Jul 5, 2024
1 parent 04ff7ab commit 4664183
Show file tree
Hide file tree
Showing 7 changed files with 408 additions and 121 deletions.
36 changes: 36 additions & 0 deletions docs/proto/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- [osmosis/meshsecurity/v1beta1/meshsecurity.proto](#osmosis/meshsecurity/v1beta1/meshsecurity.proto)
- [Params](#osmosis.meshsecurity.v1beta1.Params)
- [SlashInfo](#osmosis.meshsecurity.v1beta1.SlashInfo)
- [VirtualStakingMaxCapInfo](#osmosis.meshsecurity.v1beta1.VirtualStakingMaxCapInfo)

- [osmosis/meshsecurity/v1beta1/genesis.proto](#osmosis/meshsecurity/v1beta1/genesis.proto)
Expand All @@ -22,6 +23,7 @@
- [Query](#osmosis.meshsecurity.v1beta1.Query)

- [osmosis/meshsecurity/v1beta1/scheduler.proto](#osmosis/meshsecurity/v1beta1/scheduler.proto)
- [ScheduledWork](#osmosis.meshsecurity.v1beta1.ScheduledWork)
- [ValidatorAddress](#osmosis.meshsecurity.v1beta1.ValidatorAddress)

- [osmosis/meshsecurity/v1beta1/tx.proto](#osmosis/meshsecurity/v1beta1/tx.proto)
Expand Down Expand Up @@ -58,6 +60,25 @@ Params defines the parameters for the x/meshsecurity module.



<a name="osmosis.meshsecurity.v1beta1.SlashInfo"></a>

### SlashInfo
SlashInfo defines info event from slashing


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `infraction_height` | [int64](#int64) | | |
| `power` | [int64](#int64) | | |
| `total_slash_amount` | [string](#string) | | |
| `slash_fraction` | [string](#string) | | |
| `time_infraction` | [int64](#int64) | | |






<a name="osmosis.meshsecurity.v1beta1.VirtualStakingMaxCapInfo"></a>

### VirtualStakingMaxCapInfo
Expand Down Expand Up @@ -238,6 +259,21 @@ Query provides defines the gRPC querier service



<a name="osmosis.meshsecurity.v1beta1.ScheduledWork"></a>

### ScheduledWork



| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `repeat` | [bool](#bool) | | |






<a name="osmosis.meshsecurity.v1beta1.ValidatorAddress"></a>

### ValidatorAddress
Expand Down
9 changes: 9 additions & 0 deletions proto/osmosis/meshsecurity/v1beta1/meshsecurity.proto
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,13 @@ message Params {
// MaxGasEndBlocker defines the maximum gas that can be spent in a contract
// sudo callback
uint32 max_gas_end_blocker = 3;
}

// SlashInfo defines info event from slashing
message SlashInfo {
int64 infraction_height = 1;
int64 power = 2;
string total_slash_amount = 3;
string slash_fraction = 4;
int64 time_infraction = 5;
}
4 changes: 1 addition & 3 deletions x/meshsecurity/keeper/adapter.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package keeper

import (
"time"

"cosmossdk.io/math"

sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -123,7 +121,7 @@ func (s StakingDecorator) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, power
ModuleLogger(ctx).
Error("can not propagate slash: validator not found", "validator", consAddr.String())
// TODO: add TimeInfraction (Needs to be gathered from the caller)
} else if err := s.k.ScheduleSlashed(ctx, val.GetOperator(), power, height, totalSlashAmount, slashRatio, time.Unix(0, 0)); err != nil {
} else if err := s.k.ScheduleSlashed(ctx, val.GetOperator(), power, height, totalSlashAmount, slashRatio, 0); err != nil {
ModuleLogger(ctx).
Error("can not propagate slash: schedule event",
"cause", err,
Expand Down
37 changes: 18 additions & 19 deletions x/meshsecurity/keeper/valset_updates.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package keeper
import (
"cosmossdk.io/math"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
"time"

"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -26,7 +25,7 @@ func (k Keeper) ScheduleUnbonded(ctx sdk.Context, addr sdk.ValAddress) error {
}

// ScheduleSlashed store a validator slash event / data for the valset update report
func (k Keeper) ScheduleSlashed(ctx sdk.Context, addr sdk.ValAddress, power int64, height int64, totalSlashAmount math.Int, slashRatio sdk.Dec, timeInfraction time.Time) error {
func (k Keeper) ScheduleSlashed(ctx sdk.Context, addr sdk.ValAddress, power int64, height int64, totalSlashAmount math.Int, slashRatio sdk.Dec, timeInfraction int64) error {
var slashInfo = &types.SlashInfo{
Power: power,
InfractionHeight: height,
Expand Down Expand Up @@ -61,7 +60,16 @@ func (k Keeper) ScheduleModified(ctx sdk.Context, addr sdk.ValAddress) error {
// and async send to all registered contracts in the end blocker
func (k Keeper) sendAsync(ctx sdk.Context, op types.PipedValsetOperation, valAddr sdk.ValAddress, slashInfo *types.SlashInfo) error {
ModuleLogger(ctx).Debug("storing for async update", "operation", int(op), "val", valAddr.String())
ctx.KVStore(k.memKey).Set(types.BuildPipedValsetOpKey(op, valAddr, slashInfo), []byte{})
if op == types.ValidatorSlashed {
value, err := slashInfo.Marshal()
if err != nil {
return err
}
ctx.KVStore(k.memKey).Set(types.BuildPipedValsetOpKey(op, valAddr), value)
} else {
ctx.KVStore(k.memKey).Set(types.BuildPipedValsetOpKey(op, valAddr), []byte{})
}

// and schedule an update callback for all registered contracts
var innerErr error
k.IterateMaxCapLimit(ctx, func(contractAddr sdk.AccAddress, m math.Int) bool {
Expand Down Expand Up @@ -129,7 +137,7 @@ func (k Keeper) ValsetUpdateReport(ctx sdk.Context) (contract.ValsetUpdate, erro
case types.ValidatorModified:
return appendValidator(&r.Updated, valAddr)
case types.ValidatorSlashed:
return slashValidator(&r.Slashed, valAddr, slashInfo.Power, slashInfo.InfractionHeight, slashInfo.TimeInfraction.Unix(),
return slashValidator(&r.Slashed, valAddr, slashInfo.Power, slashInfo.InfractionHeight, slashInfo.TimeInfraction,
slashInfo.TotalSlashAmount, slashInfo.SlashFraction)
default:
innerErr = types.ErrInvalid.Wrapf("undefined operation type %X", op)
Expand Down Expand Up @@ -163,24 +171,15 @@ func (k Keeper) iteratePipedValsetOperations(ctx sdk.Context, cb func(valAddress
iter := pStore.Iterator(nil, nil)
for ; iter.Valid(); iter.Next() {
key := iter.Key()
addrLen := key[0]
addr, op := key[1:addrLen+1], key[addrLen+1]
var slashInfo *types.SlashInfo = nil
addr, op := key[:len(key)-1], key[len(key)-1]

var slashInfo types.SlashInfo
if types.PipedValsetOperation(op) == types.ValidatorSlashed {
if len(key) <= 1+int(addrLen)+1+8+8+1 {
return types.ErrInvalid.Wrapf("invalid slash key length %d", len(key))
}
totalSlashAmountLen := key[addrLen+2+8+8]
slashFractionLen := key[addrLen+2+8+8+1+totalSlashAmountLen]
slashInfo = &types.SlashInfo{
InfractionHeight: int64(sdk.BigEndianToUint64(key[addrLen+2 : addrLen+2+8])),
Power: int64(sdk.BigEndianToUint64(key[addrLen+2+8 : addrLen+2+8+8])),
TotalSlashAmount: string(key[addrLen+2+8+8+1 : addrLen+2+8+8+1+totalSlashAmountLen]),
SlashFraction: string(key[addrLen+2+8+8+1+totalSlashAmountLen+1 : addrLen+2+8+8+1+totalSlashAmountLen+1+slashFractionLen]),
TimeInfraction: time.Unix(int64(sdk.BigEndianToUint64(key[addrLen+2+8+8+1+totalSlashAmountLen+1+slashFractionLen:addrLen+2+8+8+1+totalSlashAmountLen+1+slashFractionLen+8])), 0),
if err := slashInfo.Unmarshal(iter.Value()); err != nil {
panic(err)
}
}
if cb(addr, types.PipedValsetOperation(op), slashInfo) {
if cb(addr, types.PipedValsetOperation(op), &slashInfo) {
break
}
}
Expand Down
12 changes: 9 additions & 3 deletions x/meshsecurity/keeper/valset_updates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,29 +238,35 @@ func TestSetAndGetScheduleSlashed(t *testing.T) {
ctx, keepers := CreateDefaultTestInput(t)
k := keepers.MeshKeeper

var valAdrees sdk.ValAddress
valAdrees = rand.Bytes(address.Len)
slashInfo := &types.SlashInfo{
Power: 12,
InfractionHeight: 123,
TotalSlashAmount: sdk.NewInt(1000).String(),
SlashFraction: sdk.NewDec(1).String(),
TimeInfraction: time.Now(),
TimeInfraction: time.Now().Unix(),
}
// set
err := k.sendAsync(ctx, types.ValidatorSlashed, rand.Bytes(address.Len), slashInfo)
err := k.sendAsync(ctx, types.ValidatorSlashed, valAdrees, slashInfo)
require.NoError(t, err)
// get
var getSlash types.SlashInfo
var val sdk.ValAddress
err = k.iteratePipedValsetOperations(ctx, func(valAddress sdk.ValAddress, op types.PipedValsetOperation, slashInfo *types.SlashInfo) bool {

if op == types.ValidatorSlashed {
getSlash = *slashInfo
val = valAddress
return true
}
return false
})
require.NoError(t, err)
// check
require.Equal(t, slashInfo.TimeInfraction.Unix(), getSlash.TimeInfraction.Unix())
require.Equal(t, slashInfo.TimeInfraction, getSlash.TimeInfraction)
require.Equal(t, slashInfo.Power, getSlash.Power)
require.Equal(t, slashInfo.InfractionHeight, getSlash.InfractionHeight)
require.Equal(t, slashInfo.TotalSlashAmount, getSlash.TotalSlashAmount)
require.Equal(t, valAdrees, val)
}
48 changes: 4 additions & 44 deletions x/meshsecurity/types/keys.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package types

import (
"encoding/binary"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
"time"
)

const (
Expand Down Expand Up @@ -47,14 +44,6 @@ const (
ValidatorSlashed
)

type SlashInfo struct {
InfractionHeight int64
Power int64
TotalSlashAmount string
SlashFraction string
TimeInfraction time.Time
}

// BuildMaxCapLimitKey build max cap limit store key
func BuildMaxCapLimitKey(contractAddr sdk.AccAddress) []byte {
return append(MaxCapLimitKeyPrefix, contractAddr.Bytes()...)
Expand Down Expand Up @@ -92,40 +81,11 @@ func BuildSchedulerContractKey(tp SchedulerTaskType, blockHeight uint64, contrac
}

// BuildPipedValsetOpKey build store key for the temporary valset operation store
func BuildPipedValsetOpKey(op PipedValsetOperation, val sdk.ValAddress, slashInfo *SlashInfo) []byte {
func BuildPipedValsetOpKey(op PipedValsetOperation, val sdk.ValAddress) []byte {
if op == ValsetOperationUndefined {
panic("empty operation")
}
pn, an := len(PipedValsetPrefix), len(val)
sn := 0
if op == ValidatorSlashed {
if slashInfo == nil {
panic("slash info is nil")
}
sn = 8 + 8 + 1 + len(slashInfo.TotalSlashAmount) + 1 + len(slashInfo.SlashFraction) + 8 // 8 for height, 8 for power, +1 for total amount length, +1 for slash length, +8 for time
}
r := make([]byte, pn+an+sn+1+1) // +1 for address prefix, +1 for op
copy(r, PipedValsetPrefix)
copy(r[pn:], address.MustLengthPrefix(val))
r[pn+an+1] = byte(op)
if op == ValidatorSlashed {
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, uint64(slashInfo.InfractionHeight))
copy(r[pn+an+1+1:], b)
binary.BigEndian.PutUint64(b, uint64(slashInfo.Power))
copy(r[pn+an+1+1+8:], b)

tn := len(slashInfo.TotalSlashAmount)
r[pn+an+1+1+8+8] = byte(tn)
copy(r[pn+an+1+1+8+8+1:], slashInfo.TotalSlashAmount)

sn := len(slashInfo.SlashFraction)
r[pn+an+1+1+8+8+1+tn] = byte(sn)
copy(r[pn+an+1+1+8+8+1+tn+1:], slashInfo.SlashFraction)

timeUnix := slashInfo.TimeInfraction.Unix()
binary.BigEndian.PutUint64(b, uint64(timeUnix))
copy(r[pn+an+1+1+8+8+1+tn+1+sn:], b)
}
return r
k := append(append(PipedValsetPrefix, val...), byte(op))
// return
return k
}
Loading

0 comments on commit 4664183

Please sign in to comment.