forked from maticnetwork/heimdall
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MAT-1397 - sidechannel implementation for slashing
- Loading branch information
1 parent
23f15d9
commit 793c46c
Showing
7 changed files
with
552 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,165 @@ | ||
package slashing | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"math/big" | ||
|
||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
|
||
"github.com/maticnetwork/heimdall/common" | ||
"github.com/maticnetwork/heimdall/helper" | ||
"github.com/maticnetwork/heimdall/slashing/types" | ||
hmTypes "github.com/maticnetwork/heimdall/types" | ||
|
||
hmCommon "github.com/maticnetwork/heimdall/common" | ||
) | ||
|
||
// NewHandler creates an sdk.Handler for all the slashing type messages | ||
func NewHandler(k Keeper, contractCaller helper.IContractCaller) sdk.Handler { | ||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { | ||
ctx = ctx.WithEventManager(sdk.NewEventManager()) | ||
return sdk.ErrTxDecode("Invalid message in slashing module").Result() | ||
// switch msg := msg.(type) { | ||
/* case types.MsgUnjail: | ||
return handleMsgUnjail(ctx, msg, k, contractCaller) | ||
|
||
switch msg := msg.(type) { | ||
case types.MsgTick: | ||
return handlerMsgTick(ctx, msg, k, contractCaller) | ||
case types.MsgTickAck: | ||
return handleMsgTickAck(ctx, msg, k, contractCaller) */ | ||
// default: | ||
// return sdk.ErrTxDecode("Invalid message in slashing module").Result() | ||
// } | ||
return handleMsgTickAck(ctx, msg, k, contractCaller) | ||
case types.MsgUnjail: | ||
return handleMsgUnjail(ctx, msg, k, contractCaller) | ||
default: | ||
return sdk.ErrTxDecode("Invalid message in slashing module").Result() | ||
} | ||
} | ||
} | ||
|
||
|
||
// handlerMsgTick - handles slashing of validators | ||
// 0. check if slashLimit is exceeded or not. | ||
// 1. Validate input slashing info hash data | ||
// 2. If hash matches, copy slashBuffer into latestTickData | ||
// 3. flushes slashBuffer, totalSlashedAmount | ||
// 4. iterate and reduce the power of slashed validators. | ||
// 5. Also update the jailStatus of Validator | ||
// 6. emit event TickConfirmation | ||
func handlerMsgTick(ctx sdk.Context, msg types.MsgTick, k Keeper, contractCaller helper.IContractCaller) sdk.Result { | ||
|
||
k.Logger(ctx).Debug("✅ Validating tick msg", | ||
"SlashInfoHash", msg.SlashingInfoHash, | ||
) | ||
|
||
// check if slash limit is exceeded or not | ||
if !k.IsSlashedLimitExceeded(ctx) { | ||
k.Logger(ctx).Error("TotalSlashedAmount is less than SlashLimit") | ||
return hmCommon.ErrInvalidMsg(k.Codespace(), fmt.Sprintf("TotalSlashedAmount %v is less than SlashLimit", k.GetTotalSlashedAmount(ctx))).Result() | ||
} | ||
|
||
valSlashingInfos, err := k.GetBufferValSlashingInfos(ctx) | ||
if err != nil { | ||
k.Logger(ctx).Error("Error fetching slash Info list from buffer", "error", err) | ||
return hmCommon.ErrSlashInfoDetails(k.Codespace()).Result() | ||
} | ||
|
||
slashingInfoHash, err := types.GetSlashingInfoHash(valSlashingInfos) | ||
if err != nil { | ||
k.Logger(ctx).Info("Error generating slashing info hash", "error", err) | ||
return hmCommon.ErrSlashInfoDetails(k.Codespace()).Result() | ||
} | ||
|
||
// compare slashingInfoHash with msg hash | ||
k.Logger(ctx).Info("SlashInfo hash generated", "SlashInfoHash", hmTypes.BytesToHeimdallHash(slashingInfoHash).String()) | ||
|
||
if !bytes.Equal(slashingInfoHash, msg.SlashingInfoHash.Bytes()) { | ||
k.Logger(ctx).Error("SlashInfoHash of current buffer state", "bufferSlashInfoHash", hmTypes.BytesToHeimdallHash(slashingInfoHash).String(), | ||
"doesn't match with SlashInfoHash of msg", "msgSlashInfoHash", msg.SlashingInfoHash) | ||
return hmCommon.ErrSlashInfoDetails(k.Codespace()).Result() | ||
} | ||
|
||
k.Logger(ctx).Debug("SlashInfoHash matches") | ||
|
||
// ensure latestTickData is empty | ||
tickSlashingInfos, err := k.GetTickValSlashingInfos(ctx) | ||
if err != nil { | ||
k.Logger(ctx).Error("Error fetching slash Info list from tick", "error", err) | ||
return common.ErrSlashInfoDetails(k.Codespace()).Result() | ||
} | ||
|
||
if tickSlashingInfos != nil && len(tickSlashingInfos) > 0 { | ||
k.Logger(ctx).Error("Waiting for tick data to be pushed to contract", "tickSlashingInfo", tickSlashingInfos) | ||
return common.ErrSlashInfoDetails(k.Codespace()).Result() | ||
} | ||
|
||
return sdk.Result{ | ||
Events: ctx.EventManager().Events(), | ||
} | ||
} | ||
|
||
// Validators must submit a transaction to unjail itself after | ||
// having been jailed (and thus unbonded) for downtime | ||
func handleMsgUnjail(ctx sdk.Context, msg types.MsgUnjail, k Keeper, contractCaller helper.IContractCaller) sdk.Result { | ||
|
||
k.Logger(ctx).Debug("✅ Validating unjail msg", | ||
"validatorId", msg.ID, | ||
"txHash", hmTypes.BytesToHeimdallHash(msg.TxHash.Bytes()), | ||
"logIndex", uint64(msg.LogIndex), | ||
"blockNumber", msg.BlockNumber, | ||
) | ||
|
||
// sequence id | ||
blockNumber := new(big.Int).SetUint64(msg.BlockNumber) | ||
sequence := new(big.Int).Mul(blockNumber, big.NewInt(hmTypes.DefaultLogIndexUnit)) | ||
sequence.Add(sequence, new(big.Int).SetUint64(msg.LogIndex)) | ||
|
||
// check if incoming tx is older | ||
if k.HasSlashingSequence(ctx, sequence.String()) { | ||
k.Logger(ctx).Error("Older invalid tx found") | ||
return hmCommon.ErrOldTx(k.Codespace()).Result() | ||
} | ||
|
||
// pull validator from store | ||
validator, ok := k.sk.GetValidatorFromValID(ctx, msg.ID) | ||
if !ok { | ||
k.Logger(ctx).Error("Fetching of validator from store failed", "validatorId", msg.ID) | ||
return hmCommon.ErrNoValidator(k.Codespace()).Result() | ||
} | ||
|
||
|
||
if !validator.Jailed { | ||
k.Logger(ctx).Error("Fetching of validator from store failed", "validatorId", msg.ID) | ||
return hmCommon.ErrNoValidator(k.Codespace()).Result() | ||
} | ||
return sdk.Result{ | ||
Events: ctx.EventManager().Events(), | ||
} | ||
} | ||
|
||
|
||
/* | ||
handleMsgTickAck - handle msg tick ack event | ||
1. validate the tx hash in the event | ||
2. flush the last tick slashing info | ||
*/ | ||
func handleMsgTickAck(ctx sdk.Context, msg types.MsgTickAck, k Keeper, contractCaller helper.IContractCaller) sdk.Result { | ||
|
||
k.Logger(ctx).Debug("✅ Validating TickAck msg", | ||
"SlashedAmount", msg.SlashedAmount, | ||
"txHash", hmTypes.BytesToHeimdallHash(msg.TxHash.Bytes()), | ||
"logIndex", uint64(msg.LogIndex), | ||
"blockNumber", msg.BlockNumber, | ||
) | ||
|
||
// sequence id | ||
blockNumber := new(big.Int).SetUint64(msg.BlockNumber) | ||
sequence := new(big.Int).Mul(blockNumber, big.NewInt(hmTypes.DefaultLogIndexUnit)) | ||
sequence.Add(sequence, new(big.Int).SetUint64(msg.LogIndex)) | ||
|
||
// check if incoming tx is older | ||
if k.HasSlashingSequence(ctx, sequence.String()) { | ||
k.Logger(ctx).Error("Older invalid tx found") | ||
return hmCommon.ErrOldTx(k.Codespace()).Result() | ||
} | ||
|
||
return sdk.Result{ | ||
Events: ctx.EventManager().Events(), | ||
} | ||
} |
Oops, something went wrong.